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

Автор Категория ,
3 проблемы приложений Apache Kafka Streams из-за RocksDB и способы их решения

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

Быстрые диски, RocksDB и stateful-приложения Apache Kafka Streams

Приложения Apache Kafka Streams при выполнении операций с отслеживанием состояния (stateful), таких как оконные соединения и агрегаты входящих записей в качестве локального хранилища состояний используют RocksDB. Это высокопроизводительное встраиваемое постоянное key-value NoSQL-хранилище изначально проектировалось для работы с большим объемом данных и оптимизировано для многоядерных CPU, рабочих нагрузок ввода/вывода (I/O) и быстрой памяти в виде твердотельных SSD-накопителей и флэш-дисков [1]. Однако, некорректная настройка некоторых конфигураций RocksDB может вызвать проблемы с приложениями Kafka Streams, связанные с использованием диска [2]:

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

Почему эти проблемы ограничивают производительность приложений Kafka Streams и как их решить с помощью настройки RocksDB, мы рассмотрим далее.

Высокая загрузка диска

Подобно чрезмерному потреблению памяти, о чем мы писали вчера, приложение Kafka Streams также может слишком интенсивно использовать жесткий диск из-за хранилища состояний RocksDB, информируя об этом следующими сигналами [2]:

  • аварийное завершение работы приложения из-за ошибок ввода-вывода;
  • средства мониторинга операционной системы показывают излишне высокий уровень использования диска для каталогов состояний RocksDB;
  • значения параметра total-sst-files-size, общий размер всех файлов таблицы сортированной последовательности (Sorted Sequence Table, SST) в байтах, слишком высоки.

Справиться с чрезмерной загрузкой диска помогут следующие действия:

  • уровневое сжатие вместо универсального по умолчанию. Сжатие (уплотнение) – это процесс объединения произвольного набора файлов SST и создания новых таких SST-файлов с перезаписанными ключами и удаленными ключами, чтобы повысить производительность RocksDB. Уровневое уплотнение имеет занимает меньше пространства, чем универсальное за счет более низкой скорости записи. Задать значение этой конфигурации можно в RocksDBConfigSette через параметр setCompactionStyle (CompactionStyle.LEVEL).
  • увеличение дискового пространства в случае универсального уплотнения, чтобы поддерживать высокую скорость записи без ошибок.

Слишком частые операции дискового ввода-вывода и остановки записи

Если операции дискового ввода-вывода выполняются слишком часто, увеличивается задержка обработки приложения и клиент Kafka Streams исключается из группы потребителей. Об этом сигнализируют следующие метрики RocksDB в Kafka Streams:

  • memtable-bytes-flushed-[rate | total] – среднее количество байтов, сбрасываемых из хэш-таблицы memTable на диск в секунду;
  • bytes-[read | written]-compaction-rate – среднее количество байтов, прочитанных/записанных в секунду во время сжатия;
  • write-stall-duration-[avg | total] – средняя/общая длительность остановок записи в милисекундах;
  • memtable-hit-ratio – коэффициент попадания в memtable относительно всех поисков в ней;
  • block-cache-[data | index | filter]-hit-ratio – коэффициенты попадания данных в блочный кэш, его индекс или фильтр.

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

  • проверка оборудования – возможно, причина в неисправном жестком диске;
  • проверка количества потоков фонового сжатия данных. По умолчанию Kafka Streams настраивает RocksDB на такое число потоков фонового сжатия в соответствии с доступными CPU. А если доступен только 1 процессов, будет запущено 2 фоновых потока сжатия. Увеличить количество фоновых потоков сжатия можно в реализации RocksDBConfigSetter с помощью метода setIncreaseParallelism().
  • увеличение количества и размера хэш-таблиц memtables и блочного кэша. При поиске не рекомендуется читать с диска данные, которые хранятся в memtables или блочных кэшах, хотя это и уменьшает количество операций ввода-вывода. Можно хранить больше данных в хэш-таблицах и блочных кэши, просто увеличив их размер. Но при этом важно следить о достаточном наличии памяти, чтобы не столкнуться с ошибками OutOfMemory.
  • увеличение значения параметра max.poll.interval.ms – максимальной задержки между вызовами poll () при использовании управления группами потребителей. По умолчанию значение этой конфигурации равно 5 минут. Как только клиент-потребитель Kafka Streams превысит этот интервал, он исключается из группы потребителей, что приводит к повторяющимся перебалансировкам и увеличению задержки обработки. Такая ситуация возможно при записи в RocksDB. Избежать это возможно, увеличив значение параметра poll.interval.ms в приложении Kafka Streams.

Большое количество открытых файлов

По умолчанию Kafka Streams настраивает хранилища состояний RocksDB без ограничений количества открытых файлов, т.е. параметр Max_open_files=-1. Это означает, что база данных открывает все SST-файлы и сохраняет указатель файла на каждый из них, чтобы увеличить скорость работы. Однако при этом могут закончиться файловые дескрипторы, и приложение будет аварийно завершаться из-за ошибок ввода-вывода. Решить эту проблему помогут следующие действия [2]:

  • увеличение лимита операционной системы на открытые файлы через задание параметра max_open_files равному -1;
  • установка лимита открытых файлов в RocksDB, задав значение параметра max_open_files меньше ограничения операционной системы, чтобы избежать нехватки файловых дескрипторов. Это можно сделать в RocksDBConfigSetter через метод setMaxOpenFiles().
  • уменьшение количества открытых файлов RockDB через увеличение значения параметра target_file_size_base и размер файлов SST. Например, размер файлов SST по умолчанию равен 64 МБ. Можно установить его равным 128 МБ, настроив реализацию RocksDBConfigSetter с помощью метода setTargetFileSizeBase().

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

Источники

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