Распространение push-уведомлений на нескольких рабочих

#mysql #django #celery #django-celery

#mysql #django #сельдерей #django-сельдерей

Вопрос:

Допустим, у вас есть миллионы ключей устройств Android GCM, и вы хотите отправить их в сценарии управления. Завершение работы этого скрипта займет много времени, поскольку он обрабатывает ключи в БД в виде очереди.

Вопрос: Как это реализовать быстрее? как вы отправляете эти уведомления параллельно? как вы получаете push-уведомления, близкие к реальному времени?

Одним из решений было бы создать экземпляр X числа работников celery, где каждый работник отвечает за смещение Y, при котором он начинает выборку из MySQL. Пример:

 Worker 1: starts at offset 0,
Worker 2: starts at offset 10,000,
Worker 3: starts at offset 20,000,
Worker 4: starts at offset 30,000,
Worker 5: starts at offset 40,000,

Worker 1: Restarts at offset 50,000,
Worker 2: Restarts at offset 60,000,
  

… etc

Является ли это жизнеспособным решением?

Ответ №1:

Создайте список задач в виде группы сельдерея. Кроме того, поскольку вам нужно извлекать все записи из модели Android, полезно создать отдельную задачу celery, которая будет выполнять это в фоновом режиме:

 @shared_task
def push_notification(offset, limit):
   for android in Android.objects.all()[offset:offset limit]:
       pass

@shared_task
def push_notification_to_all():
   count = Android.objects.all().count()
   limit = 100
   group(push_notification.s(offset, limit) for offset in range(0, count, limit)()

push_notification_to_all.delay()
  

Также вместо отправки

Комментарии:

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

2. Если вы используете RabbitMQ, все должно быть в порядке. Однако, если вы боитесь отправлять слишком много сообщений одновременно, вы можете разделить push_notification_all() их на меньшие партии.

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