使用 Flame Graph 火焰图调试 ScyllaDB CPU 热点:从安装到实战 使用 Flame Graph 火焰图调试 ScyllaDB CPU 热点从安装到实战【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb本文是一份针对 ScyllaDB 的火焰图Flame Graph调试实战指南。ScyllaDB 采用 Seastar 框架的线程-每-核thread-per-core架构当出现延迟问题或某个 shard 的 CPU 占用异常时火焰图能够直观呈现哪条代码路径、哪些函数吃掉了最多的 CPU 时间。读完本文你将掌握火焰图工具的安装方式、把 Linux CPU 与 ScyllaDB shard 对应起来的方法以及用perf录制采样数据并生成可交互 SVG 火焰图的完整命令流程并学会结合仓库中自带的示例图进行热点解读。火焰图能帮 ScyllaDB 解决什么问题火焰图Flame Graph本质上是perf等采样器采集到的调用栈call stack的图形化聚合。它的横轴表示函数在采样中的累计占比宽度越宽占用的 CPU 时间越多纵轴表示调用深度上层是调用者下层是被调用者。对 ScyllaDB 而言它主要回答两类问题定位热点路径需要弄清楚哪条 ScyllaDB 代码路径/函数占用了最多的时间。典型场景是出现延迟问题时快速找出是压缩compaction、查询处理、内存分配还是网络栈拖慢了整体性能。跨 shard 对比需要在不同 shard 之间对比特定 ScyllaDB 代码路径/函数的时间消耗。典型场景是只有一个 CPU 上出现延迟其他 CPU 正常——这种局部化异常在按 CPU 聚合的火焰图上会非常醒目。为什么强调按 CPU 而不是按整体这与 ScyllaDB 的架构直接相关Seastar 框架采用线程-每-核模型每个 ScyllaDB shard 绑定一个独立的 CPU 核数据、内存、网络队列都按 shard 隔离。这种设计意味着全局聚合视图往往会掩盖只发生在特定 CPU 上的异常行为而单个 CPU 的火焰图能把这类问题暴露出来。关于这一架构的具体调试背景可参考 Using the perf utility with ScyllaDB 一文中的说明。第一步安装火焰图工具链火焰图本身由 Brendan Gregg 的 FlameGraph 项目提供核心是两个 Perl 脚本stackcollapse-perf.pl把perf script的原始输出折叠成调用栈统计和flamegraph.pl把折叠结果渲染成 SVG。安装方式有两种方式一通过系统包管理器安装DNFdnf install flamegraph.noarch flamegraph-stackcollapse-perf.noarch方式二克隆 FlameGraph 源码仓库如果上述包在你的发行版仓库中不可用直接克隆 FlameGraph 的 git 仓库即可git clone https://github.com/brendangregg/FlameGraph cd FlameGraph克隆完成后目录下的stackcollapse-perf.pl与flamegraph.pl即可直接调用可以加入 PATH 或直接以相对路径调用。第二步前置知识——把 Linux CPU 映射到 ScyllaDB shard火焰图是按 CPU 录制的但 ScyllaDB 的延迟问题通常先表现为某个 shard 异常。因此录制之前必须先把 shard 编号翻译成 Linux CPU 编号。一个常见的误区是认为 ScyllaDB 的 shard ID 与 CPU ID 存在简单且可预测的一一对应关系——实际上并不成立。由于 ScyllaDB 会优先让 shard 使用物理核、跳过超线程兄弟核等策略映射关系需要动态查询。从 ScyllaDB 3.0 开始发行包自带了seastar-cpu-map.sh脚本用于查询这一映射更早版本可从 Seastar 源码树的scripts目录获取详细用法见 Map CPUs to ScyllaDB Shards。查看某个 shard 对应的 CPUseastar-cpu-map.sh -n scylla -s 0输出shard: 0, cpu: 1查看全部 shard 的映射seastar-cpu-map.sh -n scylla输出示例shard: 0, cpu: 1 shard: 1, cpu: 2 shard: 3, cpu: 4 shard: 2, cpu: 3注意上面的输出顺序并不是 0、1、2、3——这正是shard 与 CPU 并非简单对应的直观证明。拿到shard: N, cpu: M的结果后后续所有perf命令都可以加上-C M参数把采样范围限定在单个 CPU 上。另一个值得了解的参数是--smpScyllaDB 的 shard 数量由启动参数控制。当内存与 shard 数不匹配时进程会提示Configure more memory (--memory option) or decrease shard count (--smp option)见 main.cc这从侧面印证了 shard 数与内存、CPU 资源的强绑定关系也解释了为什么排查性能问题时必须精确到单个 shard/CPU。第三步运行 perf 录制并生成火焰图在完成 CPU 映射之后执行以下两条命令完成录制与渲染sudo perf record --call-graph dwarf -C CPU on which you are recording sudo perf script | stackcollapse-perf.pl | flamegraph.pl some_name.svg对命令做几点说明sudo perf record --call-graph dwarf以 DWARF 调试信息格式记录调用栈。ScyllaDB 是高度模板化的 C 代码dwarf模式比默认的帧指针frame pointer模式能捕获到更完整的栈信息。若担心采样开销可以参考 Using the perf utility with ScyllaDB 中推荐的-F 9999Hz 采样频率用法。-C CPU限定在指定 CPU 上录制这是本文档强调的关键点——录制范围必须是你通过seastar-cpu-map.sh定位到的那个 CPU。命令本身不显式指定时长perf record会持续录制直到按下CtrlC停止。录制时间越长、样本越多火焰图越能反映真实热点分布。perf script输出原始采样事件stackcollapse-perf.pl将其折叠为调用栈 - 样本数的统计最后由flamegraph.pl渲染为 SVG。解读仓库自带的示例火焰图仓库的 docs/kb/flamegraph.svg 是一张由上述流程生成的、针对 ScyllaDB 的真实示例图。从 SVG 源码中可以看到它包含的典型元素交互控件图顶部有Reset Zoom重置缩放与Search搜索按钮底部有details悬停提示区域——这正是火焰图 SVG 区别于普通图片的关键特性CQL 请求处理路径图中出现了transport::cql_server::connection::process_request、cql_server::connection::process_execute、query_processor::process_statement等符号展示了从 CQL 协议层进入查询处理器的完整链路跨 shard 通信出现了smp_message_queue::async_work_item、storage_proxy::query_singular_local等符号对应 Seastar 的跨核消息队列与存储代理的本地查询分发内核与驱动层ixgbe_poll、net_rx_action、do_IRQ、__do_softirq等符号说明图中还包含了网卡轮询与中断处理的开销内存分配热点memory::small_pool::allocate、memory::cpu_pages::free等符号表明 Seastar 的内存分配器也在采样中占据了一定比例。注意示例图中还出现了大量 mangled 的 C 符号如_ZN12continuation...。这在实际调试中很常见——如果觉得符号难以阅读可以结合 Decoding Stack Traces 中介绍的seastar-addr2line工具对栈地址做解码两者配合能还原出可读的源码级调用链。SVG 的正确打开方式生成的.svg文件不是一张普通图片而是一张动态可交互的图表搜索点击Search按钮输入函数名支持正则匹配的矩形块会高亮帮助你快速定位某个函数在所有调用路径中的位置缩放点击任意一个矩形块即可放大该函数及其子调用再点击Reset Zoom恢复全貌悬停详情鼠标悬停在矩形块上会显示函数名、采样样本数与占比例如示例图中的transport::cql_server::connection::process_request (8 samples, 0.02%)最佳浏览方式在 Chrome 或 Firefox 等现代浏览器中打开即可完整享受以上全部交互功能。实用技巧如何录出一张高质量火焰图原文档给出了两条直接影响火焰图质量的关键经验尽量让被测 CPU 跑满 100%。录制期间应给 ScyllaDB 加压例如用负载生成工具持续写入/读取使 CPU 接近满载。否则火焰图里会充斥着大量与空闲时间处理idle handling相关的 OS 函数干扰对真实热点的判断。这与 Using the perf utility with ScyllaDB 中的观点一致perf 在 CPU 运行于 100% 利用率时最有价值可以清晰识别出被特定函数吃掉的大块执行时间。不要对全部 shard 一起录制。例如用perf record -p pid录制整个进程会把来自不同线程即不同 shard对同一符号的调用混在一起导致结果难以解读——同一个函数可能由不同 shard 从不同上下文调用聚合后无法区分热点究竟发生在哪个执行路径上。这也是本文反复强调使用-C CPU单核录制的根本原因。补充一个来自 Using the perf utility with ScyllaDB 的重要背景由于 Seastar 的轮询polling机制ScyllaDB 即使在没有瓶颈时也容易把 CPU 推到 100%且轮询相关函数会在 perf 报告中占据高 CPU 时间。因此在解读火焰图时需要注意区分真正做工作的 CPU 时间与轮询等待的 CPU 时间。如果怀疑问题不在 ScyllaDB 自身可以观察reactor_utilization反映非轮询工作占比指标当它很高、同时 Linux 视图下的systemCPU 利用率也很高时说明内核才是 CPU 的主要使用者需要把排查方向转向系统层面。延伸火焰图之外的调试工具链火焰图是整个性能分析工作流中的一环与之配合的常用手段包括perf top实时点状视图适合先快速确认当前 CPU 上的热点函数再决定是否需要录制完整火焰图perf top -C 1即查看 CPU 1 的实时热点perf report录制完成后以文本形式输出调用关系分析例如sudo perf report --no-children --stdio /tmp/trace.txt可将结果导出到文件详见 Using the perf utility with ScyllaDB栈解码对日志中的崩溃栈或火焰图中的 mangled 符号使用seastar-addr2line结合 debug 二进制解码出源码级调用链详见 Decoding Stack Traces。完整的调试与调优知识体系还可以参考知识库索引 docs/kb/index.rst 中的 Analyzing ScyllaDB 板块。小结火焰图是诊断 ScyllaDB CPU 热点与局部延迟问题的高效工具。其核心流程可归纳为四步安装stackcollapse-perf.pl与flamegraph.pl工具链 → 用seastar-cpu-map.sh把可疑 shard 映射到 Linux CPU → 用perf record --call-graph dwarf -C CPU在单核上录制采样记得加压至满载→ 用perf script | stackcollapse-perf.pl | flamegraph.pl生成可在浏览器中交互检索的可视化 SVG。遵循单核录制、满载采样、区分轮询开销三条原则你就能在 CQL 请求处理、跨 shard 消息队列、内存分配与内核网络栈之间快速锁定真正消耗 CPU 的那条代码路径。【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考