Sidekiq, Posgresql, deadlocks

Ciao a tutti,
da qualche tempo a questa parte sto avendo parecchi problemi con
background jobs che vanno in deadlock e bloccano tutti gli worker di
Sidekiq su una app in produzione su heroku.

Il risultato che la coda si riempie e non riparte fino a quando non
sblocco la situazione con dei reload.

Ispezionando i locks nel momento in cui si verifica il problema ho
potuto vedere che in certe occasioni si trattava di problemi con
blocchi di transazioni SQL che ho potuto modificare per rendere pi
“slim” o in qualche caso addirittura rimuovere.

E’ probabile che ci siano delle operazioni che vengono accodate molto
rapidamente che agiscono sulla stessa tabella o addirittura sugli
stessi record che, grazie alla velocit di sidekiq, creano queste
situazioni di conflitto.

Chiaramente l’argomento deadlocks molto complesso e dipende molto da
come strutturata l’applicazione, ma mi chiedevo se qualcuno ha avuto
problemi simili e se si come li ha risolti.

Attualmente sto usando questa query per cercare di capirne di pi:

SELECT relation::regclass, mode, granted, transactionid,
substring(query, 0, 80), locktype, state FROM pg_locks pl
LEFT JOIN pg_database on (pl.database = pg_database.oid)
LEFT JOIN pg_stat_activity psa ON pl.pid = psa.pid where state <>
‘active’ ;

Tra l’altro con la console di postgres posso mettere una query in
watch, molto comodo, basta lanciare \watch [tempo-in-secondi] dopo
aver lanciato la query.

Grazie,

-f

Ho avuto un problema simile, legato a connessioni HTTP che rimanevano
appese. Il problema era il resolver C che ignora completamente il
timeout.

Nel mio caso, ho risolto rimpiazzando il resolver C con una
implementazione
Ruby usando resolv-replace.

Per capire meglio il problema, puoi inviare un segnale TTIN al processo
Sidekiq per stampare nei log di Sidekiq una backtrace dei processi.

Questo dovrebbe indicarti a quale livello (o chiamata) si e’ appeso il
thread.

– Simone

2015-02-07 18:32 GMT+01:00 Fabrizio R. [email protected]:

blocchi di transazioni SQL che ho potuto modificare per rendere pi

aver lanciato la query.

Grazie,

-f


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Simone C.
Passionate programmer and dive instructor

Twitter: @weppos https://twitter.com/weppos

Onestamente non ho mai provato su Heroku. Tuttavia

$ heroku run sh

dovrebbe aprirti una istanza di una shell su Heroku. A quel punto,
supponendo che tu conosca il PID

$ kill -TTIN pid

Il problema e’ che non saprei dove Sidekiq salva i log su Heroku.

– Simone

2015-02-09 9:57 GMT+01:00 Fabrizio R. [email protected]:

implementazione

Il risultato che la coda si riempie e non riparte fino a quando non
situazioni di conflitto.
LEFT JOIN pg_stat_activity psa ON pl.pid = psa.pid where state <>
Ml mailing list
http://simonecarletti.com/
Twitter: @weppos https://twitter.com/weppos


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Simone C.
Passionate programmer and dive instructor

Twitter: @weppos https://twitter.com/weppos

Heroku lancia ogni processo in un container. Quindi anche con heroku run sh ( a cui non avevo pensato) non ti dato di accedere ad un pid
di un altro “dyno”. Il processo che esegue sidekiq loggato come “3”,
che lo stesso pid assegnato alla shell lanciata con heroku run sh.
Non si ha accesso ai processi che girano su altri container.

Una soluzione questa:
Mikael Amborn: Sidekiq thread dump on Heroku,
ma suppongo che se i worker sono bloccati neanche questo verr
esegutio mai.

2015-02-08 10:04 GMT+01:00 Simone C. [email protected]:

Purtroppo non uso Heroku (se non per semplici service app), quindi non
saprei aiutarti.

– Simone

2015-02-09 10:45 GMT+01:00 Fabrizio R. [email protected]:

esegutio mai.

Chiaramente l’argomento deadlocks molto complesso e dipende molto da

http://lists.ruby-it.org/mailman/listinfo/ml


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Simone C.
Passionate programmer and dive instructor

Twitter: @weppos https://twitter.com/weppos

Grazie mille. Qualche suggerimento su come mandare segnali a un pid su
heroku?

2015-02-08 10:04 GMT+01:00 Simone C. [email protected]:

Il malato ancora in osservazione. Il resolver che mi hai consigliato
non ha avuto effetti positivi purtroppo. Per mi sono accorto che ero
un p indietro con pg e unicorn che ho aggiornato alle ultime
versioni. Fatto questo, per il momento non si sono verificati ancora
nuovi casi.

2015-02-09 17:39 GMT+01:00 Simone C. [email protected]:

/me che grida contro il cielo: "Dannazione, ma l'informatica non dovrebbe essere una scienza esatta, basandoci su dati digitali?!"

Tempo fa con dei miei amici phpisti e cplussari ho realizzato che stiamo
costruendo astrazioni fragili e quindi poco componibili.
Questo rende complessa l’integrazione fra più astrazioni, aumentando
anche
la presenza di proprietà emergenti.

^_^’

2015-02-12 10:42 GMT+01:00 Fabrizio R. [email protected]:

L’informatica in questi anni ha incredibilmente aumentato i livelli di
astrazione. Questo comporta maggiore complessita’.

2015-02-12 10:56 GMT+01:00 maurizio de magnis
[email protected]:

> > Purtroppo non uso Heroku (se non per semplici service app), quindi non > >> che è lo stesso pid assegnato alla shell lanciata con `heroku run sh`. > >> > >> > >> > thread. > >> >> Sidekiq su una app in produzione su heroku. > >> >> E' probabile che ci siano delle operazioni che vengono accodate > >> >> > >> >> aver lanciato la query. > >> > > >> > http://lists.ruby-it.org/mailman/listinfo/ml > > Passionate programmer and dive instructor > http://lists.ruby-it.org/mailman/listinfo/ml http://lists.ruby-it.org/mailman/listinfo/ml


Simone C.
Passionate programmer and dive instructor

Twitter: @weppos https://twitter.com/weppos

Infatti alle volte è questionabile l’introduzione di un framework o di
una
libreria invece di scriversi solo quello che ci serve :slight_smile:

Luca G. con Lotus da questo punto di vista credo c’abbia preso; un
framework essendo complesso già di suo è necessario che non si riveli un
oscuro pachiderma, ma un compagno di sviluppo snello e comprensibile,
per
quanto possibile.

Maurizio De Santis

Il giorno 12 febbraio 2015 12:54, Antonio C.
[email protected]
ha scritto:

Indeed :slight_smile:

Il giorno gio 12 feb 2015 13:20 Maurizio De Santis <
[email protected]> ha scritto:

La filosofia del Golang è quella e io francamente la apprezzo sempre di
più: invece di un framework, scrivi un’applicazione!

2015-02-12 13:34 GMT+01:00 Antonio C. [email protected]:

Lo scopo dell’astrazione è nascondere la complessità gestita, tramite
l’esposizione di interfacce.
Il problema non è tanto nell’uso della singola astrazione, quanto nel
fatto
che, mediamente, i processi di creazione delle astrazioni adottati fino
ad
ora non ci hanno messi al riparo dalle proprietà emergenti frutto della
“composizione” di più astrazioni.
Queste proprietà emergenti sono a loro volta considerabili come
complessità
e il loro esplicitarsi nei confronti degli utenti della “composizione” è
in
parte considerabile come fallimento delle astrazioni che fanno parte di
tale “composizione”.

Penso che il motivo principale di questa complessità “insostenibile” sia
strettamente legato alla definizione del contesto di applicabilità
dell’astrazione. Può non essere definito o essere definito con troppa
approssimazione ed inoltre l’astrazione potrebbe non rispettare
l’eventuale
definizione fornita.

Prendo come esempio un processo di creazione di un progetto/gemma Ruby:

Nel Gemfile/gemspec possono verificarsi alcune delle seguenti
condizioni:

  1. per alcune gemme non è presente alcun vincolo di versione;
  2. per alcune gemme il vincolo di versione non segue il semantic
    versioning;
  3. se anche viene specificato lo spermy operator (Pessimistic version
    constraint), alcune dipendenze possono non rispettare il semantic
    versioning.

Ok, è possibile utilizzare un sistema di CI, e in tal caso la
responsabilità della definizione del contesto dell’astrazione si sposta
sulla robustezza e completezza della suite di test fornita
dall’astrazione
e dalle suite di test delle dipendenze.

E mi sto riferendo ad un livello molto alto nella “torre della
astrazioni”
disponibili, perché di mezzo ci sono molti altri livelli eterogenei che
interagiscono tra di loro, ad esempio:

  1. le interfacce del SO usato;
  2. la configurazione applicata al SO;
  3. RVM;
  4. Ruby (interprete);
  5. Ruby (applicazione).

In ognuno di questi livelli sono presenti problematiche simili a quelle
dell’esempio del progetto/gemma Ruby.

Vedo di buon occhio la direzione intrapresa da progetti come Docker,
perché
l’immutabilità dell’ambiente di esecuzione aiuta a definire in maniera
molto rigida il contesto di applicabilità di un’astrazione.

Aggiungo poi che reputo sia molto utile avere livelli di astrazione
“piccoli” perchè, tra le altre cose, responsabilità limitate comportano
definizioni di contesti di applicazione più robuste.
Il fatto che RVM si sia fatto carico della gestione dell’aggiornamento
dei
certificati SSL https://rvm.io/support/fixing-broken-ssl-certificates
ha
risolto molti problemi a tutti noi, ma tale gestione dovrebbe essere
responsabilità del SO, non di RVM. Come effetto secondario,
l’implementazione di RVM è diventata relativamente più complessa e
conseguentemente anche la definizione del suo contesto di applicabilità,
soprattutto considerando che non è una sua responsabilità.
Potrebbe forse risultare sensato estrapolare in un progetto a parte tale
responsabilità (creando quindi un’astrazione “piccola”),
re-incorporandola
dentro RVM tramite composizione.

Ok, come al solito sono stato logorroico, ma ogni tanto pensare ad alta
voce ci sta :slight_smile:

2015-02-12 12:41 GMT+01:00 Simone C. [email protected]: