文章

ClickHouse 火焰图绘制

ClickHouse 火焰图绘制

使用火焰图分析程序性能瓶颈

介绍

ClickHouse 共有三种火焰图

  • CPU:显示代码中函数的 cpu 耗时,函数宽度与 cpu time 成正比。主要用于分析进程中的 cpu 瓶颈
  • Memory:显示代码中函数中申请内存的大小,函数宽度与 memory allocation 成正比。主要用于优化进程的内存占用。
  • Real:显示代码中函数的 duration 耗时,函数宽度与 real time 成正比。与 cpu 火焰图结合可用于分析进程中的 io 瓶颈

需要开启 ClickHouse trace_log 系统表

执行下面的命令生成相关的 tsv.zst 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for trace_type in CPU Memory Real
do
    ./clickhouse client -q "
            select
                arrayStringConcat((arrayMap(x -> concat(splitByChar('/', addressToLine(x))[-1], '#', demangle(addressToSymbol(x)) ), trace)), ';') AS stack,
                count(*) AS samples
            from system.trace_log
            where trace_type = '$trace_type'
            group by trace
            order by samples desc
            settings allow_introspection_functions = 1
            format TabSeparated" \
        | zstd --threads=0 > "./trace-log-$trace_type-flamegraph.tsv.zst" ||:
done

解压缩 tsv 文件并绘制 memory 火焰图

1
2
zstd -d trace-log-Memory-flamegraph.tsv.zst
flamegraph.pl --inverted --width=1200 --countname=ms trace-log-Memory-flamegraph.tsv > memory.svg

demo:

real

关于具体怎么根据火焰图分析性能并排查问题,下面有一个实际的案例场景: ClickHouse 集成了 FTS 索引之后,在 1 亿文本数据量下 benchmark 的表现太差,latency 能达到 7s,此时需要分析文本搜索的时延是否存在不合理的瓶颈。

  • 通过 tracing 分析单条 query 的时延(高并发情况下观察单条 query 的 latency 路径)
  • 在 FTS 底层代码(rust 子项目)写测试用例,模仿 ClickHouse 执行的 query 流程写一个测试函数并进行压测,直接分析 rust 侧的性能
  • 观察压测期间 CPU、内存占用,逐步减少或者增大并发量,观察 CPU 资源对 Latency 的影响。
  • rust 这边使用的 criterion 测试工具,实际上是单线程测试,需要与 ClickHouse 并发 = 1 进行对齐。
本文由作者按照 CC BY 4.0 进行授权