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

Профилирование выделения памяти для версий до 25.9

ClickHouse использует jemalloc в качестве глобального аллокатора. Jemalloc предоставляет инструменты для выборочного отслеживания и профилирования выделения памяти.
Для удобства профилирования выделения памяти предусмотрены команды SYSTEM, а также четырёхбуквенные (4LW) команды в Keeper.

Сэмплирование выделений памяти и сброс профилей кучи

Если вы хотите выполнять сэмплирование и профилирование выделений памяти в 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 и выполнив autogen.sh в корневом каталоге. В результате в каталоге bin появится скрипт jeprof
Примечание

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]

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

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 путь/к/исполняемому/файлу путь/к/профилю/heap --pdf > result.pdf

Генерация flame-графа

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

Необходимо использовать аргумент --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, множеством разных способов.

Предупреждение

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

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

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

Справочник

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

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

Справочник

Prometheus

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

Справочник

4LW-команда jmst в Keeper

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

echo jmst | nc localhost 9181