Проектирование Повторяющейся задачи PHP/MySQL
У меня здесь головная боль от дизайна, я использую PHP и MySQL в сочетании с Java (мой проект - приложение для Android). Я должен решить, как выполнять серию вычислений на стороне сервера через регулярные промежутки времени. Здесь есть множество материалов о том, как создавать рабочие места в cron и так далее, и это здорово, я вполне могу на этом закончить, но я не уверен в том, как решать эту часть моего проекта в более широком смысле.
Приложение полностью сосредоточено на географическое расположение пользователей. Они всегда организованы в кластеры от 4 до 40, и эти кластеры образуют одну запись экземпляра в моей базе данных. Эти экземпляры могут стать активными или неактивными в любое время.
Задача
Для каждой записи в моей базе данных или, я предпочитаю экземпляр, в каждую эпоху я хочу пересчитать центроид экземпляра из его пользовательских местоположений (это достаточно просто, особенно с использованием скалярного подхода, учитывая их близость), эффективно изменение местоположения самого экземпляра путем обновления значений широты и долготы в базе данных для экземпляра. Впоследствии пользователи будут получать эти новые координаты центроида экземпляра через регулярные промежутки времени, когда они будут звонить домой.
Метод
Здесь все становится запутанным из-за моей неопытности в ранге. Я начал с написания относительно простого вычисления, включающего один запрос SQL select и одну последующую операцию обновления SQL для каждого экземпляра в каждую эпоху. Если мы предположим, что интервал обновления на данный момент составляет около 20-30 секунд, это меньше одной минуты, по-видимому, это нарушает ограничение в 1 минуту для заданий cron. (Следует отметить, что разница во времени между эпохами может быть жестко задана, если это абсолютно необходимо).
В краткосрочной перспективе выполнение этого процесса может занять незначительное количество времени из-за того, что будет очень мало экземпляров/кластеров. Тем не менее, это потенциально может привести к большому количеству SQL-запросов и большому количеству времени для обработайте все вычисления в какой-то момент позже, если число экземпляров превысит тысячи... Чтобы уменьшить ненужную нагрузку, я, естественно, хочу включить какой-нибудь механизм для исключения неактивных экземпляров, хотя, я полагаю, все еще возможно, что требуемое время вычисления может превысить интервал эпохи. Я думаю, что это проблема (намного) позже.
Вопрос
В нынешнем виде вопрос двоякий:
- Я хочу выполнить то же самое простая функция для всех активных экземпляров в каждую эпоху. Итак, есть ли более эффективный способ сделать это, чем выполнить такое количество итераций? Могу ли я каким-то образом обновить сразу несколько строк таблицы, используя один большой, окончательный запрос на обновление SQL? Действительно ли здесь очень полезно что-то вроде mysqli_multi_query()? (На данный момент у меня нет mysqli).
- Как я могу наилучшим образом реализовать таймер или механизм запуска для повторного запуска этого процесса в каждую эпоху, учитывая тот факт, что он может нарушить ограничение в 1 минуту, которое я читал о работе в cron?
Моя идея
Мой текущий подход заключается в следующем:
- Запустите один запрос SQL select, чтобы настроить все это для текущей эпохи, извлекая идентификационные номера экземпляров, для которых требуется сдвиг центроида.
- Заполнить массив PHP этими идентификаторами экземпляра
- Последовательно сдвигайте каждый экземпляр, используя цикл и одно или очень много обновлений SQL (см. Выше), чтобы записать новые пары координат в базу данных.
- Запланируйте выполнение этой задачи выход в каждую эпоху (другими словами, каждые x секунд)
Является ли приведенный выше подход обоснованным? На данный момент я планирую сделать это таким образом, если только не будет лучшего предложения. Однако у меня действительно нет четкого представления о том, как я собираюсь планировать выполнение задачи в каждую эпоху (пункт № 4)... Я осмотрел все вокруг и сам не могу решить эту проблему без какого-либо руководства, я просто еще не очень хорош. :) Как всегда, любые предложения будут с благодарностью приняты.
1 answers
Вы можете рассмотреть возможность перехода от запланированной задачи к обновлению по мере необходимости. Это довольно легко сделать, но есть компромиссы.
Добавьте поле даты и времени с именем Последнее обновление
Каждый раз, когда вы запрашиваете объект, проверяйте последнее обновленное поле на наличие
"свежесть" (в вашем случае, если это было > 30 секунд назад)Если он свежий, отправьте данные пользователю.
Если он не свежий, пересчитайте данные и сохраните это в базу данных
(обязательно измените последнее обновленное поле). Затем отправьте новый
данные пользователю.
Это устранит необходимость в запланированной задаче и избавит от ненужных затрат на обновление каждой строки. Однако это может замедлить реакцию пользователя.