У меня есть база пользователей, по которым раз в неделю нужно обновлять некоторые данные. Эти данные парсятся с других сайтов. Проблема в том, что скрипт обновления выполняется долго, а на хостинге стоит ограничение на 30 секунд.
Если обновлять информацию одного пользователя, а не всех сразу, скрипт будет выполняться 10—20 секунд. Можно попробовать запускать его cron’ом каждую минуту, передавая идентификатор юзера, но не хотелось бы вручную создавать сотню правил.
Как можно решить эту проблему? Время выполнения скрипта поменять не могу.
Добавить в таблицу пользователей столбец с датой последнего обновления. Скрипт научить самому находить себе жертву и запускать его по расписанию каждую минуту. При этом потребуется всего одно правило, а скрипт сам будет находить пользователей которых надо апдейтить.
1. Сделать асинхронной задачу парсинга и обновления данных. Парсер создает пул задач для обновления, потом второй скрипт производит обработку этого пула, обновляя нужные данные.
2. Попробовать реализовать обновление триггером. Как только парсер выдернул данные и вставил в базу, они автоматом обновятся в нужных таблицах. Нужно помнить, что не всегда этот способ хорош, и может уложить на лопатки базу из-за постоянной индексации или наоборот, редкой индексации.
Я бы делал так (допустим, если используется mysql для хранения пользователей): собирал все данные на другой машине, делал бы один единственный sql-дамп для вставки/обновления данных, а потом уже его заливал на хостинг.
На другой машине написать скрипт с неограниченным временем выполнения, который подключится к базе на вашем хостинке и сделает всю работу.
Базу данных, соответственно, надо научить слушать не только локальные обращения (в MySQL можно ограничить внешние обращения до списка IP-адресов).
В базе данных для тяжелых операций внутри самой базы написать утилитарные хранимые процедуры, чтобы не гонять данные по сети.
Можно, конечно, запомнить id юзера, на котором скрипт вылетел по таймауту и при ошибке перезапускать его, начиная с этого айдишника, ну, при условии, что айдишники упорядочены. Но это какое-то извращение :)
Когда на хостинге было ограничение, реализовал вызов парсера через ajax. Тоесть, очередь обрабатывается на клиенте. Но не во всех случаях это применимо.
Обхожу неработающий set_time_limit с помощью создания очереди заданий.
Попросту
select id,task from update_list limit 3 where active = 1
далее когда обработка выполнена
update update_list limit set active=1 where id= $obj->id
Главное чтобы одна операция не превышала 30сек, конечно.
Если превышает — надо разрезать задания на куски, оптимизировать базу.
Например разделять одну таблицу на множество по id записи, например, создавая таблицы: