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

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

Этап 1. Разделение зон ответственности сервисов

На первом этап мы выделяем по одному солдату на два участка работы: первый будет приносить картошку из погреба, а второй — чистить то, что принес первый и сбрасывать в кастрюлю для варки. Запускаем процесс, смотрим что получилось:

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

Этап 2. Масштабирование

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

Делаем это упражнение и узким местом становится носильщик. Пытаемся таким же образом оптимизировать носильщика и накинуть ресов уже ему, но так как вся картошка разная и все люди работают в разном темпе — сбалансировать работу не получается. Кто то все равно простаивает.

Говоря айтишным языком, у нас есть несколько оптимизированных экземпляров приложения, которые работают параллельно. Плюс еще добавился прокси‑сервер: сержант‑балансировщик, который следит кому из чистильщиков можно отдать картошку, а также смотрит чтобы не несли гнилую (первичная валидация запросов переходит в область полномочий прокси). Проблема стала менее очевидной, время простоя рабочих сократилось, но не ушло совсем. Помимо этого в системе стало много экземпляров приложения, за которыми надо следить, кормить, и обслуживать. Мониторинг системы становится сложнее.

Этап 3. Сервис очередей

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

Как вы уже наверное поняли, роль сервиса очередей у нас тут играет тот самый таз. Сообщения в очереди — картошка. Носильщики начинают называться умным словом «продюсер», а чистильщики — «консьюмер».

Теперь поговорим айтишным языком как же можно еще оптимизировать процесс, чтобы он шел быстрее:

  • Увеличиваем размер сообщения: носильщики начинают носить картошку из погреба не по одной, а сразу ведрами. Это называется умным словом «массив».

  • Выдаем чистильщику электрический станок для чистки, в который он может загрузить сразу все ведро или даже три. Это уже «Batch processing».

Этап 4. Анализ рисков

Что же может пойти не так:

  • Мы с вами в армии. Если солдаты оставили картошку в тазу и ушли спать, то утром они найдут пустой таз, из которого всю картошку украли. Это называется «Retention time». В реальной жизни он используется для того, чтобы таз не переполнялся, так как обработанные сообщения из Kafka никуда не деваются, просто условно помечаются как обработанные. Это позволяет, например, при необходимости обработать сообщение еще раз после ошибки.

  • Таз могут опрокинуть. Для этого картошка делится на несколько тазов. Да и брать картошку для чистки удобнее каждому чистильщику из своего таза. Это называется «партиции». Если один таз опрокинут — работа не встанет пока будут собирать картошку из него обратно. Если один из чистильщиков уйдет отдохнуть - из его таза картошка будет распределена по другим.

  • Таз может опустеть. Количество картошки в тазу называется «Consumer lag». И если он слишком сильно растет — таз может либо начать переполняться и терять сообщения (картошка посыпалась на пол, по умному — Retention bytes). Надо за этим следить и заранее масштабировать чистильщиков или освобождать носильщиков.

Этап 5. Какие есть возможности?

Какой-нибудь умный командир может потребовать доставать из таза картошку, например, по цвету.

  • Надо помнить, что сервис очередей это не база данных, и все что там лежит — достается так, как отдает очередь

  • Можно сделать так, чтобы картошку чистили разные группы людей. Это называется «Консьюмер‑группа». Например, если синяя картошка идет на жарку, а белая на варку — разные консьюмер группы могут по разному обрабатывать сообщения.

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

Комментарии (13)


  1. gleb_l
    03.11.2024 09:19

    Армейский GPSS


  1. Farongy
    03.11.2024 09:19

    Например, если синяя картошка идет на жарку, а белая на варку — разные консьюмер группы могут по разному обрабатывать сообщения.

    Жаль, что в отличии от сообщения, одну картошку нельзя почистить дважды - и на варку, и на жарку =)

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


    1. rgridnev Автор
      03.11.2024 09:19

      Благодарю за указание на неточность. Поправил текст. Про многократное чтение долго думал как вписать в пример, но ничего путного в голову не пришло.


  1. gleb_l
    03.11.2024 09:19

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


    1. nixtonixto
      03.11.2024 09:19

      Однако в результате аппроксимации резко уменьшается объём полезных данных, в итоге пакет для передачи заполняется медленней, чем ожидалось, а потери детализации могут вызвать законное негодование потребителя.


    1. rgridnev Автор
      03.11.2024 09:19

      это волшебно )) Сразу видно что процесс не чужд автору )


  1. scome
    03.11.2024 09:19

    Аналогия прикольная, спасибо)

    Не понял, как(кем) таз демобилизованного/потерявшегося чистильщика будет распределен между другими? И кто вообще и как решает, в какой таз ссыпать картошку?


    1. rgridnev Автор
      03.11.2024 09:19

      Согласен, тема осталась не раскрыта, вернем сержанта на место ))


  1. grey-fox
    03.11.2024 09:19

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

    Статью лучше было назвать rabbitmq и картошка. И тогда можно расширить примеры. Описать такой процесс как пересменка солдат, когда один солдат меняет другого (деплой воркеров). И тогда недочищенная картошка возвращается в таз (очередь). Или если в тазу попадается батат и солдаты бросают его в отдельный таз, который уходит другим солдатам. Ну и много чего ещё.

    Про различия kafka и rabbitmq можно почитать, например, в этой статье на хабре: https://habr.com/ru/companies/itsumma/articles/416629/.


    1. kzkvv
      03.11.2024 09:19

      Push модель у rabbitmq совсем не ложится на пример с картошкой. А pull у Kafka идеально подходит.


  1. Bender_Rodrigez
    03.11.2024 09:19

    И раз уже до ИТ мне посчастливилось почти 10 лет отслужить в армии то пример, который очень зашел даже далеким от ИТ людям, со временем родился сам собой.

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

    мы — проектировщики системы (командиры).

    Больно много чести вы себе выписали. А что не фельдмаршалы?

    Это уникальное свойство офисного планктона, который вышел, в лучшем случае, из тех же "солдат", ассоциировать себя с тем, чем они не являются. А помните, как в детстве, когда в Чапаева играли, когда вы могли быть Чапаем, а кто-то Петькой, а? Так вот, тут таких "Петек"-то достаточно, кого эти "тонкие" сравнения цепляют, что ставит вас самих в не очень удобное и выгодное для вас самих положение.

    Если бы солдаты были айтишниками

    А айтишники солдатами? Отличное НЛП, слышали, знаем - это мечта любого посредственного менеджера, - руководить, отдавая приказы, и чтобы в ответ им и слова не было, ведь другим способом непрофессиональные сумасброды управлять проектами не умеют, но, увы, это гражданский сектор и люди с образованием не хуже вашего.

    Согласно нашим вводным солдаты, как и информационные системы, не умеют и не должны сами принимать решения, они делают только то, что мы им поручили.

    Удачи жрать полуочищенную зеленую картошку с глазками then.

    Мы с вами в армии.

    Мы с вами - нет. У вас, по всей видимости, рекуррентное посттравматическое расстройство с галлюцинациями.

    Таз могут опрокинуть. Для этого картошка делится на несколько тазов.

    Могут опрокинуть сразу несколько тазов. Поэтому пример, таки, неудачный.


    1. rgridnev Автор
      03.11.2024 09:19

      С интересом почитал, спасибо. Даже не знаю что тут ответить и у кого из нас реально есть какие то травматические расстройства, связанные с армией ))

      Про полуочищенную картошку с глазками - так может написать только тот, кто ни разу не видел этот процесс в живую. Потому что именно так он чаще всего и происходит. И для себя наряд по кухне нередко готовит отдельно чтобы не есть то что приготовили остальным.

      Несколько тазов опрокинуть могут, как и вырубить несколько серверов и даже целый датацентр.

      Да, в моем примере с армией тот, кто принимает решения называется словом "командир" и никого это никоим образом не корёжит. Ну нет там названий "тимлид" и "швабра-менеджер". И так же как в случае "командир-подчиненный" в ситуации "инженер - система" система не спорит с инженером, она делает только то, что в нее заложено.


  1. xammer
    03.11.2024 09:19

    Вот и выроло поколение IT , которые не знают спецификации JMS - пишут статьи по наитию, как они видят... Треш.