@ugin_root

Есть ли готовые решения для очереди с десятком тысяч заранее не заданных партиций?

Проблема: нужно синхронизировать мои данные со сторонними сервисами.

Дано:
  1. Мои данные ClientId, CustomerId, CustomerEmail, CustomerPoints
  2. Четыре (в перспективе до 20) сервиса с которыми нужно синхронизировать мои данные
  3. Примерно 15 000 клиентов (ClientId), у клиентов от 1000 до 500 000 customer-ов
  4. У каждого сервиса есть rate-limit. Доступ к каждому сервису для каждого клиента осуществляется по приватному ключу, т.е. rate-limit индивидуальный для связки ClientId-ServiceName


Текущее решение:
  1. Есть kafka со 100 партициями, партиция это ClientId % 100 = (0 - 99)
  2. При обновлении данных customer-а в kafka topic пишется сообщение о том чей он клиент (ClientId) и какой у него id
  3. Проверяется с какими сервисами у клиента настроена синхронизация
  4. Запускается параллельно синхронизация со всеми активными сервисами
  5. При неудаче синхронизация повторяется до тех пор пока не выполнится (rate-limit и отказы сервисов учитываются именно сдесь)


Какие сейчас есть проблемы:
  1. При подключении нового сервиса клиентом, мне необходимо синхронизировать всех его customer-ов с этим сервисом, а их у него может быть до 500 000. Партиция забьётся и те клиенты которым не повезло оказаться с ним в одной партиции будут очень долго синхронизироваться учитывая все rate-limit-ы.
  2. При достижении rate-limit-а у определённого клиента на каком либо из сервисов, страдает синхронизация для всех остальных сервисов и для всех клиентов сообщения от которых тоже находятся в этой партиции.
  3. Если сторонний сервис выходит из строя на 20 минут, то каждая партиция в которой появится сообщение для клиента данные которого необходимо синхронизировать с этим сервисом "зависнет" на 20 минут.


Какое решение для очереди сообщений мне нужно реализовать (найти готовое):
  1. Неограниченное количество партиций
  2. Партиция должна быть строкой или составным значением (ClientId, ServiceName)
  3. Каждая партиция должна обрабатываться конкретным consumer-ом
  4. Когда в партиции заканчиваются данные она пропадает и consumer переключается на обработку другой
  5. Возможность повторной обработки сообщений в случае ошибок
  6. Проверка есть ли в очереди сообщение по его ключу и значению (это не обязательно, но желательно что-бы избежать дубликатов)
  7. Проверка размера необработанных сообщений в определённой партиции (это не обязательно, но желательно)


Сразу отброшу kafka т.к. нет возможности заранее узнать все партиции и держать огромное их количество.
Рассматривал Apache Pulsar, но там количество партиций задаётся глобально в сетингах что тоже не подходит, или я невнимательно изучал этот вопрос, если так то поправьте.
RabbitMQ совсем как мне кажется про другое.
В голову лезут мысли про свой собственный велосипед поверх:
  1. redis streams
  2. redis hset+list
  3. mongodb (но тут точно возникнут проблемы с выполнением на нескольких серверах)
  4. sqs + в памяти разбивать по очередям для каждого ClientId+ServiceName (плохо параллелится и возможны проблемы по памяти)


Может у кого-то были схожие задачи и есть готовые реализации подобных очередей?
  • Вопрос задан
  • 179 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы