Вчера мы рассказывали, почему некоторые 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, мы рассмотрим далее.
Apache Kafka для инженеров данных
Код курса
DEVKI
Ближайшая дата курса
2 июня, 2025
Продолжительность
24 ак.часов
Стоимость обучения
72 000
Высокая загрузка диска
Подобно чрезмерному потреблению памяти, о чем мы писали вчера, приложение 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().
Администрирование кластера Kafka
Код курса
KAFKA
Ближайшая дата курса
2 июля, 2025
Продолжительность
24 ак.часов
Стоимость обучения
72 000
Узнайте больше особенностей продвинутого конфигурирования Apache Kafka для разработки распределенных приложений потоковой аналитики больших данных и администрирования кластеров на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
Источники
- https://ru.bmstu.wiki/RocksDB
- https://www.confluent.io/blog/how-to-tune-rocksdb-kafka-streams-state-stores-performance/
- https://docs.confluent.io/platform/current/streams/monitoring.html