Comments 17
Пойду-ка я обратно монолиты писать, извините.
+6
Справедливости ради, там тоже встречаются те же самые проблемы, просто намного реже.
0
В монолитах есть готовые инструменты согласованности предоставляемые другими системами — реляционными СУБД. Навешал разных констрейнтов на данные и сиди довольный. А в микросервисах — только свои велосипеды.
0
UFO just landed and posted this here
Идемпотентность, увы, не помогает против нарушения порядка сообщений.
+2
Возможно я не знаю какого-то красивого решения. Подскажите, пожалуйста, как сделать идемпотентным пример из статьи с сообщением о переименовании пользователя? Чтобы несколько таких сообщений перемешанных и повторённых давали правильный результат.
0
А обработка этого сообщения уже идемпотентная. Только не вполне понятно зачем об этом говорить.
+1
UFO just landed and posted this here
Например указывать версию, к которой применяется изменение. Либо полностью, либо номер (поколение), чтобы разрулить конфликты. Тогда при перемешивании и частичном применении можно отбросить транзакции, у которых версия ниже текущей. А вообще, такие вещи надо убивать на корню. СУБД создана, чтобы разруливать такие конфликты.
+1
UFO just landed and posted this here
Делал недавно, вариант с kafka exactly-once
Но у меня не завелось Timeout expired after 60000milliseconds while awaiting InitProducerId. Так не разобрался в чем причина. Без транзакций отправка работает, в итоге сделал отслеживание повторных передач через БД.
Но у меня не завелось Timeout expired after 60000milliseconds while awaiting InitProducerId. Так не разобрался в чем причина. Без транзакций отправка работает, в итоге сделал отслеживание повторных передач через БД.
0
Неоднозначное решение, на мой взгляд.
Во-первых совершенно не факт, что надо вообще хранить данные для повтора в самой кафке и тем более в виде исходного сообщения, которое мы не смогли обработать, но почему-то решили, что сможем правильно скопировать. Да, можно сказать, что вдруг БД недоступна, но тогда не надо уходить на повторы, надо просто вызывать инженеров и чинить БД.
Во-вторых часто публикуется «полное» идемпотентное событие, таким образом когда мы обработали сообщение Zoiee, то обрабатывать Zoё уже просто не нужно.
Как альтернативное решение:
1. Проблемные события сохраняем в спец-таблицу БД как ID + партишен + оффсет
2. Удаляем из неё старое сообщение, как пришло новое сообщение с тем же ID
Бонусы:
— Размер таблицы есть метрика рассинхронизации состояний, по ней можно настроить алерты
— Не уложняем картину в кафке, в которой не всегда можно красиво разделить доступ
— Можно запускать вручную повторные попытки потребления отдельных сообщений
— Можно устроить сколь угодно сложную логику повторных попыток
Во-первых совершенно не факт, что надо вообще хранить данные для повтора в самой кафке и тем более в виде исходного сообщения, которое мы не смогли обработать, но почему-то решили, что сможем правильно скопировать. Да, можно сказать, что вдруг БД недоступна, но тогда не надо уходить на повторы, надо просто вызывать инженеров и чинить БД.
Во-вторых часто публикуется «полное» идемпотентное событие, таким образом когда мы обработали сообщение Zoiee, то обрабатывать Zoё уже просто не нужно.
Как альтернативное решение:
1. Проблемные события сохраняем в спец-таблицу БД как ID + партишен + оффсет
2. Удаляем из неё старое сообщение, как пришло новое сообщение с тем же ID
Бонусы:
— Размер таблицы есть метрика рассинхронизации состояний, по ней можно настроить алерты
— Не уложняем картину в кафке, в которой не всегда можно красиво разделить доступ
— Можно запускать вручную повторные попытки потребления отдельных сообщений
— Можно устроить сколь угодно сложную логику повторных попыток
+1
Retry topic: популярное ходовое решение
Это годится, если трафик небольшой. Но вообще делать подобное на кафке это злое зло. Кафка это не брокер сообщений. Приходящие в топик сообщения из него не исчезают после прочтения, а живут там, пока их не прибьет политика по подчистке старых сообщений, которой будет пофиг, читал эти сообщения кто-то или нет. Если трафик большой, то мало того, что весь этот дополнительный поток сожрет дополнительные ресурсы у кафки (а переваривает она не так чтобы много топиков и партишенов). Так он еще будет забивать диски кучей дубликатов. Все эти разные retry топики будут хранить копии одних и тех же сообщений.
Если уж так хочется, то лучше эти повторы хранить где-то в другом месте, которое имеет необходимую семантику. Тот же полноценный брокер сообщений. Да или хоть редис банальный.
+1
Спасибо за статью. Сам испытываю проблемы с обработкой ошибочных сообщений из кафки, хотел прикрутить retry topic. У меня ситуация немного другая — кафка используется для асинхронного request-reply, т.е. есть, куда ответить об ошибке. Но с "плохими" сообщениями это дела не меняет.
Описанный подход выглядит логичным решением проблемы, разве что нужен механизм повторной публикации сообщений из отстойника.
+1
Sign up to leave a comment.
Используете Kafka с микросервисами? Скорее всего, вы неправильно обрабатываете повторные передачи