Масштабируемая обработка большого количества сложных данных базы данных в PHP, много раз в день - PullRequest
4 голосов
/ 15 января 2011

Я скоро буду работать над проектом, который представляет для меня проблему.

Потребуется через регулярные промежутки времени в течение дня обрабатывать десятки тысяч записей, возможно, более миллиона. Обработка будет включать несколько (потенциально сложных) формул и генерацию нескольких случайных факторов, запись некоторых новых данных в отдельную таблицу и обновление исходных записей с некоторыми результатами. Это должно происходить для всех записей, в идеале, каждые три часа. Каждый новый пользователь на сайте будет добавлять от 50 до 500 записей, которые необходимо обработать таким образом, чтобы число не было постоянным.

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

Хотелось бы узнать, есть ли у кого-нибудь опыт или советы по сходным предметам? Я никогда не работал с такой величиной раньше, и, насколько я знаю, это будет тривиально для сервера и не представляет большой проблемы. Пока ВСЕ записи обрабатываются до наступления следующего трехчасового периода, мне все равно, если они не обрабатываются одновременно (хотя, в идеале, все записи, принадлежащие конкретному пользователю, должны обрабатываться в одном пакете), поэтому я Вы задаетесь вопросом, должен ли я обрабатывать пакетами каждые 5 минут, 15 минут, час, все, что работает, и как лучше всего подойти к этому (и сделать его масштабируемым таким образом, чтобы это было справедливо для всех пользователей)?

Ответы [ 6 ]

3 голосов
/ 15 января 2011

Ниже я опишу, как бы я подошел к этой проблеме (но это будет стоить вам денег и, возможно, не будет желаемым решением):

  1. Вам следует использовать VPS (быстрый список некоторых дешевый VPS ).Но я полагаю, вам следует провести еще исследование , чтобы найти лучший VPS для ваших нужд, , если вы хотите достичь своей цели без раздражения вашей хостинговой компании (я уверен, что вы это сделаете) .
  2. Вы не должны использовать cronjobs, а использовать очередь сообщений, как, например, beanstalkd , чтобы ставить в очередь ваши сообщения (задачи) и выполнять обработку в автономном режиме.При использовании очереди сообщений вы также можете при необходимости ограничить обработку.

Не очень необходимо, но я бы решил это следующим образом.

  1. Если бы производительность действительно былаКлючевой вопрос У меня было бы два VPS (по крайней мере) экземпляров.один экземпляр VPS для обработки запроса http от пользователей, посещающих ваш сайт, и один экземпляр VPS для выполнения автономной обработки по вашему желанию.Таким образом, ваши пользователи / посетители не заметят какой-либо тяжелой автономной обработки, которую вы делаете.
  2. Я также, вероятно, не использовал бы PHP для выполнения автономной обработки из-за природы блокировки.Я бы использовал что-то вроде node.js для такой обработки, потому что ничто не блокирует в node.js, что будет намного быстрее.
  3. Я также, вероятно, не буду хранить данные в реляционной базе данных, ноиспользуйте молниеносный redis в качестве хранилища данных. node_redis - это невероятно быстрый клиент для node.js
1 голос
/ 15 января 2011

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

Решение, которое мы использовали ранее, состоит в том, чтобы иметь две базы данных MySQL (на нашем сервере тоже на разных серверах).Только один из них активно используется веб-сервером.Другой - просто запасной вариант и используется для такого рода обновлений.Два сервера копируют свои данные друг другу.

Решение:

  • Репликация остановлена.
  • Веб-сайту предписано использовать базу данных1.
  • Эти крупные обновления, о которых вы упомянули, сделаны на базе Database2.
  • Многие часто используемые запросы выполняются один раз в Database2 для разогрева кеша запросов.
  • Серверу предписано использовать базу данных2.
  • Репликация запускается снова.База данных2 теперь используется в основном для чтения (как веб-сайтом, так и репликацией), поэтому веб-сайты не сильно задерживаются.
0 голосов
/ 15 января 2011

Сделайте все это на стороне сервера, используя хранимую процедуру, которая выбирает подмножества данных, а затем обрабатывает данные внутренне.

Вот пример, в котором для выбора диапазонов данных используется курсор:

drop procedure if exists batch_update;

delimiter #

create procedure batch_update
(
in p_from_id int unsigned, -- range of data to select for each batch
in p_to_id int unsigned
)
begin

declare v_id int unsigned;
declare v_val double(10,4);

declare v_done tinyint default 0;
declare v_cur cursor for select id, val from foo where id between = p_from_id and p_to_id;
declare continue handler for not found set v_done = 1;

start transaction;

open v_cur;
repeat
    fetch v_cur into v_id, v_val;

    -- do work...

    if v_val < 0 then
        update foo set...
    else
        insert into foo...
    end if;

until v_done end repeat;
close v_cur;

commit;

end #

delimiter ; 

call batch_update(1,10000);

call batch_update(10001, 20000);

call batch_update(20001, 30000);

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

Вот еще один пример, который может оказаться интересным, хотя он работает с гораздо большим набором данных.+ миллион строк:

Оптимальные настройки MySQL для запросов, которые доставляют большие объемы данных?

Надеюсь, это поможет:)

0 голосов
/ 15 января 2011

В этой ситуации я хотел бы рассмотреть возможность использования Gearman (который также имеет расширение PHP, но может использоваться со многими языками)

0 голосов
/ 15 января 2011

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

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

0 голосов
/ 15 января 2011

это может быть использование нескольких серверов, где каждый сервер может делать X записей в час, чем больше записей вы будете использовать в будущем, тем больше серверов вам понадобится, в противном случае вы можете получить миллион записей, обрабатываемых в то время, как последние 2-3 или даже 4-я обработка еще не закончена ...

...