Перейти к основному содержимому
Перейти к основному содержимому

Профилирование выделения

ClickHouse использует jemalloc в качестве своего глобального диспетчера памяти, который включает инструменты для выборки и профилирования выделений.
Чтобы сделать профилирование выделения более удобным, в ClickHouse/Keeper доступны команды SYSTEM наряду с командами 4LW.

Выборка выделений и сброс профилей кучи

Если мы хотим выбрать и профилировать выделения в jemalloc, нам нужно запустить ClickHouse/Keeper с включенным профилированием, используя переменную окружения MALLOC_CONF.

MALLOC_CONF=background_thread:true,prof:true

jemalloc будет выборочно выполнять выделения и хранить информацию внутри.

Мы можем сказать jemalloc, чтобы он сбросил текущий профиль, выполнив:

SYSTEM JEMALLOC FLUSH PROFILE

По умолчанию файл профиля кучи будет создан в /tmp/jemalloc_clickhouse._pid_._seqnum_.heap, где _pid_ — это PID ClickHouse, а _seqnum_ — это глобальный порядковый номер для текущего профиля кучи.
Для Keeper по умолчанию файл будет /tmp/jemalloc_keeper._pid_._seqnum_.heap, следуя тем же правилам.

Можно определить другое местоположение, добавив к переменной окружения MALLOC_CONF опцию prof_prefix.
Например, если мы хотим создать профили в папке /data, где префикс для имени файла будет my_current_profile, мы можем запустить ClickHouse/Keeper со следующей переменной окружения:

MALLOC_CONF=background_thread:true,prof:true,prof_prefix:/data/my_current_profile

Сгенерированный файл будет дополнен PID и номером последовательности.

Анализ профилей кучи

После того как мы создали профили кучи, нам нужно их проанализировать.
Для этого необходимо использовать инструмент jemalloc, называемый jeprof, который можно установить несколькими способами:

  • установив jemalloc с помощью менеджера пакетов системы
  • клонируя репозиторий jemalloc и запустив autogen.sh из корневой папки, что обеспечит вам скрипт jeprof в папке bin
примечание

jeprof использует addr2line для генерации стек-трейсов, что может быть довольно медленным.
Если это так, мы рекомендуем установить альтернативную реализацию этого инструмента.

git clone https://github.com/gimli-rs/addr2line.git --depth=1 --branch=0.23.0
cd addr2line
cargo build --features bin --release
cp ./target/release/addr2line path/to/current/addr2line

Существует множество различных форматов для генерации из профиля кучи с использованием jeprof.
Рекомендуем запустить jeprof --help, чтобы проверить использование и множество различных опций, которые предоставляет этот инструмент.

В целом, команда jeprof будет выглядеть так:

jeprof path/to/binary path/to/heap/profile --output_format [ > output_file]

Если мы хотим сравнить, какие выделения произошли между 2 профилями, мы можем установить базовый аргумент:

jeprof path/to/binary --base path/to/first/heap/profile path/to/second/heap/profile --output_format [ > output_file]

Например:

  • если мы хотим создать текстовый файл, где каждая процедура будет написана на отдельной строке:
jeprof path/to/binary path/to/heap/profile --text > result.txt
  • если мы хотим создать PDF-файл с графом вызовов:
jeprof path/to/binary path/to/heap/profile --pdf > result.pdf

Генерация графика пламени

jeprof позволяет нам генерировать сжатые стеки для создания графиков пламени.

Нам нужно использовать аргумент --collapsed:

jeprof path/to/binary path/to/heap/profile --collapsed > result.collapsed

После этого можно использовать множество различных инструментов для визуализации сжатых стеков.

Наиболее популярным будет FlameGraph, который содержит скрипт под названием flamegraph.pl:

cat result.collapsed | /path/to/FlameGraph/flamegraph.pl --color=mem --title="Allocation Flame Graph" --width 2400 > result.svg

Еще одним интересным инструментом является speedscope, который позволяет вам анализировать собранные стеки более интерактивно.

Управление профилировщиком выделений во время выполнения

Если ClickHouse/Keeper были запущены с включенным профилировщиком, они поддерживают дополнительные команды для отключения/включения профилирования выделений во время выполнения.
С помощью этих команд проще профилировать только определенные интервалы.

Отключить профилировщик:

SYSTEM JEMALLOC DISABLE PROFILE

Включить профилировщик:

SYSTEM JEMALLOC ENABLE PROFILE

Также возможно контролировать начальное состояние профилировщика, установив опцию prof_active, которая включена по умолчанию.
Например, если мы не хотим выборочно выполнять выделения во время запуска, а только после включения профилировщика, мы можем запустить ClickHouse/Keeper со следующей переменной окружения:

MALLOC_CONF=background_thread:true,prof:true,prof_active:false

и включить профилировщик позже.

Дополнительные опции для профилировщика

jemalloc имеет множество различных опций, связанных с профилировщиком, которые можно контролировать, изменяя переменную окружения MALLOC_CONF.
Например, интервал между выборками выделений можно контролировать с помощью lg_prof_sample.
Если вы хотите сбрасывать профиль кучи каждые N байт, вы можете включить это с помощью lg_prof_interval.

Рекомендуем проверить справочную страницу jemalloc для таких опций.

Другие ресурсы

ClickHouse/Keeper предоставляют метрики, связанные с jemalloc, множеством различных способов.

Warning

Важно быть в курсе того, что ни одна из этих метрик не синхронизирована между собой и значения могут изменяться.

Системная таблица asynchronous_metrics

SELECT *
FROM system.asynchronous_metrics
WHERE metric ILIKE '%jemalloc%'
FORMAT Vertical

Справка

Системная таблица jemalloc_bins

Содержит информацию о выделениях памяти, выполненных через диспетчер памяти jemalloc в различных классах размеров (bins), агрегированную со всех арен.

Справка

Prometheus

Все метрики, связанные с jemalloc, из asynchronous_metrics, также доступны через конечную точку Prometheus как в ClickHouse, так и в Keeper.

Справка

Команда jmst 4LW в Keeper

Keeper поддерживает команду jmst 4LW, которая возвращает базовые статистические данные по выделителю.

Пример:

echo jmst | nc localhost 9181