Правильный способ использования MySQL для назначения задач рабочим процессам - PullRequest
0 голосов
/ 20 марта 2009

У меня огромный список URL-адресов в таблице MySQL InnoDB, и рабочие процессы, которые запрашивают в MySQL набор URL-адресов для обработки. URL-адреса должны быть немедленно помечены как обрабатываемые, чтобы другие рабочие процессы не тратили ресурсы, запуская те же самые.

В настоящее время я сначала делаю это, чтобы получить несколько URL-адресов:

SELECT DISTINCT url FROM urls WHERE task_assigned is NULL ORDER BY id LIMIT 100

Затем в коде я наивно перебираю каждый из этих URL, чтобы пометить его как обрабатываемый:

UPDATE urls SET task_assigned = NOW() WHERE url = ? COLLATE utf8_bin

Я прекрасно понимаю, насколько это глупо и неэффективно. Что еще более важно, нет никакой гарантии, что другой рабочий процесс не попытается получить список в середине моих ОБНОВЛЕНИЙ. Какой красивый способ сделать это? Как мне совершить сделку?

Ответы [ 2 ]

2 голосов
/ 20 марта 2009

Следующее (быстрый взгляд на руководство по MySQL 5) появляется в MySQL; Я не уверен, что это лучший подход, но я уже использовал его в PostgreSQL:

BEGIN TRANSACTION;
SELECT DISTINCT url FROM urls WHERE task_assigned is NULL ORDER BY id LIMIT 100 FOR UPDATE;
UPDATE urls SET task_assigned = NOW() WHERE url IN [list of URLs] COLLATE utf8_bin;
COMMIT;

На самом деле в PostgreSQL я бы использовал одиночный оператор UPDATE с предложением RETURNING в UPDATE вместо вместо SELECT, но это расширение, специфичное для PostgreSQL.

Одна потенциальная проблема, с которой я сталкиваюсь при вашем подходе, заключается в дублировании URL: если url http://www.example.com/ дважды появляется в вашей таблице, скажем, с идентификаторами 23 и 42, он будет возвращен с одним из этих двух идентификаторов с помощью SELECT, но ОБНОВЛЕНИЕ будет влияет на оба ряда. Я не знаю, имеет ли такое поведение смысл в вашем приложении; Возможно, я бы наложил какое-то уникальное ограничение на URL-адреса, чтобы это не могло произойти, а затем использовал бы список идентификаторов, а не URL-адресов, в предложении IN (что должно быть быстрее).

0 голосов
/ 20 марта 2009

Может быть, вам следует сначала выбрать все URL-адреса, а затем использовать потоки для их асинхронного анализа?

...