All streams
Search
Write a publication
Pull to refresh
34
0
Ермаков Денис @deermakov

User

Send message

В соседней теме задавались вопросом - почему так экстренно и втихую приняли закон о просмотре запрещенки. Вот поэтому.

Хорошая тема для исследования и статьи на Хабре )

Что касается деталей реализации, то есть большой дизайн-документ на эту тему - "Exactly Once Delivery and Transactional Messaging in Kafka", https://docs.google.com/document/d/11Jqy_GjUGtdXJK94XGsEIK7CP1SnQGdp2eF0wSw9ra8/edit#heading=h.xq0ee1vnpz4o

Скорее всего - да, второй вариант: можно положиться на менеджер транзакций Кафки, т.к. внутри Кафки есть ACID-гарантии при работе с несколькими топиками.

Хороший вопрос )

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

Плата состоит в том, что вы настраиваете transaction manager'ы и развешиваете @Transactional - это несложно. А в результате получаете, что ошибки в прикладной логике не ломают консистентность вашего приложения - а это основная доля ошибок/сбоев в приложениях. Остается непокрытым риск системных проблем - электричество выключилось, сеть отпала и т.д., но это маловероятные риски, тем более, что для поломки консистентности они должны произойти в очень маленький промежуток времени между коммитами транзакции БД и Кафки.

Суммарно, допустим, вы получаете 99,99% гарантии консистентности при небольших трудозатратах - очень неплохо, особенно по сравнению с полным отсутствием контроля )

Transactional outbox + idempotent consumer - это более существенные трудозатраты, хотя конечно не rocket science. Про eventual consistency планирую сделать отдельную статью.

Хранить consumer offsets в потребителе (и управлять ими в своем прикладном коде) - это значит брать на себя реализацию существенного объема функционала, который уже реализован в Кафке. Амбициозная задача.

Почему же странный ? "Получить сообщение + обновить БД" - это элементарный (но при этом вполне реальный) сценарий, на котором проще всего исследовать проблему. И он конечно не специфичен для BPM.

"Прочитать + обновить БД + отправить" - это просто чуть более сложный сценарий, и при этом можно усложнять и далее, комбинируя всё больше взаимодействий - но это вряд ли что-то добавит к сути статьи, скорее наоборот - замаскирует её за второстепенными деталями. То же самое на мой взгляд относится и к retries и dead letters - поддержка всего этого есть в Spring for Apache Kafka, но это выходит за рамки статьи, это вопросы, достойные отдельного рассмотрения. Тем более достойна отдельного рассмотрения тема с "остановкой consumer'а", т.к. тут возникнет куча вопросов с ребалансировкой, порядком обработки сообщений и т.д.

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

Если я правильно понимаю, то вы описываете такую ситуацию:

  1. Начата транзакция Kafka

  2. Начата транзакция БД

  3. Вычитали сообщение из кафки

  4. Обновили данные в БД

  5. Коммит транзакции БД

  6. <<выключилось электричество>>

  7. <<сообщение из кафки не вычитано (т.е. оффсет не закомитчен) >>

  8. <<после включения электричества то же самое сообщение попадет на повторную обработку>>

Если так, то да, система останется в неконсистентном состоянии, т.к. данные в БД уже обновлены, а то же самое сообщение в кафке пойдет на повторную обработку. Именно про это я и пишу и именно эту ситуацию а моделирую через параметр receive-transactions-faults-num (задайте его > 0 и увидите этот эффект.)

Забегая вперед, скажу, что лечить эту конкретную проблему можно например таким образом: запоминать в БД ключи уже обработанных сообщений и отбрасывать их при повторном получении - паттерн Idempotent Consumer (https://microservices.io/patterns/communication-style/idempotent-consumer.html). Но это усложнение решения и это точно out of scope данной статьи. Если все сложится хорошо - опишем это в отдельной статье.

Согласен, как только заказчик решает, что ему нужно что-то, чего нет в коробке - low code начинает превращаться в lot of code. С этим можно бороться только одним способом - убеждением заказчика отказаться от нестандартного функционала - и на практике это далеко не всегда получается.

Что касается lock in на подрядчика - не совсем понимаю, что вы имеете в виду. Все доработки делаются в рамках проекта, они полностью открыты заказчику, и он (т.е. его IT) при желании могут ими полностью владеть.

Information

Rating
Does not participate
Works in
Registered
Activity