ADG Оставить заявку
Блог Данные и аналитика 4 мин чтения

Apache Kafka 3.4: тестируем tiered storage с S3 и смотрим, что стало с KRaft без ZooKeeper

Kafka 3.4 открыла tiered storage в early access и продвинула KRaft ближе к production. Тестируем S3-бэкенд для долгосрочного хранения и считаем, где это реально выгодно.

Контекст момента

Apache Kafka 3.4 - tiered storage early access и стабилизация KRaft без ZooKeeper

Apache Kafka 3.4 вышла в феврале, но мы добрались до неё только сейчас - после того как закончили апгрейд ClickHouse-кластера и освободили стенд. Два главных изменения в релизе, которые нас интересовали: tiered storage как early access-фича и очередной шаг KRaft в сторону «настоящего» production-режима. Оба посмотрели вживую, впечатления - ниже.

KRaft: что это и где мы сейчас

Для тех, кто не следил: KRaft - это встроенный в Kafka консенсусный протокол на базе Raft, который позволяет убрать из схемы ZooKeeper. Kafka 3.3 сделала KRaft «production-ready» для новых кластеров. 3.4 идёт дальше: появилась поддержка делегированного ACL-контроля в KRaft-режиме и закрыт ряд известных проблем с метаданными при перебалансировке партиций.

Мы держим ZooKeeper-кластер, который обслуживает несколько сервисов, Kafka в том числе. Переходить прямо сейчас - не планируем: инструмент миграции существующих кластеров (kafka-storage.sh) ещё не достиг того уровня зрелости, чтобы мы доверили ему продакшн без основательной подготовки. Но тестовый KRaft-кластер мы развернули параллельно и гоняли на нём нагрузку последние несколько недель.

Субъективное ощущение: операции с метаданными заметно быстрее. Там, где раньше создание топика с 32 партициями занимало несколько секунд (включая синхронизацию с ZooKeeper), на KRaft-кластере это почти мгновенно. Насколько это критично для большинства - вопрос. Но для автоматизации, где топики создаются динамически, разница чувствуется.

Мониторинг метаданных в KRaft теперь через kafka-metadata-quorum.sh - команда понятная, хотя к отсутствию привычного zk-shell поначалу нужно привыкнуть.

Tiered storage: идея и что за ней стоит

Tiered storage - это механизм, при котором старые сегменты лога автоматически выгружаются в «холодное» хранилище (S3, GCS, Azure Blob), а брокеры держат у себя только свежие данные. Kafka при этом продолжает отдавать данные из холодного хранилища консьюмерам прозрачно - без изменений на стороне приложений.

Зачем это нужно? Типичный сценарий - долгосрочное хранение событий. Если нужно держать топик 90 дней, но читают активно только последние 7, то 83 дня данных просто лежат на дорогих NVMe-дисках брокеров. Tiered storage позволяет вынести «холодный хвост» на S3 и сократить требования к локальным дискам.

В нашем случае один из топиков - это поток событий платформы с retention 60 дней. Объём - несколько сотен гигабайт в неделю. Прикинули: если оставить на брокерах только 7 дней, а остальное переложить в S3, экономия на дисковом пространстве в нашем сценарии оказалась около 60%. Это не гарантированный результат для любого случая - зависит от соотношения горячих/холодных данных и ценообразования на хранилище.

Как настраивали и что сломалось

Tiered storage в 3.4 - это early access, что означает: включается только явно, стабильность не гарантирована для production, API могут поменяться. Мы настраивали на стенде, не в prod.

Конфигурация брокера минимальная:

remote.log.storage.system.enable=true
remote.log.manager.task.interval.ms=30000

Плагин для S3 - отдельная история. Официального плагина от Apache в комплекте нет: нужно либо писать реализацию RemoteStorageManager самому, либо брать готовую от вендоров (Confluent, Aiven). Мы взяли опенсорсный вариант от сообщества - он работает, но документация фрагментарная. Несколько часов ушло на то, чтобы понять, почему сегменты не уходят в S3: оказалось, что параметр remote.log.metadata.manager.impl.prefix надо указывать явно, иначе метаданные пишутся в системный топик с дефолтным именем, который конфликтует с нашим именованием.

После того как всё заработало, поведение выглядит разумно:

  • Выгрузка сегментов происходит с задержкой - не мгновенно после закрытия. Задержка управляется через remote.log.manager.task.interval.ms.
  • Чтение холодных данных заметно медленнее, чем локальных. В нашем случае - примерно в 5-8 раз по латентности. Для batch-консьюмеров это некритично, для latency-sensitive - нужно учитывать.
  • Восстановление после сбоя брокера работает корректно: новый брокер подтягивает метаданные и начинает отдавать как локальные, так и удалённые сегменты.

Что это даёт в контексте DWH

В рамках DWH и BI-сопровождения Kafka у нас выступает транспортом между источниками событий и аналитическим слоем. Исторические данные из Kafka нужны периодически - для переобучения моделей, ретроспективного анализа или debug-а. Именно для этого и нужен длинный retention.

Tiered storage в этом сценарии потенциально снимает выбор между «держать дорогой диск» и «срезать retention». Оба компромисса неприятны. S3-бэкенд с retention 90+ дней при разумной стоимости хранилища - это третий вариант, который до 3.4 требовал отдельной инфраструктуры (Kafka + внешний архив + логика repopulation).

При этом честно: early access означает, что в production мы это не несём. Следим за тем, как стабилизируется API и появится ли нормальный официальный S3-плагин.

Итог

KRaft движется в нужном направлении - ZooKeeper явно уходит на пенсию, но в нашем случае торопиться некуда. Tiered storage - реально полезная идея, которая пока требует аккуратного обращения и собственного плагина. На стенде всё работает, на prod - ждём GA.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.