Saltar al contenido principal
ClickHouse usa jemalloc como asignador global. Jemalloc incluye herramientas para el muestreo y el perfilado de asignaciones. ClickHouse y Keeper permiten controlar el muestreo mediante configuraciones, settings de consulta, comandos SYSTEM y comandos de cuatro letras (4LW) en Keeper. Hay varias formas de inspeccionar los resultados:
  • Recopilar muestras en system.trace_log con el tipo JemallocSample para analizar cada consulta.
  • Ver estadísticas de memoria en tiempo real y obtener perfiles de heap a través de la UI web de jemalloc integrada (26.2+).
  • Consultar el perfil actual de heap directamente desde SQL mediante system.jemalloc_profile_text (26.2+).
  • Volcar perfiles de heap a disco y analizarlos con jeprof.
Esta guía se aplica a las versiones 25.9+. Para versiones anteriores, consulte el perfilado de asignaciones para versiones anteriores a la 25.9.

Muestreo de asignaciones

Para muestrear y perfilar las asignaciones, inicie ClickHouse/Keeper con la opción de configuración jemalloc_enable_global_profiler habilitada:
<clickhouse>
    <jemalloc_enable_global_profiler>1</jemalloc_enable_global_profiler>
</clickhouse>
jemalloc realizará un muestreo de las asignaciones y almacenará la información internamente. También puede habilitar el muestreo por consulta mediante la configuración jemalloc_enable_profiler.
AdvertenciaDado que ClickHouse es una aplicación que realiza muchas asignaciones de memoria, el muestreo de jemalloc puede introducir una sobrecarga de rendimiento.

Almacenar muestras de jemalloc en system.trace_log

Puede almacenar muestras de jemalloc en system.trace_log con el tipo JemallocSample. Para habilitarlo globalmente, use la configuración jemalloc_collect_global_profile_samples_in_trace_log:
<clickhouse>
    <jemalloc_collect_global_profile_samples_in_trace_log>1</jemalloc_collect_global_profile_samples_in_trace_log>
</clickhouse>
AdvertenciaDado que ClickHouse es una aplicación que realiza muchas asignaciones de memoria, recopilar todas las muestras en system.trace_log puede generar una carga elevada.
También puede habilitarse para cada consulta mediante la configuración jemalloc_collect_profile_samples_in_trace_log.

Ejemplo: analizar el uso de memoria de una consulta

Primero, ejecute una consulta con el perfilador de jemalloc habilitado y recopile las muestras en system.trace_log:
SELECT *
FROM numbers(1000000)
ORDER BY number DESC
SETTINGS max_bytes_ratio_before_external_sort = 0
FORMAT `Null`
SETTINGS jemalloc_enable_profiler = 1, jemalloc_collect_profile_samples_in_trace_log = 1

Query id: 8678d8fe-62c5-48b8-b0cd-26851c62dd75

Ok.

0 rows in set. Elapsed: 0.009 sec. Processed 1.00 million rows, 8.00 MB (108.58 million rows/s., 868.61 MB/s.)
Peak memory usage: 12.65 MiB.
Si ClickHouse se inició con jemalloc_enable_global_profiler, no es necesario habilitar jemalloc_enable_profiler. Lo mismo ocurre con jemalloc_collect_global_profile_samples_in_trace_log y jemalloc_collect_profile_samples_in_trace_log.
Vacía el system.trace_log:
SYSTEM FLUSH LOGS trace_log
A continuación, consúltalo para obtener el uso acumulado de memoria a lo largo del tiempo:
WITH per_bucket AS
(
    SELECT
        event_time_microseconds AS bucket_time,
        sum(size) AS bucket_sum
    FROM system.trace_log
    WHERE trace_type = 'JemallocSample'
      AND query_id = '8678d8fe-62c5-48b8-b0cd-26851c62dd75'
    GROUP BY bucket_time
)
SELECT
    bucket_time,
    sum(bucket_sum) OVER (
        ORDER BY bucket_time ASC
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS cumulative_size,
    formatReadableSize(cumulative_size) AS cumulative_size_readable
FROM per_bucket
ORDER BY bucket_time
Encuentra el momento en que el uso de memoria fue más alto:
SELECT
    argMax(bucket_time, cumulative_size),
    max(cumulative_size)
FROM
(
    WITH per_bucket AS
    (
        SELECT
            event_time_microseconds AS bucket_time,
            sum(size) AS bucket_sum
        FROM system.trace_log
        WHERE trace_type = 'JemallocSample'
          AND query_id = '8678d8fe-62c5-48b8-b0cd-26851c62dd75'
        GROUP BY bucket_time
    )
    SELECT
        bucket_time,
        sum(bucket_sum) OVER (
            ORDER BY bucket_time ASC
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
        ) AS cumulative_size,
        formatReadableSize(cumulative_size) AS cumulative_size_readable
    FROM per_bucket
    ORDER BY bucket_time
)
Con ese resultado, vea qué pilas de asignación estuvieron más activas en el punto máximo:
SELECT
    concat(
        '\n',
        arrayStringConcat(
            arrayMap(
                (x, y) -> concat(x, ': ', y),
                arrayMap(x -> addressToLine(x), allocation_trace),
                arrayMap(x -> demangle(addressToSymbol(x)), allocation_trace)
            ),
            '\n'
        )
    ) AS symbolized_trace,
    sum(s) AS per_trace_sum
FROM
(
    SELECT
        ptr,
        sum(size) AS s,
        argMax(trace, event_time_microseconds) AS allocation_trace
    FROM system.trace_log
    WHERE trace_type = 'JemallocSample'
      AND query_id = '8678d8fe-62c5-48b8-b0cd-26851c62dd75'
      AND event_time_microseconds <= '2025-09-04 11:56:21.737139'
    GROUP BY ptr
    HAVING s > 0
)
GROUP BY ALL
ORDER BY per_trace_sum ASC

UI web de jemalloc

Esta sección se aplica a las versiones 26.2 o posteriores.
ClickHouse proporciona una UI web integrada para ver las estadísticas de memoria de jemalloc en el endpoint HTTP /jemalloc. Muestra métricas de memoria en tiempo real con gráficos, incluidas allocated, active, resident y mapped, así como estadísticas por arena y por bin. También puedes obtener perfiles de heap globales y por consulta directamente desde la UI.
http://localhost:8123/jemalloc
La UI del servidor incluye todas las pestañas: Summary, Allocations, Arenas, Operations, Global Profiler, Query Profiler y Raw Output.

Obtención de perfiles de heap desde SQL

Esta sección se aplica a las versiones 26.2+.
La tabla del sistema system.jemalloc_profile_text permite obtener y ver el perfil de heap actual de jemalloc directamente desde SQL, sin necesidad de herramientas externas ni de volcarlo antes a disco. La tabla tiene una sola columna:
ColumnaTipoDescripción
lineStringLínea del perfil de heap de jemalloc simbolizado.
Puede consultar la tabla directamente; no es necesario volcar antes un perfil de heap:
SELECT * FROM system.jemalloc_profile_text

Formato de salida

El formato de salida se controla mediante la configuración jemalloc_profile_text_output_format, que admite tres valores:
  • raw — perfil de heap en bruto, tal como lo genera jemalloc.
  • symbolized — formato compatible con jeprof con símbolos de función integrados. Como los símbolos ya están integrados, jeprof puede analizar la salida sin necesidad del binario de ClickHouse.
  • collapsed (predeterminado) — collapsed stacks compatibles con FlameGraph, una pila por línea con el recuento de bytes.
Por ejemplo, para obtener el perfil en bruto:
SELECT * FROM system.jemalloc_profile_text
SETTINGS jemalloc_profile_text_output_format = 'raw'
Para obtener una salida simbolizada:
SELECT * FROM system.jemalloc_profile_text
SETTINGS jemalloc_profile_text_output_format = 'symbolized'

Ajustes adicionales

  • jemalloc_profile_text_symbolize_with_inline (Bool, valor predeterminado: true) — Indica si se deben incluir los frames inline al simbolizar. Desactivarlo acelera significativamente la simbolización, pero reduce la precisión, ya que las llamadas a funciones inline no aparecerán en los stacks. Solo afecta a los formatos symbolized y collapsed.
  • jemalloc_profile_text_collapsed_use_count (Bool, valor predeterminado: false) — Al usar el formato collapsed, agrupa por número de asignaciones en lugar de por bytes.

Ejemplo: generar un flame graph desde SQL

Dado que el formato de salida predeterminado es collapsed, puedes redirigir la salida directamente a FlameGraph:
clickhouse-client -q "SELECT * FROM system.jemalloc_profile_text" | flamegraph.pl --color=mem --title="Allocation Flame Graph" --width 2400 > result.svg
Para generar un flame graph según el recuento de asignaciones en lugar de por bytes:
clickhouse-client -q "SELECT * FROM system.jemalloc_profile_text SETTINGS jemalloc_profile_text_collapsed_use_count = 1" | flamegraph.pl --color=mem --title="Allocation Count Flame Graph" --width 2400 > result.svg

Volcado de perfiles de heap a disco

Si necesitas guardar perfiles de heap como archivos para analizarlos sin conexión con jeprof, puedes volcarlos a disco. De forma predeterminada, el archivo del perfil de heap se generará en /tmp/jemalloc_clickhouse._pid_._seqnum_.heap, donde _pid_ es el PID de ClickHouse y _seqnum_ es el número de secuencia global del perfil de heap actual. Para Keeper, el archivo predeterminado es /tmp/jemalloc_keeper._pid_._seqnum_.heap y sigue las mismas reglas. Para volcar el perfil actual:
SYSTEM JEMALLOC FLUSH PROFILE
Devolverá la ubicación del perfil volcado.
Se puede definir una ubicación diferente añadiendo la opción prof_prefix a la variable de entorno MALLOC_CONF. Por ejemplo, si quieres generar perfiles en la carpeta /data, donde el prefijo del nombre de archivo será my_current_profile, puedes ejecutar ClickHouse/Keeper con la siguiente variable de entorno:
MALLOC_CONF=prof_prefix:/data/my_current_profile
El archivo generado se añadirá al prefijo, al PID y al número de secuencia.

Análisis de archivos de perfiles de heap con jeprof

Después de volcar los perfiles de heap en disco, se pueden analizar con la herramienta de jemalloc llamada jeprof. Se puede instalar de varias maneras:
  • Usando el gestor de paquetes del sistema
  • Clonando el repositorio de jemalloc y ejecutando autogen.sh desde la carpeta raíz. Esto le proporcionará el script jeprof dentro de la carpeta bin
Hay varios formatos de salida disponibles. Ejecute jeprof --help para ver la lista completa de opciones.

Perfiles de heap simbolizados

A partir de la versión 26.1+, ClickHouse genera automáticamente perfiles de heap simbolizados al ejecutar SYSTEM JEMALLOC FLUSH PROFILE. El perfil simbolizado (con la extensión .symbolized) contiene símbolos de función integrados y puede analizarse con jeprof sin necesidad del binario de ClickHouse. Por ejemplo, cuando ejecutas:
SYSTEM JEMALLOC FLUSH PROFILE
ClickHouse devolverá la ruta al perfil simbolizado (p. ej., /tmp/jemalloc_clickhouse.12345.0.heap.symbolized). Luego puedes analizarlo directamente con jeprof:
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --output_format [ > output_file]
No se requiere el binario: Al usar perfiles simbolizados (archivos .symbolized), no necesitas proporcionar a jeprof la ruta del binario de ClickHouse. Esto facilita mucho el análisis de perfiles en distintas máquinas o después de actualizar el binario.
Si tienes un heap profile no simbolizado más antiguo y todavía tienes acceso al binario de ClickHouse, puedes usar el enfoque tradicional:
jeprof path/to/clickhouse path/to/heap/profile --output_format [ > output_file]
Para perfiles no simbolizados, jeprof usa addr2line para generar stacktraces, lo que puede ser bastante lento. Si es así, se recomienda instalar una implementación alternativa de la herramienta.
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
Como alternativa, llvm-addr2line funciona igual de bien (pero tenga en cuenta que llvm-objdump no es compatible con jeprof).Y después úselo así: jeprof --tools addr2line:/usr/bin/llvm-addr2line,nm:/usr/bin/llvm-nm,objdump:/usr/bin/objdump,c++filt:/usr/bin/llvm-cxxfilt
Al comparar dos perfiles, puede usar el argumento --base:
jeprof --base /path/to/first.heap.symbolized /path/to/second.heap.symbolized --output_format [ > output_file]

Ejemplos

Con perfiles simbolizados (recomendado):
  • Genere un archivo de texto con cada procedimiento en una línea:
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --text > result.txt
  • Genera un archivo PDF con el grafo de llamadas:
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --pdf > result.pdf
Uso de perfiles sin simbolizar (requiere el binario):
  • Genere un archivo de texto con un procedimiento por línea:
jeprof /path/to/clickhouse /tmp/jemalloc_clickhouse.12345.0.heap --text > result.txt
  • Genera un archivo PDF con un grafo de llamadas:
jeprof /path/to/clickhouse /tmp/jemalloc_clickhouse.12345.0.heap --pdf > result.pdf

Generar un flame graph

jeprof permite generar collapsed stacks para crear flame graphs. Debe usar el argumento --collapsed:
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --collapsed > result.collapsed
O con un perfil sin simbolizar:
jeprof /path/to/clickhouse /tmp/jemalloc_clickhouse.12345.0.heap --collapsed > result.collapsed
Después, puedes usar muchas herramientas distintas para visualizar collapsed stacks. La más popular es FlameGraph, que incluye un script llamado flamegraph.pl:
cat result.collapsed | /path/to/FlameGraph/flamegraph.pl --color=mem --title="Allocation Flame Graph" --width 2400 > result.svg
Otra herramienta interesante es speedscope, que te permite analizar los stacks recopilados de forma más interactiva.

Opciones adicionales para el perfilador

jemalloc ofrece muchas opciones relacionadas con el perfilador. Se pueden controlar modificando la variable de entorno MALLOC_CONF. Por ejemplo, el intervalo entre muestras de asignación puede controlarse con lg_prof_sample. Si desea volcar el perfil de heap cada N bytes, puede habilitarlo con lg_prof_interval. Se recomienda consultar la página de referencia de jemalloc para ver la lista completa de opciones.

Otros recursos

ClickHouse/Keeper exponen métricas relacionadas con jemalloc de muchas formas distintas.
AdvertenciaEs importante tener en cuenta que ninguna de estas métricas está sincronizada con las demás y que los valores pueden diferir.

Tabla del sistema asynchronous_metrics

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

Tabla del sistema jemalloc_bins

Contiene información sobre las asignaciones de memoria realizadas mediante el asignador jemalloc en distintas clases de tamaño (bins), agregadas de todas las arenas. Referencia

Tabla del sistema jemalloc_stats (26.2+)

Devuelve la salida completa de malloc_stats_print() en una sola cadena. Equivale al comando SYSTEM JEMALLOC STATS.
SELECT * FROM system.jemalloc_stats

Prometheus

Todas las métricas relacionadas con jemalloc de asynchronous_metrics también están expuestas a través del endpoint de Prometheus tanto en ClickHouse como en Keeper. Referencia

Comando 4LW jmst de Keeper

Keeper admite el comando 4LW jmst, que devuelve estadísticas básicas del asignador de memoria:
echo jmst | nc localhost 9181
Última modificación el 10 de junio de 2026