KRaft и почему Kafka быстрая
Урок про внутренности: как Kafka управляет метаданными без ZooKeeper и за счёт чего достигает экстремальной пропускной способности.
KRaft — режим, в котором Kafka хранит метаданные кластера в собственном внутреннем логе на основе протокола Raft, без внешнего ZooKeeper. Zero-copy — приём, при котором данные идут с диска в сеть, минуя лишние копирования в памяти.
Зачем нужен KRaft
Исторически Kafka хранила метаданные (топики, партиции, ISR, лидеров) в отдельном ZooKeeper. Это вторая система: её надо ставить, мониторить, обновлять, и она ограничивала масштаб (число партиций). KRaft убирает ZooKeeper: метаданные становятся обычным логом Kafka, которым управляет встроенный контроллер по протоколу Raft. Меньше движущихся частей, быстрее восстановление, выше потолок числа партиций.
Раньше: [ Kafka брокеры ] ----> [ ZooKeeper ] (метаданные)
KRaft: [ Kafka брокеры + контроллеры ]
метаданные -- внутренний лог по Raft, отдельной системы нет
Почему Kafka быстрая: три причины
| Приём | Что даёт |
| Последовательная запись в лог | линейный доступ к диску — на порядок быстрее случайного |
| Page cache ОС | горячие данные читаются из памяти, Kafka не дублирует кэш |
| Zero-copy (sendfile) | данные из файла в сокет минуя пользовательскую память |
Последовательная запись
Kafka только дописывает в конец сегмента — это последовательная запись, которую и HDD, и SSD, и ОС обрабатывают максимально эффективно (упреждающее чтение, отложенная запись). Никаких случайных обновлений «в середину» — отсюда сотни мегабайт в секунду на брокер.
Page cache и zero-copy
Kafka не строит свой кэш в JVM-куче, а полагается на page cache операционной системы: свежезаписанные данные и так лежат в памяти, и консьюмеры, читающие «хвост» лога, берут их из RAM, не трогая диск. А zero-copy (системный вызов sendfile) отдаёт данные из файла прямо в сетевой сокет, минуя копирование в пользовательское пространство приложения.
Обычная отдача: диск -> page cache -> буфер приложения -> сокет (3 копии) Zero-copy: диск -> page cache --------------------o сокет (без копии в приложение)
Как работает под капотом
Связка приёмов взаимоусиливается. Поскольку Kafka не парсит содержимое сообщений при отдаче (она оперирует байтовыми диапазонами лога), её можно передавать через sendfile без участия приложения — ядро само перекидывает байты из page cache в сетевую карту. Последовательная запись держит данные компактными и «тёплыми» в page cache, а батчинг и сжатие на стороне продюсера снижают и объём, и число операций. Именно отсутствие лишней работы (не индексируем содержимое, не копируем зря, не правим на месте), а не хитрые алгоритмы, делает Kafka быстрой.
Частые ошибки
- Давать Kafka гигантскую JVM-кучу «для кэша». Кэширует ОС через page cache; раздутая куча лишь вредит сборщику мусора.
- Считать ZooKeeper обязательным. Современные кластеры работают в KRaft без него.
- Ломать zero-copy шифрованием на брокере без нужды. TLS-терминация на брокере мешает sendfile; учитывайте это под высокой нагрузкой.
Итоги
- KRaft убирает ZooKeeper: метаданные — внутренний лог по Raft, меньше частей и выше потолок партиций.
- Скорость Kafka — это последовательная запись, опора на page cache ОС и zero-copy отдача.
- Главный секрет — отсутствие лишней работы: не индексировать, не копировать, не править на месте.