Ho uno script PHP che recupera le righe da un database e quindi esegue il lavoro in base ai contenuti. Il lavoro può essere dispendioso in termini di tempo (ma non necessariamente costoso da un punto di vista computazionale) e quindi è necessario consentire l'esecuzione di più script in parallelo.Implementazione di una coda semplice con PHP e MySQL?
Le righe nel database sembra qualcosa di simile:
+---------------------+---------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+---------------+------+-----+---------------------+----------------+
| id | bigint(11) | NO | PRI | NULL | auto_increment |
.....
| date_update_started | datetime | NO | | 0000-00-00 00:00:00 | |
| date_last_updated | datetime | NO | | 0000-00-00 00:00:00 | |
+---------------------+---------------+------+-----+---------------------+----------------+
Il mio script attualmente seleziona le righe con le date più antiche date_last_updated
(che viene aggiornato una volta il lavoro è fatto) e non fanno uso di date_update_started
.
Se dovessi eseguire più istanze dello script in parallelo adesso, selezionerebbero le stesse righe (almeno una parte del tempo) e il lavoro duplicato sarebbe fatto.
Quello che sto pensando di fare è utilizzare una transazione per selezionare le righe, aggiornare la colonna date_update_started
, e quindi aggiungere una condizione WHERE
per l'istruzione SQL selezionando il file per selezionare solo le righe con date_update_started
maggiore di un certo valore (a assicurati che un altro script non funzioni su di esso). Per esempio.
$sth = $dbh->prepare('
START TRANSACTION;
SELECT * FROM table WHERE date_update_started > 1 DAY ORDER BY date_last_updated LIMIT 1000;
UPDATE table DAY SET date_update_started = UTC_TIMESTAMP() WHERE id IN (SELECT id FROM table WHERE date_update_started > 1 DAY ORDER BY date_last_updated LIMIT 1000;);
COMMIT;
');
$sth->execute(); // in real code some values will be bound
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
Da quello che ho letto, questa è essenzialmente un'implementazione della coda e sembra essere disapprovata in MySQL. Allo stesso tempo, ho bisogno di trovare un modo per consentire l'esecuzione di più script in parallelo, e dopo la ricerca che ho fatto questo è quello che ho trovato.
Questo tipo di approccio funzionerà? C'è un modo migliore?
Come si fa a eseguire gli script in parallelo? – Lupin
@Lupin Attualmente lo script viene eseguito ogni 15 minuti tramite un cron job. Lo script verifica se un'altra istanza è in esecuzione e, in tal caso, termina. Non sono sicuro di come gestirò più script in esecuzione - potrei avere un contatore in un database per vedere quanti sono in esecuzione e limitare il numero di istanze in quel modo, ma un problema alla volta :-) – Nate
OK , alcune domande aggiuntive per me per comprendere appieno: 1. si dispone di uno script che seleziona le righe e lavorare su di essi e quindi aggiornare di nuovo al DB, giusto? 2. Vuoi la possibilità di avere script paralleli in esecuzione e facendo lo stesso, ma su righe diverse, giusto? 3. Ogni volta che lo script viene eseguito, le righe selezionate sono continue, ovvero sono 1-100, 101-200 ecc o sono casuali in termini di ID e selezionate solo da quelle che date_update_started è maggiore di 1? – Lupin