Исправляем OOM-ошибки приложений Apache Kafka Streams через конфигурирование RocksDB

Автор Категория ,
Исправляем OOM-ошибки приложений Apache Kafka Streams через конфигурирование RocksDB

Сегодня заглянем под капот stateful-приложений Kafka Streams и рассмотрим, что такое RocksDB, как устроено это key-value NoSQL-хранилище и почему его необходимо настраивать для быстрой и безотказной работы приложений потоковой аналитики больших данных. Читайте далее, какие проблемы приложений Kafka Streams связаны с RocksDB и как ограничить повышенное потребление оперативной памяти.

Что такое RocksDB и при чем здесь Apache Kafka Streams

Для создания распределенных приложений, которые будут обрабатывать данные, хранящиеся в топиках Apache Kafka, используется специальный компонент этой платформы потоковой передачи событий – клиентская библиотека Kafka Streams. Приложение Kafka Streams может выполнять операции без сохранения состояния (stateless), такие как map и фильтрация, а также операции с отслеживанием состояния (stateful): оконные соединения и агрегаты для входящих записей данных. Для stateful-операций Kafka Streams использует локальные хранилища состояний, отказоустойчивость которых обеспечивается за счет связи с логом изменений, хранящимся в Kafka. В качестве хранилища состояний по умолчанию Kafka Streams использует RocksDB – адаптируемое, встраиваемое и постоянное key-value хранилище [1]. Подробнее о том, как именно Kafka Streams обеспечивает согласованность и полноту потоковых данных, читайте в нашей новой статье.

Apache Kafka для инженеров данных

Код курса
DEVKI
Ближайшая дата курса
25 июля, 2022
Длительность обучения
32 ак.часов
Стоимость обучения
80 000 руб.

Эта высокопроизводительная встраиваемая NoSQL-СУБД была написана разработчиками Facebook в 2012 году на C++ на основе LevelDB от Google. Сначала open-source проект был выпущен под лицензией BSD, а в июле 2017 года перенесен на лицензию Apache 2.0. RocksDB оптимизирована для многоядерных CPU, рабочих нагрузок ввода/вывода (I/O) и эффективного использования быстрой памяти, в частности, твердотельных SSD-накопителей. Надежность и быстрота работы RocksDB обеспечиваются следующими решениями [2]:

  • журнально-структурированное дерева со слиянием (LSM tree);
  • префиксы ключей для сокращения объема считываемых данных;
  • механизм контрольной суммы для блока данных с аппаратной поддержкой;
  • лог транзакций с механизмом пакетной фиксации;
  • балансировка нагрузки через логическое разделение данных;
  • LRU-кэширование и табличные кэши;
  • изначальная ориентация на работу с большими объемами данных;
  • фокус на «быстрые» носители данных (SSD-накопители и флэш-диски).

Facebook, Yahoo!, LinkedIn и многие другие компании используют RocksDB в своей инфраструктуре для обеспечения высокой производительности обслуживания данных. Также RocksDB часто применяется как механизм хранения в рамках более крупной СУБД, например, в CockroachDB [2]. А Kafka Streams приложениях RocksDB выполняет роль хранилища состояний, оптимизированного для записи. Поэтому именно RocksDB может быть источником некоторых проблем с приложениями Kafka Streams, о чем мы поговорим далее.

4 проблемы приложений Kafka Streams из-за RocksDB и способы их решения

Основными проблемами приложений Kafka Streams вызванными некорректной работой RocksDB, можно назвать следующие [1]:

  • повышенное потребление памяти;
  • чрезмерное использование дискового пространства;
  • большое количество операций дискового ввода-вывода и остановки записи;
  • слишком много открытых файлов.

Что представляет собой каждая проблема и как решить ее с помощью грамотного конфигурирования RocksDB, мы рассмотрим далее.

Нехватка памяти

Если приложение Kafka Streams потребляет слишком много памяти из-за хранилища состояний, оно работает медленно или даже вылетает из-за ошибок OutOfMemory. Инструменты мониторинга операционной системы показывает высокий уровень использования памяти, а следующие метрики в Kafka Streams (версии платформы 2.7 и выше) принимают слишком большие значения [3]:

  • size-all-mem-tables – размер активных неизменяемых таблиц memtables в байтах;
  • block-cache-usage – размер памяти для записей в кэше блоков (байт);
  • block-cache-pinned-usage – размер памяти в байтах для записей, закрепляемых в блочном кэше;
  • estimate-table-readers-mem – предполагаемая память в байтах, используемая для чтения таблиц сортированной последовательности (Sorted Sequence Tables, SST), кроме памяти в блочном кэше.

Если хранилище состояний состоит из нескольких экземпляров RocksDB, как в случае агрегации по времени и сеансовых окон, каждая метрика суммирует значения со всех экземпляров RocksDB, кроме метрик блочного кэша (block-cache- *). Метрики блочного кэша суммируют значения со всех экземпляров RocksDB, если каждый из них использует свой собственный блочный кэш. А если кэш одного блока является общим для всех экземпляров, то эти метрики покажут значение только для одного экземпляра.

Решить проблему с чрезмерным потреблением памяти можно следующими способами:

  • проверить соответствие фактического размера хэш-таблицы memtable заданному в Kafka Streams. Настроить эту конфигурацию можно в реализации RocksDBConfigSetter через методы options.setMaxWriteBufferNumber() и options.setWriteBufferSize().
  • использовать общий блочный кеш во всех хранилищах состояний RocksDB, которые работают в одном клиенте Kafka Streams. Можно ограничить память, используемую совместно блочным кэшем и хэш-таблицами memtables.
  • проверить типовые ошибки RocksDB, которые связаны с памятью и могут быть исправлены в новой версии или с помощью рекомендации профессионального сообщества. Например, как исправить ошибку с утечкой памяти при применении операции drop() к семейству столбцов или как обойти исключение, сгенерированное неверным выделением памяти при использовании оператора сравнения ASSERT_NE в рамках тестирования с Google Testing Framework [4].

Завтра мы продолжим разговор про то, как настройки RocksDB влияют на работу stateful-приложений Apache Kafka Streams и рассмотрим особенности конфигурирования дисковых операций в этом NoSQL-хранилище данных. А о том, как RocksDB  используется в Apache Flink, читайте в нашей новой статье.

Администрирование кластера Kafka

Код курса
KAFKA
Ближайшая дата курса
11 июля, 2022
Длительность обучения
24 ак.часов
Стоимость обучения
60 000 руб.

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

 
Я даю свое согласие на обработку персональных данных и соглашаюсь с политикой конфиденциальности.

Источники

  1. https://www.confluent.io/blog/how-to-tune-rocksdb-kafka-streams-state-stores-performance/
  2. https://ru.bmstu.wiki/RocksDB
  3. https://docs.confluent.io/platform/current/streams/monitoring.html
  4. https://github.com/facebook/rocksdb/issues