Ehi. Io uso delayed_job per l'elaborazione in background. Ho 8 CPU del server, MySQL e inizio 7 delayed_job elaboraRails che eseguono più delayed_job - lock tables
RAILS_ENV=production script/delayed_job -n 7 start
Q1: sto chiedendo è possibile che 2 o più processi delayed_job avviare l'elaborazione dello stesso processo (lo stesso record fila in il database delayed_jobs). Ho controllato il codice del plugin delayed_job ma non riesco a trovare la direttiva lock in un modo che dovrebbe essere (nessuna tabella lock o SELECT ... FOR UPDATE).
Penso che ogni processo dovrebbe bloccare la tabella del database prima di eseguire un UPDATE sulla colonna lock_by. Bloccano il record semplicemente aggiornando il campo locked_by (UPDATE delayed_jobs SET locked_by ...). È abbastanza? Non è necessario il blocco? Perché? So che UPDATE ha una priorità più alta di SELECT ma penso che questo non abbia l'effetto in questo caso.
La mia comprensione della situazione multy-threaded è:
Process1: Get waiting job X. [OK]
Process2: Get waiting jobs X. [OK]
Process1: Update locked_by field. [OK]
Process2: Update locked_by field. [OK]
Process1: Get waiting job X. [Already processed]
Process2: Get waiting jobs X. [Already processed]
Penso che in alcuni casi, più posti di lavoro possono ottenere le stesse informazioni e possono avviare l'elaborazione lo stesso processo.
Q2: 7 il ritardo è un buon numero per il server 8CPU? Perché sì/no.
Thx 10x!
Quindi stai dicendo che ogni processo è atom-style ed è sicuro? – xpepermint
Quello che penso manchi qui è SELECT ... FOR UPDATE. ? – xpepermint
La query è atomica. Quindi se si esegue la query 'UPDATE jobs SET locked_at = '..', locked_by = 1 WHERE id = 12 e (locked_at è null o locked_at <'..')', quindi locked_at e locked_by vengono aggiornati solo se non c'è altro blocco valido. Il DBMS prima controlla la condizione where e quindi esegue l'aggiornamento e assicura che la riga non venga modificata in mezzo. Quindi non è possibile sovrascrivere un blocco esistente. – gregor