LINUX.ORG.RU

job сервер

 , , ,


0

3

Есть задача организовать отложенную запись данных(чтобы endpoint’ы не захлёбывались.

Как пример: Есть chat-data, который имеет апи записи и чтения сообщений. Есть entrypoint chat, который предоставляет клиенту возможность писать другому пользователю сообщения и читать сообщения, которые адресованы этому пользователю.

Если писать и читать сообщения напрямую, есть несколько узких мест:

  1. при большой нагрузке chat-data и chat могут захлёбываться
  2. при отключении chat и\или chat-data сообщения не будут записаны в базу

Это просто пример, это касается всех действий пользователей, которые выполняют какие-то действия(события). Как это пофиксить? Скорей всего, необходим какой-то job-сервер, в который будут прилетать job’ы. Эндпоинт или entrypoint(?) подписывается на rabbitmq очередь, в которой он будет получать события «есть задача». Далее эндпоинт или энтрипоинт идет на job-сервер, блокирует записи, над которыми работает и начинает выполнять job’ы. Допустим в 8 потоков(настраиваемо должно быть). И выполняет их до тех пор, пока их не будет ноль. После выполнения - производится удаление job’ов.

Т.е получается, что chat chat-data могут быть отключены. При этом сообщения падают в job-сервер. Как только chat chat-data включаются, они заходят на job-сервер и начинают оттуда брать job’ы. Это правильно архитектурно? Или как-то по-другому надо делать?

Вопрос по job-серверу. Rabbitmq позволяет изменять messag’и? Т.е я делаю queue, туда прилетают job’ы. В отдельном queue прилетают нотификации о наличие job’ов. Эндпоинт или энтрипоинт выбирает несколько сообщений, блокирует их и начинает выполнять. По окончанию - удаляет их из queue. Rabbitmq позволит так делать? Или делать отдельный job-сервер с апи добавления задач и записи их, скажем, в postgresql?

★★★★

Ответ на: комментарий от korvin_

В rabbitmq можно поставить блокирование записей на изменение? Т.е Есть 3 инстанса chat-data. Всем им сигнализируется о наличие job. Первый кто успел - идет блокирует изменение записей(при этом можно в очередь добавлять записи). Далее выбирает N записей, проставляет этим записям статус blocked_by_endpointname. Далее разблокирует queue на изменение(чтобы другие инстансы могли забирать другие job’ы. Далее производит манипуляции над этими записями и удаляет их. Rabbitmq позволяет это сделать?

bryak ★★★★ ()
Ответ на: комментарий от bryak

В rabbitmq можно поставить блокирование записей на изменение?

В rabbitmq нет «записей» и их изменения.

Первый кто успел - идет блокирует изменение записей(при этом можно в очередь добавлять записи).

Первый кто успел — «вытаскивает» сообщение (или N сообщений) из очереди, остальные его (их) уже не видят.

Далее разблокирует queue

Очередь при этом не блокируется.

Далее производит манипуляции над этими записями и удаляет их. Rabbitmq позволяет это сделать?

Да. Будь мужиком — почитай документацию.

korvin_ ★★★★★ ()

Т.е я делаю queue, туда прилетают job’ы. В отдельном queue прилетают нотификации о наличие job’ов. Эндпоинт или энтрипоинт выбирает несколько сообщений, блокирует их и начинает выполнять. По окончанию - удаляет их из queue. Rabbitmq позволит так делать?

Ну через костыли можно сделать, но зачем?

Одна очередь, куда кладутся джобы. Их оттуда выбирают воркеры. Когда воркер работу закончил он говорит rabbit'у "я все", сервер задачку удаляет. Если воркер не уложился в таймаут или свалился и не сообщил об успешном завершении - сервер вернет задачу в очередь. Никакие блокировки опять же не нужны, сервер будет делать это сам.

Допустим в 8 потоков(настраиваемо должно быть).

Сколько воркеров у вас будет читать очередь, столько потоков и будет, все просто. Можно, конечно, заставить воркер брать несколько сообщений и организовать параллельное выполнение внутри, но зачем?

Или делать отдельный job-сервер с апи добавления задач и записи их, скажем, в postgresql?

Использовать БД для очередей это вообще какое-то извращение из нулевых, не делайте так.

micronekodesu ★★ ()
Ответ на: комментарий от micronekodesu

Одна очередь, куда кладутся джобы. Их оттуда выбирают воркеры. Когда воркер работу закончил он говорит rabbit’у «я все», сервер задачку удаляет. Если воркер не уложился в таймаут или свалился и не сообщил об успешном завершении - сервер вернет задачу в очередь. Никакие блокировки опять же не нужны, сервер будет делать это сам.

Можно подробней, как это реализовать. Имеено про

Когда воркер работу закончил он говорит rabbit'у "я все", сервер задачку удаляет. Если воркер не уложился в таймаут или свалился и не сообщил об успешном завершении - сервер вернет задачу в очередь

autoAck = true?

bryak ★★★★ ()
Последнее исправление: bryak (всего исправлений: 1)
Ответ на: комментарий от bryak

autoAck = true

Нет, это наоборот будет помечать сообщения в очереди обработанными как только их воркеру передадут, вам нужно это отключить. На питоне "ручное подтверждение" делается вот так:

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)
    time.sleep( body.count('.') )
    print(" [x] Done")
    ch.basic_ack(delivery_tag = method.delivery_tag)

channel.basic_consume(queue='hello', on_message_callback=callback)

ch.basic_ack как раз и подтвердит что сообщение успешно обработано.

micronekodesu ★★ ()
Последнее исправление: micronekodesu (всего исправлений: 1)

Т.е получается, что chat chat-data могут быть отключены

Не получается. И вообще нишиша не получается. Пока сообщения висят в очереди их никто не видит. У тебя интерактивный чат, или где?

блокирует их

Это отдельный прикол. Блокирует и по какой-то причине помирает. Дальнейшие действия?

no-such-file ★★★★★ ()
Ответ на: комментарий от no-such-file

Предложи свой вариант. Может в теле сообщения указывать какой инстанс это должен обработать(рандомно выбирать). А может надо один сервер job-server, с несколькими инстансами, который будет сообщения обрабатывать хз хз

bryak ★★★★ ()
Последнее исправление: bryak (всего исправлений: 1)
Ответ на: комментарий от no-such-file

Как вариант любой другой инстанс должен проверять сообщения с локом другого инстанса и если лоченные месаги больше какого-то таймаута - перелочивал на себя и выполнял их. Скажем еще добавить поле lock_timestamp. И чекать и его(в случае переанлока)

bryak ★★★★ ()
Последнее исправление: bryak (всего исправлений: 1)

Есть задача организовать отложенную запись данных(чтобы endpoint’ы не захлёбывались.

Затея неплохая, но давай я тебе подпорчу настроение.

А кто тогда будет захлебываться? Если ты считаешь, что ендпойнты не справляются (что это вообще такое?), то почему ты решил, что кто-то другой справится? Если он справится, то почему нельзя так же организовать ендпойнты?

Если (когда) он, другой будет не справляться, то что будет с джоб сервером? Сколько он должен прожить? Если он пишет в память, то что будет с данными, когда он ребутнется или сдохнет по OOM? Если тебе эти данные не нужны, то зачем ты их вообще пишешь?

Если они нужны, то как обеспечивать надежное хранение, если у тебя даже ендпойнты захлебываются, а центральный джоб сервер тем более будет. Или не будет, но тогда почему?

А как ты будешь сообщать клиентам, что их данные записались? Обратная связь традиционно очень слабая сторона микросервисной архитектуры и шины. Вместо синхронного вызова функции в локальном адресном пространстве какие то посылки данных по сети, которые постоянно находятся в состоянии: неизвестно обработали эти данные, но точно известно, что нам ещё не ответили.

max_lapshin ★★★ ()
Ответ на: комментарий от max_lapshin

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

cdshines ★★★★ ()
Последнее исправление: cdshines (всего исправлений: 1)

Есть задача организовать отложенную запись данных(чтобы endpoint’ы не захлёбывались

Нет такой задачи. Если у тебя «endpoint’ы захлёбываются», значит не хватает трупута и отложенная запись только жрёт память, вообще никак не решая проблему. Про балансировку выше верно сказали. Но поскольку у тебя сообщения(уж не мгновенные ли)

предоставляет клиенту возможность писать другому пользователю сообщения и читать сообщения

, т. е. нет большого разброса по ресурсоёмкости задач, никакая очередь опять не нужна.

cppsektant ()

Как правильно написали выше - читай доку на рэббит, там все что нужно есть и есть про подводные камни. Он позволяет сделать то что ты хочешь, но немного не так как ты себе это видишь. Посмотри в сторону кафки и тарантула(он визуально не про то, но там есть модуль очередей), возможно они подойдут лучше под задачу. А ещё лучше подумай над задачей ещё раз, сходу непонятно зачем для чата очереди, это очень странное решение для этой задачи

cobold ★★★ ()
Ответ на: комментарий от cobold

Ого ты умный, а балансировать оно будет куда? На бэкенд, а бэкенд «захлёбывается» по словам тс

Именно поэтому у load balancer’а есть встроенная очередь, которую не нужно велосипедить. И есть уйма внезапно умных алгоритмов, которые ТС не будет велосипедить вокруг своей очереди. И load balancer зачастую умеет запустить/потушить ещё несколько инстансов бэкенда в пределах заданных лимитов.

x3al ★★★★★ ()

Эндпоинт или entrypoint(?) подписывается на rabbitmq очередь, в которой он будет получать события «есть задача».

Технически, это можно сделать через http вместо rabbitmq. Тогда это выглядит как «эндпойнт (worker) тупо хэндлит запросы по некоторому URL».

После выполнения - производится удаление job’ов.

Нет. После неполучения ответа от воркера твой клиент, load balancer или какой-нибудь сторонний процесс при необходимости пытаются перезапустить задачу (если клиент — это может быть вручную, при этом ты можешь хэндлить ситуацию «оригинальный воркер не умер, он просто долго думает» чтобы избежать двойной отправки сообщения хоть тупо дедупликацией).

А задача — это всего лишь факт запроса к твоему воркеру. Её нельзя удалить потому, что она уже исчезла к этому моменту.

x3al ★★★★★ ()

при отключении chat и\или chat-data сообщения не будут записаны в базу

Если ты хочешь тупо разделить фичи на, например, «прямо сейчас покажи это сообщение пользователю» и «когда будет время, проанализируй это сообщение и вытяни оттуда умную аналитику о пользователе» — ты хочешь kafka либо aws kinesis, а не job-сервер.

x3al ★★★★★ ()