- 存储
- 分布式文件系统
- 对象存储
- 后端
- 高可用
【免费下载链接】ceph
Ceph is a distributed object, block, and file storage platform
Ceph 作为统一的分布式对象、块与文件存储平台,其 I/O 请求会跨越客户端(librados/librbd)、消息层(Messenger)、Objecter、OSD 主处理线程直至底层对象存储等多个阶段。本指南围绕 doc/dev/blkin.rst 展开,系统讲解如何用 LTTng 用户态追踪(Userspace Tracing)为 Ceph 埋点、如何借助 Blkin 实现基于 Dapper 语义的跨阶段请求链路追踪,以及最终如何用 Zipkin 将追踪结果可视化。读完本文,你将掌握从编译开关、ceph.conf配置、vstart.sh本地集群验证到 Zipkin 展示的完整操作链路,并理解其底层 tracepoint 与 span 传播机制。
一、Ceph 追踪体系总览:tracepoint 是骨架,Blkin 是链路
Ceph 的追踪能力建立在两个层次上:
LTTng 事件追踪(第一层):Ceph 在关键代码路径中插入 LTTng-UST tracepoint(用户态静态探针),用于观察某一阶段"发生了什么"(如 OSD 处理一个 op 的进入/退出)。所有 tracepoint 定义文件(
.tp)与对应的 provider 共享库源码集中在 src/tracing 目录,包括bluestore.tp、objectstore.tp、osd.tp、oprequest.tp、pg.tp、librados.tp、librbd.tp、rgw_op.tp、rgw_rados.tp、mgroprequest.tp、eventtrace.tp等。Blkin 分布式追踪(第二层):Blkin 是 Marios Kogias 等人创建的库,它实现 Dapper 追踪语义(
trace_id/span_id/parent_span_id),用于把"一个请求从高层进入系统、到最终由 RADOS 服务完成"的因果链路串联起来,配合每个阶段的时延信息,实现端到端的请求路径可视化。由于底层仍由 LTTng 承载,开销很低且可实时采集,采集到的数据最终可交给 Twitter 的 Zipkin 展示。
需要特别留意的是:Blkin 功能在 Squid 版本中已被标记为弃用(deprecated),并将在后续版本中移除(见 doc/dev/blkin.rst 中的.. deprecated::声明)。而 LTTng 事件追踪仍是 Ceph 长期维护的能力,因此本文先完整展开 LTTng 部分,再讲解 Blkin/Zipkin 链路。
二、使用 LTTng 追踪 Ceph
2.1 编译:通过-DWITH_LTTNG=ON启用(默认开启)
LTTng 支持是 Ceph 默认编译选项(default: ON)。从源码编译时显式指定:
./do_cmake -DWITH_LTTNG=ON在构建系统中,WITH_LTTNG会驱动 src/tracing/CMakeLists.txt 生成各 provider 共享库。该文件对每个.tp文件调用lttng-gen-tp生成头文件,并通过add_tracing_library打包出多个*.so:
osd_tp(由oprequest.tp、osd.tp、pg.tp组成)rados_tp(librados.tp)os_tp(objectstore.tp)bluestore_tp(bluestore.tp)rgw_op_tp、rgw_rados_tpmgr_op_tp(mgroprequest.tp)rbd_tp(仅当WITH_RBD时构建)cyg_profile_tp(仅当WITH_OSD_INSTRUMENT_FUNCTIONS时构建,见 2.5)eventtrace_tp(仅当WITH_EVENTTRACE时构建)
这些共享库最终安装到${CMAKE_INSTALL_LIBDIR},运行时会由目标进程通过动态加载方式绑定到对应 tracepoint。
2.2 包安装:为什么缺少 tracepoint.so会导致 coredump
如果 Ceph 是通过 YUM / DNF / APT 等包管理器安装的(而非容器化部署),必须根据你要追踪的模块安装对应的开发包。文档明确列出:
librbd-devel librgw-devel librados-devel原因在于:当进程(如ceph-osd、radosgw)在运行时遇到缺失的 LTTng tracepoint 共享库(*.so)文件时,会因无法解析符号而直接 coredump。因此"编译时开了追踪、运行环境却没装齐 provider 库"是一个典型的崩溃场景,务必按需把三个-devel包装齐。
2.3 配置选项:在ceph.conf中开启对应追踪开关
编译启用只是第一步,追踪行为默认是关闭的。必须在ceph.conf中把目标开关设为true。下表汇总了当前可用的选项,并对照仓库中的配置定义(src/common/options/global.yaml.in、src/common/options/rbd.yaml.in、src/common/options/rgw.yaml.in)给出默认值(所有选项均为bool类型、advanced级别,默认false):
| 配置项 | 默认值 | 含义 | 仓库配置位置 |
|---|---|---|---|
bluestore_tracing | false | 启用 BlueStore 事件追踪 | global.yaml.in |
event_tracing | false | 通用事件追踪(需-DWITH_EVENTTRACE编译) | global.yaml.in |
osd_function_tracing | false | OSD 函数级插桩追踪(需-DWITH_OSD_INSTRUMENT_FUNCTIONS) | global.yaml.in |
osd_objectstore_tracing | false | 对象存储层追踪(实际即 filestore 追踪) | global.yaml.in |
rbd_tracing | false | RBD(librbd)LTTng-UST tracepoint | rbd.yaml.in |
osd_tracing | false | OSD LTTng-UST tracepoint | global.yaml.in |
rados_tracing | false | librados LTTng-UST tracepoint | global.yaml.in |
rgw_op_tracing | false | RGW 操作级追踪 | rgw.yaml.in |
rgw_rados_tracing | false | RGW 调用 RADOS 层追踪 | rgw.yaml.in |
从配置定义看,两个选项还可细读:
bluestore_tracing有配套的bluestore_throttle_trace_rate(float,默认 0,单位:每秒采样的 BlueStore 事务数),可用于控制追踪采样率、降低开销(见 global.yaml.in)。- 文档中括号标注了部分选项与编译开关的对应关系:
event_tracing需要-DWITH_EVENTTRACE,osd_function_tracing需要-DWITH_OSD_INSTRUMENT_FUNCTIONS。
2.4 测试 Trace:从启动 LTTng 会话到查看结果
完整的测试流程如下(命令均来自 doc/dev/blkin.rst)。
第一步:启动 LTTng 会话守护进程
lttng-sessiond --daemonize第二步:用 vstart 启动本地集群并注入追踪配置
../src/vstart.sh -d -n -l -e -o "osd_tracing = true"其中-o是核心机制:它会把后面的键值对作为额外配置注入到生成的ceph.conf(当前 src/vstart.sh 中-o将参数追加进extra_conf)。其他常用开关如-n(新建集群)、-e(启用纠删码池,创建名为ec的池)在 src/vstart.sh 中有对应实现;-d(debug 模式)与-l等参数的具体含义以你所检出版本的./vstart.sh --help为准。如果你用的版本不支持某个短选项,直接通过-o注入osd_tracing = true也能达到同样的追踪开启效果。
第三步:列出用户态可用 tracepoint
lttng list --userspace可以看到类似如下的输出(每个运行中的进程列出其绑定的 UST 事件):
UST events: ------------- PID: 100859 - Name: /path/to/ceph-osd pg:queue_op (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) osd:do_osd_op_post (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) osd:do_osd_op_pre_unknown (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) osd:do_osd_op_pre_copy_from (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) osd:do_osd_op_pre_copy_get (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) ...第四步:创建会话、启用事件并开始追踪
lttng create trace-test lttng enable-event --userspace osd:* lttng startosd:*会一次性启用osdprovider 下的全部事件;你也可以按需只启用某个事件,例如lttng enable-event --userspace osd:do_osd_op_pre_write。
第五步:制造负载
rados bench -p ec 5 write向ec池执行 5 秒的写入基准测试,产生真实的 OSD 操作流。
第六步:停止追踪并查看结果
lttng stop lttng view第七步:销毁会话
lttng destroy2.5 源码视角:tracepoint 长什么样
以 src/tracing/osd.tp 为例,osdprovider 定义了非常细粒度的探针。每个TRACEPOINT_EVENT包含参数(TP_ARGS)与字段(TP_FIELDS)两部分,例如:
osd:prepare_tx_enter/osd:prepare_tx_exit:一次 OSD 事务准备阶段的进入/退出,字段为osd_reqid_t的四个分量(type、num、tid、inc);osd:ms_fast_dispatch、osd:opwq_process_start/osd:opwq_process_finish:消息快速分发与 op 工作队列处理的起止;osd:do_osd_op_pre_*系列:按操作类型细分的"op 执行前"探针,覆盖read、write、writefull、writesame、zero、truncate、delete、create、append、setxattr、omap*、copy_from、call、watch、checksum等,字段通常包含对象名(oid)、快照(snap)、偏移(offset)、长度(length)、操作码(op)与操作名(opname);osd:do_osd_op_post:op 执行完成后的探针,除上述字段外还携带执行结果(result)。
也就是说,osd:*这一组事件足以还原"一个对象操作在 OSD 内被解析、排队、执行、返回"的全过程。如果你需要做函数级的火焰图分析,可参考 src/tracing/README.md:Ceph 支持 GCC 的-finstrument-functions插桩(-DWITH_OSD_INSTRUMENT_FUNCTIONS=ON,目前仅 GCC 生效),进入/退出探针为lttng_ust_cyg_profile:func_enter与lttng_ust_cyg_profile:func_exit,payload 中的addr与call_site可通过nm解析为函数名,后续可用 TraceCompass 生成火焰图,或用 libbabeltrace 编写自定义分析。
三、Blkin:端到端的请求链路追踪
3.1 Blkin 是什么
Blkin 的作用是追踪"一个请求从进入系统的高层(客户端)开始,直到被 RADOS 最终服务"的完整路径。其核心思想是实现 Dapper 的追踪语义:通过trace_id(一次请求的唯一标识)、span_id(每个处理阶段的标识)与parent_span_id(父阶段标识)表达各处理阶段之间的因果关系,目标是端到端可视化请求在系统中的路由,并附带每个阶段的时延信息。借助 LTTng,这一切可以以极小开销、实时地完成;LTTng 采集的 trace 再由 Twitter 的 Zipkin 做可视化。
再次强调:该功能在 Squid 版本中被标记为弃用,后续版本将移除(见 doc/dev/blkin.rst 的 deprecation 声明),本文按文档内容完整呈现其用法,供仍在旧版本上的维护者参考。
3.2 编译与配置
编译(WITH_BLKIN依赖WITH_LTTNG,二者需同时开启):
./do_cmake -DWITH_LTTNG=ON -DWITH_BLKIN=ON从构建系统看,WITH_BLKIN=ON时会执行add_subdirectory(blkin/blkin-lib)(见 src/CMakeLists.txt),把 Blkin 的 ztracer 库编入构建。相应地,src/common/zipkin_trace.h 在WITH_BLKIN宏下会#include <ztracer.hpp>引入真实实现;未开启时则退化为全空的 stub(Trace、Endpoint所有方法均为 no-op,valid()恒为false),从而在关闭 Blkin 的构建中做到零开销。
配置:在ceph.conf中把以下选项设为true(均为bool、advanced、默认false):
| 配置项 | 默认值 | 含义 | 仓库配置位置 |
|---|---|---|---|
rbd_blkin_trace_all | false | 为所有 RBD 请求创建 blkin trace | rbd.yaml.in |
osd_blkin_trace_all | false | 为所有 OSD 请求创建 blkin trace | global.yaml.in |
osdc_blkin_trace_all | false | 为所有 Objecter(客户端侧请求转发层)请求创建 blkin trace | global.yaml.in |
3.3 源码结构:zipkin_trace.h与 span 传播
src/common/zipkin_trace.h 定义了追踪的核心数据结构与接口:
struct blkin_trace_info:三个int64_t字段trace_id、span_id、parent_span_id,并配套encode/decode,使其可以随 Ceph 的消息(buffer::list)跨进程序列化传递——这正是链路跨节点传播的基础;ZTracer::Trace:提供init()(初始化 span)、keyval()(记录整数/字符串键值对,对应zipkin:keyval_integer/zipkin:keyval_string探针)、event()(记录事件,对应zipkin:timestamp探针)等方法;ZTracer::Endpoint:表示服务端点(名称、IP、端口)。
3.4 调用链示例:Objecter 侧如何打 span
以客户端 Objecter 为例,src/osdc/Objecter.cc 在组装 MOSDOp 消息前有如下逻辑:
if (!op->trace.valid() && cct->_conf->osdc_blkin_trace_all) { op->trace.init("op", &trace_endpoint); }即:当osdc_blkin_trace_all = true且该 op 尚未携带 trace 时,以服务名"op"和本地 endpoint 初始化一个新的 span。随后在发送消息时:
if (op->trace.valid()) { m->trace.init("op msg", nullptr, &op->trace); }把父 span 挂到消息上随请求发出(src/osdc/Objecter.cc),从而让 OSD 端能延续同一trace_id生成子 span。期间还会记录"op submit"、"post op complete"、"osd op reply"等关键事件(src/osdc/Objecter.cc、src/osdc/Objecter.cc、src/osdc/Objecter.cc)。可见osdc_blkin_trace_all打开的是一条"客户端发起 → 消息携带 → OSD 处理 → 回复"的完整链路。
3.5 测试 Blkin:完整操作流程
假设 Ceph 尚未运行、且你已编译出带 Blkin 支持但未安装的版本,按文档在src目录用vstart.sh启动(OSD=3 MON=3 RGW=1表示 3 个 OSD、3 个 MON、1 个 RGW):
OSD=3 MON=3 RGW=1 ../src/vstart.sh -n -o "rbd_blkin_trace_all" lttng list --userspace此时lttng list --userspace会看到每个进程都注册了 Blkin 的 zipkin 探针,例如:
UST events: ------------- PID: 8987 - Name: ./ceph-osd zipkin:timestamp (loglevel: TRACE_WARNING (4)) (type: tracepoint) zipkin:keyval_integer (loglevel: TRACE_WARNING (4)) (type: tracepoint) zipkin:keyval_string (loglevel: TRACE_WARNING (4)) (type: tracepoint) lttng_ust_tracelog:TRACE_DEBUG (loglevel: TRACE_DEBUG (14)) (type: tracepoint) PID: 8407 - Name: ./ceph-mon zipkin:timestamp (loglevel: TRACE_WARNING (4)) (type: tracepoint) zipkin:keyval_integer (loglevel: TRACE_WARNING (4)) (type: tracepoint) zipkin:keyval_string (loglevel: TRACE_WARNING (4)) (type: tracepoint) lttng_ust_tracelog:TRACE_DEBUG (loglevel: TRACE_DEBUG (14)) (type: tracepoint) ...下一步是先停掉 Ceph,以便 tracepoint 能被 LTTng 会话启用(避免进程运行期间动态库绑定影响事件启用):
../src/stop.sh创建 LTTng 会话并启用 zipkin 相关事件:
lttng create blkin-test lttng enable-event --userspace zipkin:timestamp lttng enable-event --userspace zipkin:keyval_integer lttng enable-event --userspace zipkin:keyval_string lttng start重新启动 Ceph:
OSD=3 MON=3 RGW=1 ../src/vstart.sh -n -o "rbd_blkin_trace_all"确认集群状态正常:
ceph status然后通过rados做一轮"写入 → 列出 → 定位 → 读回 → 校验 → 删除"的完整对象操作:
ceph osd pool create test-blkin rados put test-object-1 ../src/vstart.sh --pool=test-blkin rados -p test-blkin ls ceph osd map test-blkin test-object-1 rados get test-object-1 ./vstart-copy.sh --pool=test-blkin md5sum vstart* rados rm test-object-1 --pool=test-blkin也可以直接使用 examples/librados 中的示例程序,或用rados bench制造持续负载。
停止追踪并查看采集结果:
lttng stop lttng view输出形如(每条记录都带有trace_id、span_id、parent_span_id三件套,这正是还原链路的依据):
[15:33:08.884275486] (+0.000225472) ubuntu zipkin:timestamp: { cpu_id = 53 }, { trace_name = "op", service_name = "Objecter", port_no = 0, ip = "0.0.0.0", trace_id = 5485970765435202833, span_id = 5485970765435202833, parent_span_id = 0, event = "osd op reply" } [15:33:08.884614135] (+0.000002839) ubuntu zipkin:keyval_integer: { cpu_id = 10 }, { trace_name = "", service_name = "Messenger", port_no = 6805, ip = "0.0.0.0", trace_id = 7381732770245808782, span_id = 7387710183742669839, parent_span_id = 1205040135881905799, key = "tid", val = 2 } [15:33:08.884616431] (+0.000002296) ubuntu zipkin:keyval_string: { cpu_id = 10 }, { trace_name = "", service_name = "Messenger", port_no = 6805, ip = "0.0.0.0", trace_id = 7381732770245808782, span_id = 7387710183742669839, parent_span_id = 1205040135881905799, key = "entity type", val = "client" }解读要点:
zipkin:timestamp记录的是"某个事件发生"的时间点与 span 归属(如 Objecter 收到osd op reply);zipkin:keyval_integer/zipkin:keyval_string记录附加键值(如tid、entity type = client),丰富 span 上下文;- 时间戳前的
(+0.000xxx)是相对上一条记录的时间增量,可用于估算阶段时延。
四、用 Zipkin 可视化 Blkin 追踪结果
4.1 安装 Zipkin
Blkin 的价值在于可视化。Zipkin 同时作为 tracepoint 收集器与 Web 服务运行:可执行 jar 在9410端口启动 collector,在9411端口提供 Web 界面。
方式一:下载并运行 jar
git clone https://github.com/openzipkin/zipkin && cd zipkin wget -O zipkin.jar 'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec' java -jar zipkin.jar方式二:Docker 镜像
docker run -d -p 9411:9411 openzipkin/Zipkin4.2 使用 babeltrace-zipkin 把 LTTng 数据送入 Zipkin
babeltrace-zipkin 项目负责读取 Blkin 产生的 LTTng trace,并通过 scribe 协议发送给 Zipkin collector:
git clone https://github.com/vears91/babeltrace-zipkin cd babeltrace-zipkin发送命令的格式为:
python3 babeltrace_zipkin.py ${lttng-traces-dir}/${blkin-test}/ust/uid/0/64-bit/ -p ${zipkin-collector-port(9410 by default)} -s ${zipkin-collector-ip}其中-p指定 Zipkin collector 端口(默认 9410),-s指定 collector 的 IP。实际示例:
python3 babeltrace_zipkin.py ~/lttng-traces-dir/blkin-test-20150225-160222/ust/uid/0/64-bit/ -p 9410 -s 127.0.0.1注意~/lttng-traces-dir/...中的目录名blkin-test-<时间戳>由lttng create blkin-test自动生成,ust/uid/0/64-bit/是 UST trace 在 trace 目录下的标准存放路径,请以实际目录为准。
4.3 在 Zipkin Web 上查看链路
浏览器访问 Zipkin Web 界面:
http://${zipkin-collector-ip}:9411点击"Find traces",即可看到按trace_id聚合的请求链路。Zipkin 会以时间轴形式展示trace_name(如"op")、service_name(如Objecter、Messenger、OSD 等)以及各 span 的父子关系与耗时,从而直观地定位请求在哪个阶段出现瓶颈。
五、注意事项与后续方向
- 版本与弃用状态:Blkin 在 Squid 版本中被标记为弃用并将被移除,新项目请评估该约束;LTTng 事件追踪(第二节内容)不受影响。当前仓库配置中还保留了
jaeger_tracing_enable等新一代追踪选项(见 global.yaml.in),可作为迁移/后续方向的参考。 - 编译与运行环境必须一致:编译时开启
WITH_LTTNG/WITH_BLKIN后,运行环境必须安装对应的 tracepoint 共享库(librbd-devel、librgw-devel、librados-devel),否则进程可能因缺少*.so而 coredump。 - 配置开关默认关闭:所有追踪相关配置项默认均为
false,无论编译是否开启,都需在ceph.conf(或 vstart 的-o注入)中显式开启,且建议只在排障窗口期开启,避免常驻性能开销。 - 调试闭环:
lttng list --userspace是确认探针是否注册的第一手段;lttng view输出的三件套(trace_id/span_id/parent_span_id)是人工校验链路是否完整的最快途径。若需程序化分析,可参照 src/tracing/README.md 使用 libbabeltrace 编写分析工具,或用 TraceCompass 生成火焰图。
参考路径速查
- 本文档源:doc/dev/blkin.rst
- tracepoint 定义与构建:src/tracing、src/tracing/CMakeLists.txt、src/tracing/osd.tp
- LTTng/函数插桩说明:src/tracing/README.md
- Blkin 追踪头文件:src/common/zipkin_trace.h
- Blkin 编译开关:src/CMakeLists.txt
- 配置项定义:src/common/options/global.yaml.in、src/common/options/rbd.yaml.in、src/common/options/rgw.yaml.in
- Objecter 端 span 传播:src/osdc/Objecter.cc
- vstart 本地集群脚本:src/vstart.sh
- 存储
- 分布式文件系统
- 对象存储
- 后端
- 高可用
【免费下载链接】ceph
Ceph is a distributed object, block, and file storage platform
相关推荐
终极指南:如何用CKAN一键管理你的坎巴拉太空计划模组
终极指南:如何用CKAN一键管理你的坎巴拉太空计划模组 你是否曾经因为坎巴拉太空计划(Kerbal Space Program)的模组管理而头疼?手动下载、版本
开发工具包管理器游戏开发Ceph 分布式追踪实践:基于 Jaeger 与 OpenTracing 的链路追踪集成指南
Ceph 分布式追踪实践:基于 Jaeger 与 OpenTracing 的链路追踪集成指南 本文是 Ceph 开发者指南系列中关于分布式追踪(Distribu
存储分布式文件系统对象存储后端高可用终极指南:如何快速实现Dubbo集成Zipkin全链路追踪
终极指南:如何快速实现Dubbo集成Zipkin全链路追踪 在分布式微服务架构中,全链路追踪是排查问题、优化性能的关键工具。Dubbo作为一款高性能、轻量级的分
后端RPC框架微服务服务注册发现
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考