PHP разветвляет и обрабатывает базу данных MySQL без конфликтов


У меня есть таблица базы данных MySQL, которую мне нужно обработать. Для обработки 3 строк требуется около 1 секунды (из-за соединений CURL, которые мне нужно сделать для каждой строки). Итак, мне нужно разветвить PHP-скрипт, чтобы иметь разумное время (так как я буду обрабатывать до 10 000 строк за один пакет).

Я собираюсь запустить 10-30 процессов одновременно, и, очевидно, мне нужен какой-то способ убедиться, что процессы не перекрываются (с точки зрения того, какие строки они извлекают и изменяют).

Из из того, что я прочитал, есть три способа сделать это. Я пытаюсь решить, какой метод лучше всего подходит для данной ситуации.

Вариант 1: Начните транзакцию и используйте SELECT ... FOR UPDATE и ограничьте количество строк для каждого процесса. Сохраните данные в массив. Обновите выбранные строки с помощью флага состояния "обработка". Зафиксируйте транзакцию, а затем обновите выбранные строки до статуса "завершено".

Вариант 2: Обновите определенное количество строк с флагом состояния "обработка" и идентификатор процесса. Выберите все строки для этого идентификатора процесса и флага. Работайте с данными как обычно. Обновите эти строки и установите флажок "готово".

Вариант 3: Задайте предложение LIMIT ... OFFSET ... для запроса SELECT каждого процесса, чтобы каждый процесс получал уникальные строки для работы. Затем сохраните идентификаторы строк и выполните и UPDATE, когда закончите.

Я не уверен, какой вариант самый безопасный. Я думаю, что вариант 3 кажется достаточно простым, но мне интересно, есть ли способ, которым это может потерпеть неудачу? Вариант 2 также кажется очень простым, но я не уверен, что блокировка из-за UPDATE заставляет все замедляться. Вариант 1 кажется лучшим вариантом, но я не очень хорошо знаком с FOR UPDATE и транзакциями и мог бы воспользоваться некоторой помощью.

ОБНОВЛЕНИЕ: Для ясности, в настоящее время у меня есть только один файл process.php который выбирает все строки и отправляет данные стороннему пользователю через Curl один за другим. Я хотел бы иметь вилку в этом файле, чтобы 10 000 строк можно было разделить между 10-30 дочерними процессами.

Author: Trevor Gehman, 2013-02-10

2 answers

Другой способ справиться с этим - поместить идентификаторы, которые вам нужно обработать, в очередь redis (список). Затем вы можете вставлять/вставлять элементы из списка. Когда len(список) пуст, вы знаете, что обрабатывать больше нечего.

Существует также проект php resque, который будет реализовывать некоторые из заданий, которые вы хотите выполнить.

Https://github.com/chrisboulton/php-resque

 0
Author: Daniel, 2013-02-13 05:38:36

В итоге я использовал функции mult_curl (как предложил Брэд) для выполнения этой задачи. Я разделил массив строк на группы по 100 с помощью array_chunk(), а затем настроил задачу multi_curl для их обработки. Я начал использовать ParallelCurl, но в итоге он не работал правильно, поэтому я просто сам закодировал mult_curl.

Для обработки 10 000 соединений curl потребовалось почти 2 часа, чтобы занять всего несколько минут.

 0
Author: Trevor Gehman, 2013-02-13 16:45:23