интервьюер: Сегодня я хочу спросить, что вы думаетеКафка потеряет данные?
Кандидат: Ну, при использовании Kafka могут быть следующие сценарии, когда сообщения будут потеряны
Кандидат: Например, когда мы используем производителя для отправки сообщения брокеру, сообщение может быть потеряно.
Кандидат: Если не хотите потерять сообщение, при отправке сообщения нужно выбрать апи с callBack для отправки
Кандидат: На самом деле это означает, что если вы успешно отправите сообщение, оно перезвонит вам, чтобы сообщить, что оно было успешно отправлено. Если это не удается, хорошо повторить попытку самостоятельно после получения обратного вызова.
Кандидат: После того, как сообщение отправлено Брокеру, сообщение также может быть потеряно
Кандидат: Как правило, наша онлайн-среда находится в кластерной среде, но, возможно, брокер зависает после того, как вы отправляете сообщение.В это время зависший брокер не успел синхронизировать данные с другими брокерами, и данные, естественно, будут потеряны.
Кандидат: После отправки Брокеру нет гарантии, что данные не потеряются, ведь Брокер будет хранить данные на диске и использовать кеш операционной системы.
Кандидат: то есть процесс асинхронной очистки также может привести к потере данных.
Кандидат: Ну, я уже упоминал здесь три сценария, а именно: производитель->брокер, синхронизация между брокером->брокером и брокер->диск
Кандидат: Решить указанные выше проблемы относительно просто, а об этой и говорить нечего...
Кандидат: Если вы не хотите терять данные, используйте API с обратным вызовом и установите такие параметры, как acks, повторные попытки, фактор и т. д., чтобы гарантировать, что сообщения, отправленные Producer, не будут потеряны.
интервьюер:В порядке...
Кандидат: Вообще говоря, существует много сценариев, когда клиенты потребляют брокеров и теряют сообщения.
интервьюер:Так как же обеспечить надежность данных при их использовании?
Кандидат: Прежде всего, если данные о потреблении на стороне клиента не могут быть потеряны, нельзя использовать автофиксацию, поэтому ее необходимо отправить вручную.
Кандидат: Вот что мы здесь делаем:
Кандидат: 1. При вытягивании сообщений из Kafka (вытягивание 500 сообщений пачками, тут в основном зависит от конфигурации)
Кандидат: Во-вторых, назначьте msgId (приращение) каждому извлеченному сообщению.
Кандидат: 3. Сохранить msgId в очереди памяти (sortSet)
Кандидат: В-четвертых, используйте Map для хранения отношения сопоставления между msgId и msg (с информацией, связанной со смещением).
Кандидат: 5. Когда бизнес завершит обработку сообщения, при подтверждении получите msgId обрабатываемого в данный момент сообщения, а затем удалите msgId из sortSet (это означает, что оно было обработано в это время)
Кандидат: 6. Затем сравнить его с первым идентификатором первой части очереди sortSet (фактически наименьший msgId), если текущий msgId
Кандидат: 7. Даже если система зависнет, она начнет дергать из сообщения шапки команды sortSet при следующем перезапуске, чтобы добиться хотя бы одной семантической обработки
Кандидат: 8. Будет небольшое количество повторений сообщений, но пока нисходящий поток является идемпотентным, все будет в порядке.
интервьюер: Ну, вы еще упомянули об идемпотентности, как ваш бизнес пришел к идемпотентности?
Кандидат: Хорошо, возьмем для примера обработку сообщений о заказах.
Кандидат: Идемпотентный ключ состоит из номера заказа + статуса заказа (статус заказа будет обработан только один раз)
Кандидат: Перед обработкой мы сначала проверим, существует ли ключ в Redis, если он есть, значит, мы его обработали и отбрасываем напрямую.
Кандидат: Если Redis не обработал его, продолжайте обработку.Конечная логика заключается в том, чтобы вставить обработанные данные в бизнес-БД и, наконец, вставить идемпотентный ключ в Redis.
Кандидат: Очевидно, что идемпотентность не может быть гарантирована только через Redis (:
Кандидат: Итак, Redis на самом деле просто "предварительная обработка", а конечная идемпотентность гарантируется уникальным Ключом базы данных (уникальный Ключ - это фактически номер заказа + статус)
Кандидат: Как правило, идемпотентность достигается с помощью Redis в качестве предварительной обработки и уникального индекса БД в качестве окончательной гарантии.
интервьюер:Сталкивались ли вы там с проблемой последовательного потребления?
Кандидат: ну есть же, приведу пример
Кандидат: Статус заказа, такой как оплата, подтверждение получения, завершение и т. д., а также сообщения о выставлении счетов и возврате средств под заказом.
Кандидат: По идее новость о платеже должна приходить раньше новости о возврате, но это не обязательно в процессе обработки программы.
Кандидат: Так что тут тоже проблема порядка потребления.
Кандидат: Но в рекламном сценарии это не «сильный заказ», если гарантируется окончательная согласованность.
Кандидат: Итак, наша реализация обработки сообщений «не по порядку» выглядит так:
Кандидат: 1. Широкая таблица: разделите каждый статус заказа на одно или несколько независимых полей. Когда приходит сообщение, обновляйте только соответствующие поля.Сообщение будет иметь только краткосрочное несоответствие состояния, но в конечном итоге состояние будет согласованным.
Кандидат: Во-вторых, механизм компенсации сообщения: другое потребляет данные той же темы, сообщение помещается на диск, а обработка задерживается. Сравните сообщение с БД.Если данные не соответствуют друг другу, повторно отправьте сообщение в основной процесс для обработки.
Кандидат: Есть еще несколько сценариев.Может быть, нам нужно только отправить один и тот же userId/orderId в один и тот же раздел (потому что раздел потребляется одним потребителем), и это может решить большую часть проблем с порядком потребления.
интервьюер: Хм... Понял
Добро пожаловать в мой публичный аккаунт WeChat【Java3y] Давайте поговорим об интервью по Java
Серия [Онлайн-интервьюер-Мобильный терминал]Продолжаем обновлять два раза в неделю!
【Онлайн-интервьюер-компьютер】СерияПродолжаем обновлять два раза в неделю!
Оригинал это не просто! ! Проси три! !