Проектирование Повторяющейся задачи PHP/MySQL


У меня здесь головная боль от дизайна, я использую PHP и MySQL в сочетании с Java (мой проект - приложение для Android). Я должен решить, как выполнять серию вычислений на стороне сервера через регулярные промежутки времени. Здесь есть множество материалов о том, как создавать рабочие места в cron и так далее, и это здорово, я вполне могу на этом закончить, но я не уверен в том, как решать эту часть моего проекта в более широком смысле.

Приложение полностью сосредоточено на географическое расположение пользователей. Они всегда организованы в кластеры от 4 до 40, и эти кластеры образуют одну запись экземпляра в моей базе данных. Эти экземпляры могут стать активными или неактивными в любое время.

Задача

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

Метод

Здесь все становится запутанным из-за моей неопытности в ранге. Я начал с написания относительно простого вычисления, включающего один запрос SQL select и одну последующую операцию обновления SQL для каждого экземпляра в каждую эпоху. Если мы предположим, что интервал обновления на данный момент составляет около 20-30 секунд, это меньше одной минуты, по-видимому, это нарушает ограничение в 1 минуту для заданий cron. (Следует отметить, что разница во времени между эпохами может быть жестко задана, если это абсолютно необходимо).

В краткосрочной перспективе выполнение этого процесса может занять незначительное количество времени из-за того, что будет очень мало экземпляров/кластеров. Тем не менее, это потенциально может привести к большому количеству SQL-запросов и большому количеству времени для обработайте все вычисления в какой-то момент позже, если число экземпляров превысит тысячи... Чтобы уменьшить ненужную нагрузку, я, естественно, хочу включить какой-нибудь механизм для исключения неактивных экземпляров, хотя, я полагаю, все еще возможно, что требуемое время вычисления может превысить интервал эпохи. Я думаю, что это проблема (намного) позже.

Вопрос

В нынешнем виде вопрос двоякий:

  1. Я хочу выполнить то же самое простая функция для всех активных экземпляров в каждую эпоху. Итак, есть ли более эффективный способ сделать это, чем выполнить такое количество итераций? Могу ли я каким-то образом обновить сразу несколько строк таблицы, используя один большой, окончательный запрос на обновление SQL? Действительно ли здесь очень полезно что-то вроде mysqli_multi_query()? (На данный момент у меня нет mysqli).
  2. Как я могу наилучшим образом реализовать таймер или механизм запуска для повторного запуска этого процесса в каждую эпоху, учитывая тот факт, что он может нарушить ограничение в 1 минуту, которое я читал о работе в cron?

Моя идея

Мой текущий подход заключается в следующем:

  1. Запустите один запрос SQL select, чтобы настроить все это для текущей эпохи, извлекая идентификационные номера экземпляров, для которых требуется сдвиг центроида.
  2. Заполнить массив PHP этими идентификаторами экземпляра
  3. Последовательно сдвигайте каждый экземпляр, используя цикл и одно или очень много обновлений SQL (см. Выше), чтобы записать новые пары координат в базу данных.
  4. Запланируйте выполнение этой задачи выход в каждую эпоху (другими словами, каждые x секунд)

Является ли приведенный выше подход обоснованным? На данный момент я планирую сделать это таким образом, если только не будет лучшего предложения. Однако у меня действительно нет четкого представления о том, как я собираюсь планировать выполнение задачи в каждую эпоху (пункт № 4)... Я осмотрел все вокруг и сам не могу решить эту проблему без какого-либо руководства, я просто еще не очень хорош. :) Как всегда, любые предложения будут с благодарностью приняты.

Author: Chaos, 2012-07-17

1 answers

Вы можете рассмотреть возможность перехода от запланированной задачи к обновлению по мере необходимости. Это довольно легко сделать, но есть компромиссы.

  • Добавьте поле даты и времени с именем Последнее обновление

  • Каждый раз, когда вы запрашиваете объект, проверяйте последнее обновленное поле на наличие
    "свежесть" (в вашем случае, если это было > 30 секунд назад)

  • Если он свежий, отправьте данные пользователю.

  • Если он не свежий, пересчитайте данные и сохраните это в базу данных
    (обязательно измените последнее обновленное поле). Затем отправьте новый
    данные пользователю.

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

 4
Author: MrGlass, 2012-07-17 14:09:52