3 проблемы администрирования Apache Kafka и пути их решения на практических примерах

Big Data, Большие данные, обработка данных, Kafka, администрирование, архитектура

Администрирование кластера Kafka порой напоминает работу детектива, когда нужно понять мотив преступления причину появления того или иного бага и устранить ее вместе с последствиями наиболее оптимальным способом. В этой статье мы рассмотрим несколько практических примеров конфигурирования Apache Kafka из опыта компании Booking.com, кейс которой был представлен в докладе ее сотрудника Александром Мироновым 23 января 2020 года на зимнем Kafka-митапе Avito.Tech.

Называйте файлы по-разному или как корректно обновить SSLContext без перезапуска брокера Kafka

Истоки рассматриваемой проблемы лежат в механике самообслуживаемой (self-service) mTLS-аутентификации Kafka, которая реализована в Booking.com следующим образом [1]:

  • на брокере Kafka запускается проверка наличия SSL-сертификата и его валидности (TTL, Time To Live) в течение следующих 5 дней;
  • если TTL обнаруженного сертификата более 5 дней, никакие дополнительные действия не производятся;
  • иначе (TTL < 5 дней), то на стороне сервера необходимо выпустить новый сертификат и запустить конфигурационный скрипт kafka-configs.sh, чтобы динамически обновить внутренний резидентный (in-memory) SSLContext. Это позволит не перезапускать брокер каждый раз при перевыпуске сертификата.

Первый раз вся последовательность действий выполнилась успешно, однако потом начали возникать ошибки. Одна из них связана с тем, что SSLContext не обновлялся, если файл с новыми SSL-ключами имел то же самое имя. В официальной документации эта проблема называется KAFKA-8190 и сопровождается следующим описанием [2]:

  • хранилище ключей и доверенных сертификатов SSL перезагружается при динамическом обновлении конфигурации на брокере, если одна из конфигураций изменилась или изменилось время модификации файла;
  • для обновления без изменения конфигурации сравнивается время модификации при последней загрузке с текущим временем модификации файла;
  • если время модификации файла для проверки динамических конфигураций совпадает со временем его последней загрузки, обновление SSLContext’а не выполняется.

Это происходило потому, что сохранялось время модификации файла-хранилища ключей (keystore) при его загрузке в экземпляр SecurityStore. При динамическом обновлении keystore без изменения имени файла сравнивалось время последней загрузки с временем изменения текущего файла. Для проверки динамических конфигураций хранилище ключей просто загружалось без воссоздания SSLContext’а при выполнении фактической реконфигурации после проверки. Новый экземпляр SecurityStore для перенастройки хранилища создавался всегда, поэтому требовалось только сохранить время модификации файла, с которым и выполнялось сравнение. Данный баг был исправлен в апреле 2019 года для версий Apache Kafka
2.3.0, 2.1.2 и 2.2.1 [2]. Поэтому команда Big Data администраторов компании Booking.com обновила платформу до версии 2.3.1. Это помогло решить вышеописанную проблему, но далее возникли новые [1].

Гонки состояний или проблемы многопоточности в Кафка

Причиной одной из новых проблем стала ошибка проектирования многопоточной системы, при которой ее работа зависит от того, в каком порядке выполняются части кода. Такой тип ошибок называется «неопределённость параллелизма» или состояние гонки (Race condition), когда из-за неконтролируемого доступа к общей памяти ошибки могут проявляться в непредсказуемые моменты времени, а попытка их повторения в целях отладки со схожими условиями работы оказываются безуспешными [3]. В случае Booking.com эта проблема проявилась в виде бага, получившего название KAFKA-9156, когда в случайные моменты времени начали удаляться потоки получения реплик при продолжении работы брокеров. В результате этого становились недоступны отдельные разделы (partitions) топиков Кафка [1].

Причина данного бага связана с тем, что в версии 2.3.0 было сделано улучшение механизма загрузки индексов в память брокеров по принципу ленивых или отложенных вычислений (lazy-loaded), которые выполняются только в момент требования. При этом возникло состояние гонки в методах get для LazyTimeIndex и LazyOffsetIndex, которое приводило к одновременному созданию нескольких объектов OffsetIndex/TimeIndex. При этом позиция MappedByteBuffer в AbstractIndex перемещалась до последней записи, что, в свою очередь, приводило к возникновению критического исключения BufferOverflowException, когда лидер или реплика пытается добавить запись в сегмент. В официальной документации также отмечается, что указатель `file_ =` также подвержен этой уязвимости, поскольку несколько потоков могут одновременно пытаться установить новую ссылку на файл и создать новые объекты Time / OffsetIndex. Это приводит к несоответствующим ссылкам на файлы, хранимые в LazyTimeIndex и TimeIndex. Данный баг был исправлен 2 декабря 2029 года в версиях Apache Kafka 2.4.0 и 2.3.2 [4].

Наконец, Big Data администраторы компании Booking.com столкнулись с проблемой остановки потока очистки журнала (Log Cleaner thread) без четкой ссылки на лог, который его вызывает. Эта ошибка получила название KAFKA-9133, суть которой состоит в том, что в случайные моменты времени некоторые разделы переставали очищаться из-за того, что смещение записей, которые нужно удалить, превышало базовое смещение активных сегментов. Эта проблема была решена 9 ноября 2019 года для версий Apache Kafka 2.4.0 и 2.3.2 [5].

В заключение отметим практический совет от администраторов Apache Kafka из Booking.com. С учетом активного развития Кафка и open-source статуса этой Big Data технологии, в ней достаточно много багов. Поэтому регулярное обновление платформы – залог избавления от этих проблем. Однако, следует подумать дважды или даже трижды, прежде чем обновить версию протоколов общения между брокерами (inter-broker protocol) и работы с сообщениями (message protocol), поскольку откат назад не всегда возможен [1]. В следующей статье мы продолжим разговор про Apache Kafka и рассмотрим, как и зачем совмещать эту Big Data систему с популярным ETL-инструментом для маршрутизации потоков данных — Apache NiFi. Про корпоративный self-service интеграции данных на Kafka в компании Авито читайте здесь.

А технические детали решения этих и других проблем с администрированием кластера Apache Kafka для потоковой обработки больших данных в проектах цифровизации своего бизнеса, а также государственных и муниципальных предприятий, вы узнаете на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

 

Источники

  1. https://habr.com/ru/company/avito/blog/486278/
  2. https://issues.apache.org/jira/browse/KAFKA-8190
  3. https://ru.wikipedia.org/wiki/Состояние_гонки
  4. https://issues.apache.org/jira/browse/KAFKA-9156
  5. https://issues.apache.org/jira/browse/KAFKA-9133