跳到主要内容

使用 LLVM 的 XRay 分析 ClickHouse

·3 分钟阅读
了解如何使用 LLVM 的 XRay instrumentation profiler 分析 ClickHouse,可视化追踪并分析性能。

profiler 的类型

LLVM 已经包含一个工具,该工具对代码进行检测,使我们能够进行检测分析。与抽样或统计分析相反,它非常精确,不会丢失任何调用,但代价是需要检测代码并消耗更多资源。

简而言之,检测分析器引入新代码来跟踪对所有函数的调用。统计分析器允许我们在不需要任何更改的情况下运行代码,定期拍摄快照以查看应用程序的状态。因此,只有在拍摄快照时正在运行的函数才会被考虑。perf 是一个非常著名的统计分析器。

如何使用 XRay 进行分析

检测代码

想象一下以下源代码

#include <chrono>
#include <cstdio>
#include <thread>

void one()
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}

void two()
{
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}

int main()
{
printf("Start\n");

for (int i = 0; i < 10; ++i)
{
one();
two();
}

printf("Finish\n");
}

为了使用 XRay 进行检测,我们需要添加一些标志,如下所示

clang++ -o test test.cpp -fxray-instrument -fxray-instruction-threshold=1
  • 需要 -fxray-instrument 来检测代码。
  • -fxray-instruction-threshold=1 用于检测所有函数,即使它们像我们的示例中那样非常小。默认情况下,它会检测至少 200 条指令的函数。

我们可以通过检查二进制文件中是否存在新节来确保代码已正确检测

objdump -h -j xray_instr_map test

test: file format elf64-x86-64

Sections:
Idx Name Size VMA LMA File off Algn
17 xray_instr_map 000005c0 000000000002f91c 000000000002f91c 0002f91c 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA

使用正确的 env var 值运行进程以收集跟踪

默认情况下,除非明确要求,否则不会进行 profiler 收集。换句话说,除非我们正在进行分析,否则开销可以忽略不计。我们可以为 XRAY_OPTIONS 设置不同的值来配置 profiler 何时开始收集以及如何收集。

XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1" ./test
==74394==XRay: Log file in 'xray-log.test.14imlN'
Start
Finish
==74394==Cleaned up log for TID: 74394

转换跟踪

XRay 的跟踪可以转换为多种格式。trace_event 格式非常有用,因为它易于解析,并且已经有许多工具支持它,因此我们将使用该格式

llvm-xray convert --symbolize --instr_map=./test --output-format=trace_event xray-log.test.14imlN | gzip > test-trace.txt.gz

可视化跟踪

我们可以使用基于 Web 的 UI,例如 speedscope.appPerfetto

虽然 Perfetto 可以更轻松地可视化多个线程和查询数据,但 speedscope 更擅长生成 flamegraph 和数据的三明治视图。

时间顺序

time-order

左重

left-heavy

三明治

sandwich

分析 ClickHouse

  1. 在构建 ClickHouse 时,将 -DENABLE_XRAY=1 传递给 cmake。这设置了正确的编译器标志
  2. 在运行 ClickHouse 时设置 XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1" env var 以生成跟踪。
  3. 将跟踪转换为有趣的格式,例如 trace event:llvm-xray convert --symbolize --instr_map=./build/programs/clickhouse --output-format=trace_event xray-log.clickhouse.ZqKprE | gzip > clickhouse-trace.txt.gz
  4. speedscope.appPerfetto 中可视化跟踪。

clickhouse-time-order

请注意,这只是一个线程的可视化。您可以在顶部栏上选择其他 tid

查看文档

查看 XRay InstrumentationDebugging with XRay 文档以了解更多详情。