Благодаря высокой пропускной способности, масштабируемости и отказоустойчивости Apache Kafka — ведущее решение для создания конвейеров данных в реальном времени и потоковых приложений. Чтобы использовать весь его потенциал, старшим инженерам-программистам важно разбираться в продвинутом функционале Kafka: разбиении на разделы, масштабировании, избыточности данных, гарантиях доставки, управлении смещениями, контроллере Kafka, эволюции схем и т. д. Изучим все это в исчерпывающем руководстве по освоению Kafka.
1. Разбиение на разделы в темах Kafka
Что такое «разделы»?
Темы Kafka разделяются на разделы — фундаментальные единицы масштабируемости и параллелизма. Каждый раздел — это упорядоченная, неизменяемая последовательность записей с возможностью их добавления.
Разбиение на разделы. Для чего?
Благодаря разбиению на разделы в Kafka обрабатываются большие объемы данных, а нагрузка распределяется между серверами, или брокерами. Так упрощается горизонтальное масштабирование, можно работать с большим количеством отправителей и получателей одновременно.
Взаимодействие отправителя и раздела
Указание ключа сообщения: при отправке сообщения в тему отправителями указывается ключ, которым определяется раздел, куда отправится сообщение. Поэтому сообщения с одним и тем же ключом всегда отправляются в один раздел, чем сохраняется порядок следования этого ключа.
Циклическое распределение: если ключ не указан, сообщения в Kafka распределяются по разделам циклически и с равномерной балансировкой нагрузки между ними.
Взаимодействие получателя или группы получателей и раздела
Группы получателей: сообщения из темы получаются ими совместно. Каждый раздел в теме одномоментно потребляется только одним получателем из этой группы, поэтому дублированная обработка исключена.
Балансировка нагрузки: разделы между получателями в группе балансируются автоматически. Если к группе присоединяется новый получатель, нагрузка в Kafka перераспределяется и новому получателю присваиваются разделы. Так обеспечиваются эффективное расходование ресурсов и масштабируемость.
2. Проблемы динамического масштабирования разделов
Динамическое масштабирование разделов
Добавление новых разделов чревато проблемами. И вот почему.
Перебалансировка: при добавлении новых разделов имеющиеся группы получателей в Kafka перебалансируются. Пока получатели заново присваиваются разделам, возникает кратковременный период недоступности. Как итог — временные задержки в обработке сообщений.
Перераспределение данных: данных в новых разделах может не быть, а значит, переприсвоенные получатели до поступления новых данных недоиспользуются. При некорректном управлении баланс нагрузки нарушается.
Почему это происходит?
Каждому получателю в группе достается справедливая доля нагрузки благодаря протоколу кооперативной перебалансировки. Однако в Kafka при добавлении или удалении разделов изменения «доводятся до сведения» всех получателей, которыми соответственно перераспределяется работа. Этот процесс, хотя и эффективен, сопряжен с задержкой.
3. Избыточность данных и репликация разделов
Механизм репликации Kafka
Чтобы обеспечить высокую доступность и отказоустойчивость, в Kafka реплицируется каждый раздел многочисленных брокеров. Для такой репликации задается коэффициентом репликации, которым определяется количество копий каждого раздела.
Лидер и последователи: в разделе одна реплика — лидер, ею обрабатываются все считывания и записи. Другие реплики — последователи, ими данные реплицируются из лидера. Если случается сбой лидера, лидером становится один из последователей.
Важность репликации: при сбое брокера данные не теряются. Благодаря многочисленным копиям данных в Kafka выдерживаются сбои брокера, сохраняется доступность данных.
Репликация в действии
Синхронная репликация: последователями данные реплицируются из лидера синхронно: копируются, как только записываются им.
Набор синхронизированных реплик: это все реплики, актуализированные с лидером. Отстающая реплика удаляется из набора синхронизированных и не становится лидером, пока отставание не ликвидируется.
4. Гарантии доставки: минимум одна, максимум одна, ровно одна
Гарантии доставки
Для управления процессом обработки данных в Kafka предоставляется три уровня гарантий доставки.
Максимум одна: сообщения доставляются однажды или не доставляются вообще. Повторов нет, при сбое сообщения теряются. Хорош для сценариев, где потери допустимы.
Минимум одна: сообщения повторяются до подтверждения, поэтому не теряются. Однако это чревато дублями, если сообщение подтверждено, но до обработки случается сбой получателя.
Ровно одна: каждое сообщение доставляется ровно один раз, даже в случае повторов. Этот уровень самый надежный, но и сложный для реализации.
Настройка отправителей и получателей для гарантий доставки
Конфигурации отправителей
acks=0
: отправителем не ожидается подтверждения, максимум одна.acks=1
: отправителем ожидается подтверждение от лидера, минимум одна.acks=all
: отправителем ожидается подтверждение от всех синхронизированных реплик, минимум одна или ровно одна с идемпотентностью.- Идемпотентность: с включенной идемпотентностью каждое сообщение доставляется в тему лишь однажды, дубли предотвращаются.
Конфигурации получателей
Работа с дублями, семантика минимум одной доставки: для семантики минимум одной доставки получателями учитывается возможность неоднократной обработки одного и того же сообщения. Это случается, если сообщение обработано, но до фиксации смещения происходит сбой получателя. Получателями для исключения дублей реализуется идемпотентная логика обработки: даже если сообщение обрабатывается многократно, результат остается неизменным. Сюда относится проверка по уникальному идентификатору сообщения или транзакции, не выполнена ли уже операция.
Ровно одна с явным управлением смещениями и isolation.level=read_committed
: для достижения семантики ровно одной доставки получателями.
- Отключается автофиксация: автофиксация смещений в Kafka предотвращается заданием
enable.auto.commit=false
. Получателем контролируется фиксация смещений, они фиксируются только после обработки сообщений. - Явно фиксируются смещения: ручными фиксациями смещений, например
commitSync()
илиcommitAsync()
, после обработки каждого сообщения или пакета сообщений. Так смещения фиксируются только после завершения обработки, в случае сбоев повторная обработка предотвращается. - Используется
isolation.level=read_committed
: в конфигурации получателя задаетсяisolation.level=read_committed
. Этим параметром обеспечивается считывание получателями только зафиксированных сообщений как части успешной транзакции. И это важно для семантики ровно одной доставки, поскольку предотвращается считывание получателем незафиксированных или прерванных транзакций, которое чревато несоответствиями обработки.
5. Управление смещениями и согласованная обработка сообщений
Управление смещениями
Позиция последнего полученного сообщения в каждом разделе Kafka отслеживается по смещениям, которыми определяется, где получателям возобновиться после остановки в случае сбоя.
Как управляются смещения
Смещения фиксируются получателями после обработки сообщений и сохраняются в специальном разделе Kafka __consumer_offsets
или во внешней системе.
Автоматическое управление смещениями против ручного: в Kafka поддерживается автоматические и ручные фиксации смещений. Первые чреваты потерей данных при сбое получателя, вторыми обеспечивается больше контроля, но нужно внимательно обращаться с ними во избежание дублей.
Важность управления смещениями
Согласованность: при корректном управлении смещениями одно и то же сообщение не обрабатывается получателями многократно, это важно для обеспечения согласованности обработки.
Отказоустойчивость: благодаря фиксации смещений только после обработки сообщений, в Kafka даже при сбое получатель возобновляется с последнего зафиксированного смещения без повторной обработки сообщений.
6. Контроллер Kafka. Zookeeper и его роль
Контроллер Kafka
Контроллер — это брокер, которым управляется состояние кластера Kafka, выбираются лидеры разделов, присваиваются реплики, обеспечивается согласованность метаданных всех брокеров, координируются изменения лидеров.
Zookeeper и его роль
Zookeeper — это внешняя служба для координирования Kafka. Ею управляются метаданные о брокерах, темах, разделах и выборе контроллера.
Почему Zookeeper?
Координирование и управление: в Zookeeper имеется согласованное, отказоустойчивое хранилище состояний для метаданных Kafka. С ним проще управлять сбоями брокеров, выбирать лидеров, присваивать разделы.
Выборы лидеров: с помощью Zookeeper в Kafka выбирается контроллер, которым затем выбираются лидеры разделов.
Переход на KRaft, то есть Kafka Raft
В Kafka отказываются от Zookeeper, переходя на KRaft, встроенный протокол консенсуса для управления метаданными.
Почему именно KRaft? Им упрощается архитектура Kafka, повышается масштабируемость, уменьшается сложность операций — метаданные управляются прямо в Kafka.
7. Управление схемой данных, эволюция схем
Реестр схем и поддерживаемые форматы
Реестр схем не ограничивается Avro, им управляются схемы и для других форматов сериализации: буферы протокола Protobuf и JSON-схема. С реестром схем обеспечиваются согласованное управление схемами и их проверка в этих форматах, так что отправителями и получателями соблюдается общее определение схемы.
Обратная совместимость
Обратной совместимостью обеспечивается то, что новые данные — выдаваемые новой схемой — получаются старыми получателями, предназначенными для работы со старой схемой. Так по мере развития схем поддерживается совместимость, предотвращаются простои.
Совместимости схем
Обратная: данные, записанные старыми схемами, считываются новыми. При развитии отправителей имеющиеся получатели не ломаются.
Прямая: данные, записанные новыми схемами, считываются старыми. Поэтому получатели обновляются раньше отправителей.
Полная: это обратная и прямая совместимость, отправители и получатели развиваются независимо друг от друга, не ломаясь.
Изменения схем
Добавление поля:
Поскольку добавляется со значением по умолчанию, поле обратно совместимо, имеющимися получателями оно игнорируется, а значение по умолчанию используется при необходимости.
Пример: добавление поля country
со значением по умолчанию USA
. Имеющиеся получатели, которыми это поле не распознается, не сломаются: ими по умолчанию используется.
При добавлении поля без значения по умолчанию имеющиеся получатели ломаются, если не обновятся для работы с новым полем. Если получателем ожидается конкретная схема и получается сообщение, в котором полей больше ожидаемого, случается сбой.
Удаление поля:
Удаление необязательного поля, не используемого имеющимися получателями, обычно обратно совместимо. Эти получатели продолжают корректно функционировать.
Удаление обязательного поля — от него получатели не зависят — обратно совместимым не является. Это чревато сбоями имеющихся получателей из-за неполучения ожидаемых данных.
Обработка сообщений на лету при изменениях схемы
Эволюция схем в реальном времени:
Реестром схем обеспечивается соблюдение правил совместимости: при регистрации новой схемы проверяется, совместима ли она с предыдущей версией. Так предотвращаются изменения, из-за которых ломаются имеющиеся получатели. Эти проверки применимы ко всем поддерживаемым форматам: Avro, Protobuf, JSON-схеме.
Адаптация на лету: при обновлении схемы передаваемые сообщения — отправленные, но еще не полученные — должны соответствовать правилам совместимости. Например, если добавить поле со значением по умолчанию, новая схема обработается получателями легко и без сбоев.
Рассматриваемые сценарии
Добавление поля со значением по умолчанию: корректное функционирование получателей, которыми применяется старая схема, продолжится — новое поле ими игнорируется. Это справедливо для Avro, Protobuf и JSON при использовании реестра схем, пока в новом поле имеется значение по умолчанию.
Добавление поля без значения по умолчанию: прежде чем отправителями начнется применение новой схемы, получателям необходимо обновиться для работы с новым полем. Иначе сообщения отклоняются или случаются ошибки обработки. В Avro, Protobuf и JSON-схеме в этом сценарии требуется тщательно контролировать, чтобы получатели обновлялись синхронно с изменениями схемы.
Удаление поля: чтобы прекратить использование поля до его удаления, все получатели обновляются. Удаление поля, используемого получателями, чревато ошибками. Это применимо во всех форматах, управляемых реестром схем.
Дополнительные замечания по Avro, Protobuf и JSON-схеме
- Avro:
Отличается компактным двоичным кодированием, надежной поддержкой схем. Реестр схем легко интегрируется с Avro, при этом обеспечиваются надежные проверки схем и совместимости.
- Protobuf:
Активно применяется благодаря своей эффективности и платформонезависимости. При использовании с реестром схем для Protobuf доступен функционал эволюции схем, аналогичный Avro, с обратной и прямой совместимостью.
- JSON-схема:
JSON славится удобным для человеческого восприятия форматом. JSON-схемой с реестром схем обеспечиваются те же преимущества проверки и эволюции схем, причем данными JSON соблюдается определенная структура.
Расширенное применение Kafka
Политики сжатия и хранения сообщений: управление хранилищем и актуальность данных
Политики хранения:
Хранение по времени: в Kafka сообщения хранятся в течение указываемого периода времени, например семь дней, по истечении которого удаляются. Так сохраняется управляемым хранилище, обеспечивается доступность последних данных.
Хранение по размеру: в Kafka хранение осуществляется также по общему размеру сообщений в теме. Когда достигается указываемый размер, удаляются старые сообщения и освобождается место для новых.
Сжатие сообщений:
Что такое «сжатие»?
Сжатие — это процесс сохранения только последнего значения для каждого уникального ключа. В Kafka сообщения не удаляются по продолжительности существования или размеру, сохраняются самые последние обновления и удаляются старые.
Принцип работы сжатия:
Сжатие приходится особенно кстати для сценариев вроде журналов изменений или сохранения информации о текущем состоянии. Например, в разделе, где хранятся обновления пользовательских профилей, сжатием сохраняется только последнее обновление для идентификатора каждого пользователя.
Сжатие выполняется в фоновом режиме, при этом сканируются разделы на наличие ключей с записями, для каждого ключа сохраняется только последняя запись.
Зачем нужно сжатие?
Эффективное управление состоянием: сжатие идеально для тем, в которых актуально только последнее состояние. Благодаря упрощению и актуализации набора данных сокращается потребность в хранении, ускоряется доступ.
Корректность данных: сжатие кстати в сценариях, где необходима перезапись предыдущего состояния, например при отслеживании предпочтений пользователя или сохранении конфигураций.
Kafka Streams для обработки в реальном времени
Введение в Kafka Streams
Kafka Streams — клиентская библиотека для создания приложений и микросервисов, которыми обрабатываются хранящиеся в Kafka данные. С ее помощью обрабатываются и преобразовываются потоки данных в реальном времени.
Основные понятия
Поток: непрерывный поток записей или сообщений из темы Kafka.
KStream и KTable: основные абстракции Kafka Streams. KStream
— это поток записей, а KTable
— поток журнала изменений, где каждая запись является обновлением.
Почему Kafka Streams?
Обработка в реальном времени: в Kafka Streams данные обрабатываются по мере поступления, в реальном времени фильтруются, преобразовываются и агрегируются для респонсивных, умных приложений.
Обработка с сохранением состояния: в Kafka Streams поддерживаются операции с сохранением состояния: оконная обработка, в частности агрегирование данных по временным интервалам, и объединения потоков.
Масштабируемость и отказоустойчивость: приложения Kafka Streams горизонтально масштабируются и автоматически восстанавливаются после сбоев, чем обеспечивается высокая доступность.
Сценарии для Kafka Streams
Мониторинг и оповещения: обнаружение аномалий в системных показателях или журналах транзакций в режиме реального времени.
Обогащение данных: пополнение входящих потоков данных справочными сведениями, например транзакций клиента — данными профиля.
Аналитика и агрегирование: расчет статистических данных реального времени, например скользящих средних или агрегирование данных о продажах.
Безопасность и соответствие требованиям
Функционал безопасности Kafka
Шифрование: в Kafka для защиты передаваемых данных поддерживается шифрование SSL/TLS. Благодаря этому данные, передаваемые между отправителями, получателями и брокерами, нельзя перехватить или скомпрометировать.
Аутентификация: в Kafka поддерживаются механизмы аутентификации на основе SSL и SASL, поэтому доступ в кластер здесь разрешен только авторизованным пользователям и приложениям.
Авторизация и списки контроля доступа: в Kafka списками управления доступом задаются разрешения на чтение, запись или управление темами, обеспечивается детализированный контроль доступа: операции над ресурсами Kafka выполняются только разрешенными клиентами.
Соответствие требованиям
Конфиденциальность данных: для соответствия таким регламентам защиты данных, как GDPR и CCPA, важно обеспечить шифрование конфиденциальных данных и контроль доступа.
Журналирование аудита: в Kafka настраивается регистрация доступа и операций, предоставляется контрольный журнал о том, кто, к каким данным обращался и когда. Так обеспечивается контролируемость, подтверждается соответствие требованиям.
Хранение и удаление данных: для соответствия требованиям данные обычно хранятся определенный период времени, а затем удаляются. Политики хранения Kafka настраиваются под эти требования: данные хранятся, только пока нужны.
Мониторинг и наблюдаемость
Важность мониторинга Kafka
Чтобы эффективно работать в Kafka и справляться с рабочими нагрузками продакшена, необходим мониторинг. Узкие места производительности, сбои брокеров, запаздывания получателей — все это сказывается на производительности приложений и целостности данных.
Инструменты мониторинга Kafka
Prometheus и Grafana: Prometheus — это мощная система мониторинга для извлечения JMX-метрик Kafka. Они отображаются на визуальном дашборде Grafana — мониторить работоспособность и производительность кластера здесь проще.
JMX-метрики Kafka: управленческими расширениями Java Management Extensions предоставляются разнообразные метрики для диагностики проблем и оптимизации производительности: работоспособность брокера, состояние разделов темы, запаздывания получателей и другие.
Kafka Manager и Control Center: этими инструментами пользовательского интерфейса предоставляется информация о темах, брокерах и группах получателей Kafka, при помощи которой визуализируются метрики кластера, контролируются конфигурации тем, отслеживаются запаздывания получателей.
Что мониторится в Kafka
Работоспособность брокеров: проверкой ЦП, расхода памяти и дискового ввода-вывода предотвращается перегруженность брокеров.
Распределение разделов: для равномерной балансировки нагрузки мониторится распределение разделов между брокерами.
Запаздывания получателей: чтобы получатели поспевали за скоростью поступления данных, отслеживаются метрики запаздывания.
Недореплицированные разделы: чтобы выявить потенциальные проблемы репликации и доступности данных, отслеживается количество недореплицированных разделов.
Заключение
Для расширенного применения Kafka нужно разбираться в его основном функционале, особенностях масштабирования, безопасности и надежности. Освоив репликацию, гарантии доставки, разбиение на разделы, управление смещениями, операции контроллера, эволюцию схем и другой продвинутый функционал, старшие инженеры-программисты проектируют надежные решения под задачи современных, управляемых данными приложений. Благодаря этим концепциям Kafka остается производительным, совместимым, отказоустойчивым, незаменимым инструментом обработки и анализа данных в реальном времени.
Читайте также:
- Обработка дублированных сообщений в Kafka
- Оптимизация начальной загрузки сервера с RocksDB
- Плавный переход: миграция кластера Kafka в Kubernetes
Читайте нас в Telegram, VK и Дзен
Перевод статьи Manjula Piyumal: Mastering Kafka: Advanced Concepts Every Senior Software Engineer Should Know