Ещё есть одна причина: вертикальный скейл дороже горизонтального.
🦾
🦾 IT-Качалка Давида Шекунца 💪
2023-10-30 17:51
Разве? Мне кажется, что вертикальный скейл часто дешевле взятия новой тачки (потому что там всегда есть статическая стоимость за штуку)
У него есть четкие лимиты и он намного дороже в момент, когда вы в эти лимиты уперлись, это да
A
Arthur G
2023-10-30 18:00
Это если нагрузка одинаковая. А если есть пики и просадки?
🦾
🦾 IT-Качалка Давида Шекунца 💪
2023-10-30 18:02
Да, тут полностью согласен
C
CENTURIONO
2023-10-30 20:30
Да, так и есть. Кейс только о потолке, а он отличается, но всегда присутствует.
🦾
🦾 IT-Качалка Давида Шекунца 💪
2023-11-05 08:37
В прошлом посте я рассказывал про проблему с RMQ при которой он самостоятельно убивает очереди и не сообщает об этом.
Это было настолько дикое поведение, что оно должно было быть или так глубоко в RMQ, что мало кто туда залезал, или настолько на поверхности, что я просто не увидел очевидного.
Сколько я не капался в дип-нете на тему моей проблемы, я не находил ничего подходящего, поэтому решил пойти с другого конца: перечитать Getting started
В очередной раз я прохожу абзац, в котором написано: "вы не должны использовать auto-delete очереди, если сами задаете им название" – и пример: "если вы создадите очередь с auto-delete, отключитесь от одной ноды, а потом быстро переключитесь на другую, то RMQ не поймет что делать и у вас возникнут ошибки на стороне клиента"
А мы и создаем auto-delete именованные очереди (для чего расскажу в следующем посте) и это именно то, что нам было нужно от RMQ
И скажу больше, в описанном выше кейсе он правда присылает ошибку и закрывает connection, но это абсолютно нормальное поведение, RMQ вообще любит на любой чих закрыть connection, поэтому вся наша логика написана так, чтобы реконнектиться и восстанавливать все подписки.
И тут я подумал: "а что если эта гнида также ведет себя в момент выпадения одной из нод, но при поднятии просто не отправляет нам разрыв connection из-за рейсинга конфигурации?" – и я блять оказался прав
Когда нода на которой auto-delete очереди отрывается от кластера (даже на пару секунд) и при этом consumer-ы находятся на соседней ноде, то кластер не закрывает их соединения и не кидает ошибок, но при этом удаляет очередь...
И единственный сука адекватный способ решения проблемы – сделать все очереди реплицируемыми (quorum) и поразительно, но именно это моментально превращает RMQ просто в умственноотсталую версию Kafka
Но описание почему слишком больше, поэтому расскажу в следующем посте
🦾
🦾 IT-Качалка Давида Шекунца 💪
2023-11-06 10:44
У нас есть было 2 стула вида коммуникации
Event Driven Architecture (выкинули event и забыли, а с другой стороны кучей читателей прочитали) и RPC (отправили запрос, ждем ответ от 1 читателя) + ясен пень, это все должно работать в кластерном режиме хотябы из 3-х нод
EDA должен нам гарантировать: "если мы выкинули event и увидели, что он попал в очередь, то с другой стороны его рано или поздно смогут прочитать в правильной последовательности нужное кол-во инстансов"
RPC должен гарантировать: "если читателя нет, то мы должны об этом узнать, чтобы сделать retry, если его так и не появлось, то вернуть timeout, а если читатель есть, то в оптимальный промежуток времени получить ответ или вернем timeout"
Заходят в бар RMQ, NATS и Kafka
NATS – message broker, то есть его задача дать возможность подписаться и отправлять сообщения в топики в формате fire-and-forget, при этом он не гарантирует очередность.
Он отлично подходит для RPC (в нем даже есть вшитый модуль), но поскольку он не гарантирует последовательность и что сообщение дойдет до читателя, который еще не успел подняться, мы не можем использовать его для EDA (сразу скажу, JetStreams не рассматриваем)
Kafka – распределенный лог: записываем в конец и читаем с желанного момента (оффсета)
Прекрасно решает вопрос EDA (сложность только в рассчете партишенов и реализации внешних локов на очереди, но об этом ниже) и в целом можно реализовать RPC (он просто будет немного "жирным")
RMQ – это что-то среднее между двумя мирами: fire-and-forget, с гарантированной последовательностью, а распределение и уникальность достигаются параметрами очереди (exclusive, single-active-consumer, durabitlity, etc.) и жанглированием видами exchange + queue
В теории, он хорошо решает вопрос RPC (в нем даже есть встроенный RPC плагин) и, заисключением долговременного хранения сообщений, он даст нам все нужные для EDA характеристики, даже с возможностью выбирать между скоростью (отсутствие репликации) и надежностью (латентная Kafka репликация)
На практике же это гавно работает нормально только при определенных настройках из-за которых он становится херовой альтернативой как NATS, так и Kafka
Мульти-тул = зеро-кволити
Так вот, RMQ очень любит разъебать кластер и не собрать его.
Во-первых, для RMQ абсолютная норма показывать вам, что все в порядке, все очереди и exchange есть, но на деле при попытке записи или потребления ничего происходить не будет ДАЖЕ ОШИБКИ. Почему? Потому что он неправильно синхронизировал свою конфигурацию. Как лечить? Или ручным удалением очередей, или перезагрузкой ноды, или сменой всего кластера (я не шучу, нам приходилось все 3 варианта делать)
Во-вторых, если вы не используете quorum (реплицируемые) очереди или используете любой вид TTL на очередях, то любые проблемы в кластере гарантируют вам или полную дисфункцию этих очередей, или полную дисфункцию кластера.
А если вы используете quorum очереди, то готовьтесь к мощной деградации скорости передачи и обработки сообщений.
То есть, чтобы RMQ работал стабильно, нам придется превратить его в более медленную версию Kafka без персистентного лога.
Из преимуществ остается только его встроенная система управления читателями, НО смехуючек в том, что в итоге, если вы хотите не просто иметь "одного читателя в моменте на очередь", а "по одному читателю в моменте на набор очередей с балансировкой кол-ва очередей к читателям" (а это частый кейс), вам так и так придется самостоятельно реализовывать локи на очереди, как и на Kafka...
Для меня это очередной кейс "швейцарского ножа", который может, но херов во всем
Можно ли использовать RMQ? Если вы будете использовать quorum очереди без частого их создания, вам достаточно fire-and-forget и при этом не хотите разбираться с партишенами, курсорами и распределением в Kafka, то да RMQ будет делать свое дело.
В остальных случаях, при выборе между RMQ и Kafka, лучше выбрать Kafka. С ней гораздо больше проблем вначале, но потом можно хотябы спать по ночам.
🦾
🦾 IT-Качалка Давида Шекунца 💪
2023-11-06 10:49
Ах да, еще одно интересное умозаключение:
RMQ даст вам кучу возможностей, но они будут работать только пока он в 1 инстансе, встает вопрос: "а зачем вообще их давать?" – а потому что RMQ все-таки в первую очередь технология, которая предполагает работу в 1 инстансе и все дальнейшие навороты с кластером это фичи, которые пришли постфактум, потому что время и рынок диктовали условия
Но эта технология очень плоха в кластеризации
Поэтому второй вариант использования RMQ: если вам достаточно 1 инстанса, то вы тоже (наверное) спокойно можете использовать RMQ
🦾
🦾 IT-Качалка Давида Шекунца 💪
2023-11-06 10:55
И еще раз подытоживая я отметил бы 2 момента:
1. Вместо того, чтобы жестко ограничить какие-то свойства очередей в случае наличия кластера, они часто пишут "рекомендации" (не)использовать ту или иную фичу в кластере
Но если эта фича полностью ломает очереди при кластеризации, то это нехера не "рекомендации" это просто надо запрещать использовать и все
2. Если уж RMQ добавили возможность кластеризации, то сделайте синхронизацию конфигурации надежной, даже в ущерб скорости.
Потому что сейчас система может говорить "все ок", а на деле вообще не работать, и ты никак этого не увидишь пока просто не попробуешь отправить / получить сообщение и при этом ничего не произойдет.
И если бы эти 2 пункта были, то моя претензия осталась бы на уровне: "В итоге, RMQ это упрощенная, но более медленная альтернатива Kafka" – и в такой формулировке я бы мог доверять технологии, а при текущей ситуации, когда она ломает кластер и вообще ничего об этом не сообщает доверия 0