Как Kafka обеспечивает сохранность данных при отказе брокера?

Ответ

Kafka использует несколько взаимосвязанных механизмов для обеспечения отказоустойчивости и сохранности данных (durability):

  1. Репликация партиций. Каждая партиция топика копируется на несколько брокеров. Этот replication-factor (обычно 3) определяет, сколько копий данных существует в кластере. Одна реплика является лидером (принимает запись), остальные — фолловерами (копируют данные с лидера).

  2. In-Sync Replicas (ISR). Это список реплик (включая лидера), которые не сильно отстали от лидера. Только реплики из списка ISR могут быть выбраны новым лидером в случае отказа текущего. Это гарантирует, что новый лидер будет иметь актуальные данные.

  3. Настройка подтверждений (acks). Продюсер при отправке сообщения может указать, какого уровня подтверждения он ожидает:

    • acks=0: Не ждать подтверждения. Максимальная производительность, но есть риск потери данных.
    • acks=1: Ждать подтверждения только от лидера. Хороший баланс, но данные могут быть потеряны, если лидер упадет сразу после отправки подтверждения, но до того, как фолловеры скопируют данные.
    • acks=all: Ждать подтверждения от всех реплик из списка ISR. Максимальная надежность, но самая низкая производительность.
  4. Конфигурация min.insync.replicas. Этот параметр на стороне брокера задает минимальное количество реплик в ISR, которые должны подтвердить запись, чтобы она считалась успешной (при acks=all). Если синхронизированных реплик меньше, продюсер получит ошибку. Это защита от записи в кластер с недостаточной репликацией.

Пример конфигурации продюсера для максимальной надежности:

from kafka import KafkaProducer

producer = KafkaProducer(
    bootstrap_servers='kafka1:9092,kafka2:9092',
    # Ждём подтверждения от всех реплик в ISR
    acks='all',
    # Повторяем отправку в случае временных ошибок сети
    retries=5
)

Ключевая настройка на стороне брокера для предотвращения потери данных — unclean.leader.election.enable = false, которая запрещает выбирать лидером реплику, не входящую в ISR.

Ответ 18+ 🔞

Слушай, а вот этот ваш Кафка, он там не просто так на кофеине сидит, он реально продумал, как данные не растерять, если вдруг какой брокер решит накрыться медным тазом. Сейчас разжую, как бабушка семечки.

Представь, у тебя есть топик — это типа папка. А в ней партиции — такие шустрые блокноты, куда всё пишется. Так вот, чтобы не случилось пиздеца, каждый такой блокнот ксероксят на несколько других брокеров. Это называется репликация. Циферка replication-factor=3 — это святое, значит, будет один оригинальный блокнот (лидер) и две его ксерокопии (фолловеры). Лидер принимает все записи, а фолловеры тупо с него списывают, как двоечники.

Но не все фолловеры одинаково полезны. Есть список In-Sync Replicas (ISR) — это элитный клуб реплик, которые не отстали от лидера на овердохуище записей. Только член этого клуба может стать новым лидером, если старого вдруг грохнет. Иначе выйдет хуйня: новый лидер окажется с данными позавчерашнего дня.

А теперь самое сочное — настройка acks для продюсера. Это уровень его паранойи:

  • acks=0 — «отправил и похуй». Лети, моя запись, в никуда! Производительность — огонь, но если брокер ляжет в этот же миг, данные испарятся. Надежность — ноль ебать.
  • acks=1 — «подтверди, что ты лидер и принял». Ждём кивка только от лидера. Быстро, но если лидер, получив данные, тут же сдохнет, не успев скопировать их фолловерам — всё, пиши пропало. Волнение ебать.
  • acks=all — «подтвердите, пацаны, все, кто в теме!». Ждём одобрительных кивков от ВСЕХ реплик в том самом элитном клубе ISR. Максимальная надёжность, но скорость падает, потому что ждать приходится дольше всех.

Но и это ещё не всё! Чтобы продюсер совсем уж не расслаблялся, есть параметр брокера min.insync.replicas. Допустим, он равен 2. Это значит, что если в синхронизированном клубе ISR осталось меньше двух членов (например, один лидер и всё), то при acks=all продюсеру прилетит ошибка. Мол, «чувак, пиши некуда, тут бардак, реплик не хватает». Защита от записи в одинокий, обречённый блокнот.

И вишенка на торте — unclean.leader.election.enable = false. Это священное правило, которое запрещает выбирать лидером какую-нибудь левую реплику, которая валялась в пыли и не была в ISR. Иначе выйдет, что мы выберем царём того, у кого половины данных нет — вот это будет пиздопроебищно.

Вот так, собственно, и живут данные в Кафке. Не просто так, а с гарантиями. Если, конечно, не косячить с настройками.

from kafka import KafkaProducer

producer = KafkaProducer(
    bootstrap_servers='kafka1:9092,kafka2:9092',
    # Ждём подтверждения от всех реплик в ISR
    acks='all',
    # Повторяем отправку в случае временных ошибок сети
    retries=5
)