Комментарии 19
чтобы Kafka не теряла сообщения
С каких пор кафка теряет сообщения? Если вы не можете настроить rf=3, isr=2, ack=all и дождаться ack от кафки, то почему это вдруг кафка теряет сообщения, а не вы криво все настроили, не разобравшись в выбранном иснтрументе?
Такое ощущение что вы прочитали только последний абзац, а не всю статью от начала до конца.
прочитал всю и даже перечитал, чтобы найти где расписано что именно кафка теряет сообщения, а не кривой код. Потрудитесь привести что ли доказательства, либо уж поправьте текст на то что вы хотели донести, чтобы не вводить в заблуждение о надежности самой кафки
Хорошо, что в финале есть оговорки про владельца продюсера и консьюмеров: именно граница ответственности обычно и определяет, когда WAL уже не заменяет Kafka. Бенчмарк с задержками тоже наглядно показывает цену «просто добавим брокер».
Какую задачу решаете?
Если задача "оповестить заинтересованных, что случилось событие1", то я не вижу этого в решении через БД. Где событие, как версионируется контракт, как подписываться на события потребителям в других сервисах?
Как выглядит предложенный вариант? В wal попадает что - событие специальное для оповещения или какая рядовая информация вида "создан заказ 123 с полями ..."?
А ещё очень подозрительно звучит идея дать репликацию эээ аутбоксов между разными БД. Вместо общей универсальной шины общения между N сервисами у вас будет каждое с каждым и комбинаторный взрыв?
ПС: я понимаю что кафка может быть перебором. Я не уверен что предложенное решение хорошее.
Все статье описано:
Рано или поздно один сервис перестаёт быть одним сервисом. Появляется второй, которому важно узнать о том же событии — обсчитать аналитику, обновить поисковый индекс, отправить письмо. Возникает соблазн просто дёрнуть его по HTTP, и это первая ошибка, которую все совершают и все же исправляют: синхронный вызов делает вас настолько же надёжным, насколько надёжен самый хрупкий из ваших соседей.
В WAL попадает все что записано в базу. Оно всегда попадает. Как прочитать WAL - на ваше усмотрение. Пример кода есть.
Понятно что попадает всё. Что вы предлагаете туда складывать? Отдельная табличка "событий" (как аутбокс) или потребитель сам начинает шариться в вашей БД в поисках "ага, вот заказы, а вот клиенты, а вот ещё история изменений статусов"?
Я предлагаю читать из самих таблиц, куда сохраняются данные пока это позволяет решить задачу.
Это прямо максимально грустно звучит. Та самая проблема, от которой все годами уходят - потребители залезли в вашу БД (за отчетами) и любые ваши изменения в сервисе теперь ломают работу потребителей. Потому что для сервиса БД - его внутренности и он их хочет менять в любой момент как сможет. А для потребителя это контракт, как же так, вы сломали мне работу!
Вы пишите в статье что кафка не нужна на маленьких объемах, а подскажите, какие у вас объемы, где используется чтение WAL и как давно вы с таким подходом работаете?
В пике видел 2000 прочитанных сообщений\сек, каждое из которых вызывало нетривиальную работу. Это был потолок для читателей, а не для WAL. WAL при этом не рос больше чем обычно.
Естественно отправители и получатели были сделаны одной командой, поэтому никаких проблем нарушения контракта не было. В статье я указал, что при очень разнородных получателях не стоит использовать прямое чтение WAL. Лучше Debenzium + Kafka тогда.
кстати а что там с фильтрацией чувствительных данных, которые легко могут попасть в WAL, но которые недопустимо светить другим сервисам?
Если вы делаете оба сервиса, то откуда такая проблема?
обычно другой сервис это другая зона ответственности, даже если делает та же команда. В этой другой зоне ответственности могут быть другие требования эксплуатации и тем более ИБ, зачем в нем решать проблемы работы с персухой например и влетать в немилость к безопасникам на приемках лишь из-за того, что сервис читает WAL в котором эта персуха летит рядом с тем что нам реально надо?
Статья наглядно показывает, что Postgres сейчас пытаются закрыть вообще все дыры — и хранилище, и транзакции, и очереди через WAL. Но у такой универсальности есть предел. Рано или поздно Postgres придется подвинуться, уступая специализированным распределенным решениям, а останутся связки под конкретные задачи.
Как по мне, баланс сил в будущем будет выглядеть примерно так:
Apache Kafka: Никуда не уйдет. Она нужна не как очередь для одного сервиса, а как сквозная шина для интеграции десятков независимых команд.
Redis / Valkey: Сверхбыстрый In-Memory кеш, когда дисковая БД (даже Postgres) начинает захлебываться на чтении.
Apache Ignite: Распределенная In-Memory БД для тяжелых вычислений «на лету» над большими данными.
NewSQL (CockroachDB, TiDB): Замена классическому Postgres, когда проект вырастает из одного сервера и упирается в шардирование.
Vector DB (Qdrant, Milvus): Специфичная ниша для ИИ и работы с эмбеддингами.
Так что Кафка останется на своем месте (в enterprise-интеграции), а вот монополия Postgres точно пошатнется в пользу распределенной памяти (Ignite/Redis) и NewSQL.
Пока мы видим ровно обратную картину. Pg все больше подъедает workload других систем. Добавление jsonb и json индексов почти похоронило nosql решения. Если бы апдейт в постгресе не был таким дорогим, то наверное уже совсем похоронило бы.
timescaleDb и pgvector прекрасно работают для подавляющего большинства задач.
Таже самая репликация и синхронизированный кэш в приложении за счет нее, о котором я писал в прошлой статье, делает Redis избыточным во многих сценариях.
Плюс железо постоянно двигает "предел универсальности".
Только когда речь заходит об очень больших нагрузках, которые есть у малой части проектов, или интеграции очень разнородных систем там без кучи дополнительных сервисов никуда.
Помимо неприятного LLM-ного стиля статьи, я осуждаю её основную мысль. Не надо использовать логическую wal-репликацию для Postgres, она плохо заменяет Kafka. Процесс walsender не очень хорошо масштабируется под большое количество соединений. Медленный получатель заставит wal расти. А если получатель отстанет достаточно сильно, то его подписку отменят, и он потеряет данные. Нет возможности распараллелить обработку данных. Debezium страдает от аналогичных проблем. Самый простой вариант: отослать в Kafka, чтобы сохранить в базу уже получателем, автор не рассмотрел.
Можете подробнее рассказать почему логическая репликация не достаточно хорошо масштабируется и большое количество соединений это сколько?
Я несколько раз слышал это аргумент, но не понял сколько это в цифрах. Сколько нужно подключений логической репликации чтобы стало катастрофически плохо работать? Я видел глазами десятки на один небольшой сервер и сервер этого фактически не замечал.
Если у нас читатель в принципе не успевает обрабатывать все сообщения в единицу времени, то без разницы что будет транспортом Kafka или WAL, рано или поздно и тот и другой потеряют сообщения из-за того, что хранилище переполнится. В базе данные сохранятся в таблицах, они сами по себе никуда не потеряются, их можно будет прочитать и обработать в пакетном режиме. Kafka потеряет насовсем.
Самый простой вариант: отослать в Kafka, чтобы сохранить в базу уже получателем, автор не рассмотрел.
В статье пример использования Kafka для МСА, где каждый сервис выполняет свою полезную работу. Если Сервис просто пересылает сообщение в кафку, то никакой полезной работы он не выполняет. Можно клиентский запрос отправить сразу на целевой сервис.

Очередь на Postgres: почему Kafka не нужна