У меня есть PHP-скрипт, который извлекает строки из базы данных и затем выполняет работу на основе содержимого. Работа может занять много времени (но не обязательно дорогостоящим путем), и поэтому мне нужно разрешить параллельное выполнение нескольких сценариев.Реализация простой очереди с PHP и MySQL?
Строка в базе данных выглядит примерно так:
+---------------------+---------------+------+-----+---------------------+----------------+
| 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 | |
+---------------------+---------------+------+-----+---------------------+----------------+
Моего сценарий в настоящее время выбирает строки с древнейшими датами в date_last_updated
(которая обновляется после того, как работа выполнена) и не делает использование date_update_started
.
Если бы мне пришлось запускать несколько экземпляров скрипта параллельно, они будут выбирать одни и те же строки (по крайней мере, некоторое время), и будет выполняться дублирующая работа.
Что я имею в виду делать это с помощью транзакции, чтобы выбрать строки, обновить date_update_started
столбец, а затем добавить WHERE
условие к оператору SQL выбора строк только выбранных строк с date_update_started
больше некоторого значения (для убедитесь, что другой скрипт не работает над ним). Например.
$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);
Из того, что я прочитал, это, по сути, реализация очереди, и, похоже, в MySQL она недоказана. Тем не менее, мне нужно найти способ позволить нескольким сценариям работать параллельно, и после исследования, которое я сделал, это то, что я придумал.
Будет ли этот тип подхода работать? Есть ли способ лучше?
Как вы запускаете параллельные скрипты? – Lupin
@ Lupin В настоящее время скрипт выполняется каждые 15 минут с помощью задания cron. Скрипт проверяет, работает ли другой экземпляр, и если это так прекращается. Я не уверен, как я буду управлять несколькими сценариями, но пока у меня есть счетчик в базе данных, чтобы увидеть, сколько запущено и ограничено количество экземпляров таким образом, но одна проблема за раз :-) – Nate
OK , некоторые дополнительные вопросы, чтобы я мог полностью понять: 1. У вас есть скрипт, который выбирает строки и работает над ними, а затем обновляет его обратно в БД, правильно? 2. Вы хотите иметь параллельные скрипты и делать то же самое, но в разных строках? 3. Каждый раз, когда скрипт запускается, выбираемые строки являются непрерывными, то есть они 1-100, 101-200 и т. Д. Или являются ли они случайными с точки зрения идентификатора и выбираются только теми, у которых date_update_started больше 1? – Lupin