9. Отказоустойчивость и DR
В этой теме — как Kafka ведёт себя при отказах и как производственно тренировать recovery-процедуры.
Сценарии:
- broker down,
- network partition,
- disk full,
- и связанные эффекты: leader election, ISR, rebalance у consumer group’ов.
Инструменты: MirrorMaker 2 (межкластерная репликация для DR).
Термины и сущности
| Термин | Определение |
|---|---|
| Leader | Узел, который обслуживает запись/чтение для конкретной части данных. |
| ISR (in-sync replicas) | Реплики, которые синхронизированы с leader’ом и считаются “безопасными” для продолжения записи. |
| Rebalance | Перераспределение разделов данных между членами consumer group’а при изменениях членства или недоступности частей кластера. |
| Unclean leader election | Режим, при котором могут быть выбраны не-синхронизированные реплики (повышает доступность, но может ухудшить консистентность). |
| DR (Disaster Recovery) | Восстановление сервиса после крупной аварии с RTO/RPO, обычно с межкластерной репликацией. |
Сценарии отказов: что ожидать и что проверять
1) Broker down
Что происходит:
- leader может переизбраться на доступную реплику,
- запись продолжится, если ISR и
min.insync.replicasпозволяют, - consumer group’ы сделают rebalance и продолжат чтение с последнего committed прогресса (или с сохранённых offset’ов).
Production best practices:
- заранее закладывайте число broker’ов и replication factor под отказ “n узлов”,
- для критичных потоков используйте
acks=allна producer’е и корректныйmin.insync.replicas, - не включайте “нечистую” переизбрание leader’ов без бизнес-обоснования.
Симуляция: остановить один broker (Kubernetes)
# 1) Найдите broker под’ы
kubectl -n kafka get pods -l strimzi.io/name=my-cluster-kafka -o name
# 2) Удалите (эмулируем падение)
kubectl -n kafka delete pod <broker-pod-name>
# 3) Наблюдайте: новые leaders/ISR и rebalance
kubectl -n kafka describe pod <consumer-pod-name>
Комментарий:
- в production вы обычно “убиваете” через контролируемые операции (cordon/drain), но для практики полезно воспроизвести отказ именно как потерю pod’а.
2) Network partition
Что происходит:
- часть broker’ов станет недоступной по сети,
- ISR может “усыхать” (репликации не синхронизируются),
- возможны ошибки producer’ов (timeouts/retries) и рост задержек у consumer’ов.
Production best practices:
- планируйте failure domains (rack/zone) и используйте rack awareness,
- настраивайте timeouts/retries так, чтобы recovery занимал предсказуемое время,
- учитывайте, что partition может быть “частичным” (не равномерным).
Симуляция: временно заблокировать доступ к порту broker’а
# Пример (идея): блокируем исходящие TCP на 9092 с pod’а consumer’а.
# Реальные команды зависят от вашего базового образа и наличия iptables.
kubectl -n kafka exec -it <consumer-pod-name> -- sh -c \
"iptables -A OUTPUT -p tcp --dport 9092 -j DROP"
# Через N минут снимите правило
kubectl -n kafka exec -it <consumer-pod-name> -- sh -c \
"iptables -D OUTPUT -p tcp --dport 9092 -j DROP"
3) Disk full
Что происходит:
- broker начинает ограничивать операции из‑за заполнения,
- grow latency и error rate,
- retention cleanup может отставать (особенно при compaction/cleaner нагрузке).
Production best practices:
- мониторьте disk usage и задавайте thresholds для раннего вмешательства,
- планируйте рост storage как часть capacity planning,
- тренируйте реакцию: увеличить объем, перестроить storage, проверить cleaner throughput.
Симуляция: заполнить тестовый mount (dev/prod-drill)
# Заполнить файл до лимита на mounted volume (примерная идея)
kubectl -n kafka exec -it <broker-pod-name> -- sh -c \
"dd if=/dev/zero of=/var/lib/kafka/fill-test bs=1M status=progress"
Комментарий:
- выполняйте только на staging или в controlled drill, иначе можно сломать cluster-wide SLO.
Leader election: как проверять recovery
Ключевая мысль: leader переизбирается автоматически, но ваша задача — убедиться, что:
- потребители продолжили читать,
- запись продолжается без длительных ошибок,
- ISR восстановился до ожидаемого состояния (если политика требует).
Практика проверки:
# Быстро оценить consumer progress
kafka-consumer-groups.sh \
--bootstrap-server <bootstrap> \
--describe \
--group <group-name>
Рекомендации:
- сравнивайте до/после recovery метрики latency/error/lag,
- фиксируйте “как долго заняло восстановление” для RTO.
DR между кластерами: MirrorMaker 2 (инструмент)
MirrorMaker 2 нужен, когда вы хотите:
- реплицировать данные между кластерами в разных failure domains (например, разные дата-центры),
- пережить крупную аварию: кластер A недоступен, но кластер B продолжает обслуживать потребителей.
Production best practices:
- определите RPO: как много данных можно потерять по факту недоставки,
- определите routing потребителей при DR (какой consumer group переключается на второй кластер),
- заранее протестируйте switch и проверьте совместимость схем/семантики.
Примечание по коду:
- конкретная настройка MirrorMaker 2 обычно включает фильтрацию потоков/групп; поля зависят от выбранного формата и конфигурационного файла вашего кластера.
План drill: “сломать и восстановить” (шаблон)
1) Определите SLA восстановления: например, broker down за <N минут, network partition за <M минут. 2) Выполните сценарий (подвес, блок сети, заполнение диска в staging). 3) Соберите признаки: - ошибки producer’ов, - рост задержек, - изменение прогресса consumer group’ов, - восстановление доступности записи/чтения. 4) Зафиксируйте результат и внесите изменения в: - timeouts/retries, - replication/ISR параметры, - capacity (storage/IO).
Небольшая проверка прогресса:
kafka-consumer-groups.sh \
--bootstrap-server <bootstrap> \
--describe \
--group <group-name>
Production checklist
| Что проверить | Зачем |
|---|---|
| replication/ISR политики под ожидаемые отказа | запись продолжалась без потери SLO |
| producer retry/timeout поведение при недоступности | меньше “тишины” и падений |
| disk usage алерты и runbook | чтобы заполнение не стало “сюрпризом” |
| drill сценарии раз в период | recovery становится предсказуемым |
| межкластерный plan для DR и тест switch | чтобы RTO/RPO реально достигались |