资讯详情

资讯详情

Ceph RBD 工作负载回放工具 rbd-replay 完全指南:从轨迹采集到多客户端压测实战

Ceph RBD 工作负载回放工具 rbd-replay 完全指南从轨迹采集到多客户端压测实战【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址: https://gitcode.com/gh_mirrors/ce/cephrbd-replay 是 Ceph 提供的分布式块设备RBD工作负载回放工具它读取预先录制好的 RBD 访问轨迹trace在目标集群上以可调速度、可重映射镜像名的方式重新执行这些请求是容量规划、回归测试与性能对比的利器。读完本文你将掌握 rbd-replay 的全部命令行选项、配合 rbd-replay-prep 与 rbd-replay-many 的完整回放工作流并能理解其基于依赖图与多线程 Worker 的底层执行原理。一、工具定位Ceph RBD 回放工具链概览rbd-replay 是 Ceph 源码树中src/rbd_replay/目录下的一组工具之一整个回放工具链由三个命令组成分工明确工具职责源码/文档位置rbd-replay-prep将 LTTng 采集的原始 RBD 轨迹CTF 格式加工为回放文件rbd-replay-prep.cc、文档rbd-replay读取回放文件在集群上按原时序执行全部请求rbd-replay.cc、文档rbd-replay-many在多个客户端上并行回放同一工作负载各自对应独立镜像文档其中rbd-replay是核心执行器本文重点讲解。其构建配置位于 src/rbd_replay/CMakeLists.txt可执行文件安装到bin目录rbd-replay-prep依赖 babeltraceHAVE_BABELTRACE宏控制仅在该库可用时才构建。回放文件格式回放文件是二进制格式以固定横幅字符串rbd-replay-trace定义于 src/rbd_replay/ActionTypes.h开头后续是一系列编码后的 action 条目。Replayer读取时会通过is_versioned_replay()检测横幅是否存在以决定按带版本还是不带版本的旧格式解码见 src/rbd_replay/Replayer.cc。因此旧版本生成的未带横幅的回放文件也能被当前版本读取实现了向后兼容。二、命令用法与完整选项解析语法rbd-replay [ options ] replay_file其中replay_file是必选参数即由rbd-replay-prep生成的回放文件路径。若未指定程序会报错退出见 src/rbd_replay/rbd-replay.cc。选项总览选项含义默认值-c ceph.conf, --conf ceph.conf使用指定的 ceph.conf 配置文件替代默认的 /etc/ceph/ceph.conf 来确定启动时的 monitor 地址/etc/ceph/ceph.conf-p pool, --pool pool回放时交互的目标存储池rbd--latency-multiplier乘以请求之间的延迟inter-request latencies1--read-only只回放非破坏性请求读取类跳过所有写操作关闭--map-image rule添加一条把轨迹中镜像名映射到回放集群镜像名的规则可重复指定无--dump-perf-counters实验性在镜像被关闭之前将性能计数器perf counters转储到标准输出关闭下面逐项深入。-c / --conf指定集群配置默认情况下 rbd-replay 读取/etc/ceph/ceph.conf获取 monitor 地址等集群信息。在测试环境或使用非默认配置时通过该选项显式指定配置文件例如rbd-replay -c /path/to/my-ceph.conf workload1与大多数 Ceph 客户端工具一致该参数最终进入global_init初始化流程见 src/rbd_replay/rbd-replay.cc因此它也支持CEPH_ARGS环境变量等方式传递配置。-p / --pool指定目标存储池回放默认在rbd池中进行。需要覆盖默认池时rbd-replay --poolmybenchpool workload1一个值得注意的实现细节如果在命令行未显式指定池名Replayer::run()会尝试从配置项rbd_default_pool读取默认池见 src/rbd_replay/Replayer.cc读取失败才会报错——这意味着你还可以通过 ceph.conf 中的rbd default pool mypool来改变回放目标池而无需修改命令行。--latency-multiplier时间缩放控制回放节奏该参数是回放工具最具实用价值的控制旋钮用于整体缩放请求之间的间隔延迟--latency-multiplier1默认按录制时的原始时序回放真实还原负载节奏--latency-multiplier0所有请求间隔清零以最快速度打满集群——这正是压力测试的典型用法--latency-multiplier2等大于 1 的值放慢回放节奏可用于观察慢速/长时间运行下的稳定性。从源码看该值作用于每个 action 的依赖等待阶段Replayer::wait_for_actions()在等待前驱 action 完成后会计算dep.time_delta * m_latency_multiplier / 1000微秒的附加延迟并 sleep 至释放时刻见 src/rbd_replay/Replayer.cc其中time_delta是轨迹中记录的两个请求之间的纳秒间隔见 src/rbd_replay/ActionTypes.h 中Dependency结构的定义。在 src/rbd_replay/rbd-replay.cc 中该参数被解析为float并断言必须非负。--read-only只读安全回放开启后rbd-replay 只执行读取类请求所有写操作被短路跳过。这非常适合在生产环境或共享测试环境中验证读路径性能而不产生任何数据变更。源码中的处理逻辑非常清晰见 src/rbd_replay/actions.ccWriteAction仍然构造长度为length的零填充缓冲append_zero但仅在非只读模式才真正调用image-write()actions.ccAioWriteAction/AioDiscardAction在只读模式下直接remove_pending跳过实际 IO 调用actions.cc、actions.ccDiscardAction同样在只读模式下不执行image-discard()actions.ccOpenImageAction若轨迹中该镜像本就是以只读方式打开read_only标志或回放处于只读模式则调用rbd-open_read_only()actions.cc。--map-image镜像名映射安全替换回放目标该选项把轨迹中记录的镜像名可含快照映射到回放集群中实际存在的镜像名是在不改动轨迹文件的前提下复用同一工作负载的关键机制也是将录制环境与回放环境解耦的核心手段。规则格式为image1snap1image2snap2含义是把image1的snap1快照映射为image2的snap2。该选项可多次指定构成一张映射表。解析与查找逻辑位于 src/rbd_replay/ImageNameMap.ccparse_mapping()以分隔左右两侧支持用\转义字面等号ImageNameMap.cc两侧位置字符串按pool/imagesnap三元组格式解析规则详见 src/rbd_replay/rbd_loc.hpp/与均可省略斜杠和 at 号可用反斜杠转义例如rbd/vm1、vm、rbd\x/vm\/y1都是合法形式map()查表未命中则原样返回ImageNameMap.cc因此映射是可选的锦上添花不配置也不会报错在OpenImageAction执行时worker.map_image_name(name, snap_name)完成最终名称解析actions.cc。一个典型的安全用例把录自生产镜像prod_image的负载完整重放到测试镜像test_image上验证新版本或新硬件对既有负载的表现。--dump-perf-counters实验性的性能计数转储开启该选项后每次镜像关闭erase_image前以及回放结束时清空镜像缓存clear_images前rbd-replay 都会以 JSON 格式把 Ceph 上下文的性能计数器perf dump命令结果输出到标准输出见 src/rbd_replay/Replayer.cc 与 Replayer.cc。需要注意该功能目前标记为Experimental性能计数器的集合与含义可能在版本之间变化若同一镜像被多次打开/关闭或一次回放涉及多个镜像计数器会多次转储输出可能重复。三、从轨迹到回放完整工作流实战步骤一用 rbd-replay-prep 预处理原始轨迹rbd-replay 本身不消费 LTTng 原始轨迹需要先用rbd-replay-prep转换。其语法为rbd-replay-prep [ --window seconds ] [ --anonymize ] [ --verbose ] trace_dir replay_file其中trace_dir是 LTTng trace 目录典型路径形如workload1-trace/ust/uid/1000/64-bitreplay_file是输出回放文件。文档给出的示例rbd-replay-prep workload1-trace/ust/uid/1000/64-bit workload1该工具的选项见 rbd-replay-prep.cc 与 文档选项含义--window seconds相隔超过该秒数的请求被视为相互独立不建立依赖关系。默认 1 秒即窗口大小以纳秒为单位换算为1e9 * secondsrbd-replay-prep.cc--anonymize对镜像名与快照名做匿名化处理输出形如image0、snap0的脱敏名称rbd-replay-prep.cc--verbose将每个处理过的事件打印到控制台预处理时rbd-replay-prep通过 babeltrace 读取 CTF 格式事件流识别librbd:open_image_enter、librbd:read_enter、librbd:aio_write_enter、librbd:aio_complete_enter等事件rbd-replay-prep.cc将其转换为带依赖关系的 action 序列并序列化到输出文件。它会为每个线程自动插入StartThreadIO与StopThreadIO并补发隐式缺失的OpenImageIOrequire_image()rbd-replay-prep.cc。步骤二执行回放在目标集群上准备好 ceph.conf或使用-c指定、确保目标镜像存在后执行# 按录制节奏原速回放 rbd-replay workload1 # 压测零延迟全速回放 rbd-replay --latency-multiplier0 workload1 # 将轨迹中的 prod_image 映射到 test_image 后回放 rbd-replay --map-imageprod_imagetest_image workload1 # 组合使用指定池 只读 快照级映射 rbd-replay --poolbench --read-only \ --map-imageprod_imagesnap1test_imagesnapA workload1步骤三多客户端并行回放rbd-replay-many当需要模拟多 VM/多客户端并发场景时使用rbd-replay-many在多个主机上并行执行回放rbd-replay-many host-0 host-1 --original-imageimage -- -c ceph.conf replay.bin该命令等价于依次默认无间隔在每台主机上执行ssh host-0 rbd-replay --map-image imageimage-0 -c ceph.conf replay.bin ssh host-1 rbd-replay --map-image imageimage-1 -c ceph.conf replay.bin关键选项文档选项含义--original-image name轨迹中原始镜像名可含快照用于生成正确的镜像名映射--image-prefix prefix各客户端回放目标镜像的前缀默认取原始镜像名如--image-prefixfoo会依次映射到foo-0、foo-1……--exec programrbd-replay 可执行文件路径--delay seconds各客户端启动之间的间隔默认 0使用前提所有客户端都能访问集群配置与回放文件不会自动分发且目标回放镜像必须预先创建好。四、深入原理Replayer 与 Worker 的并发执行模型要真正用好 rbd-replay理解其执行模型至关重要。整体架构由Replayer与Worker两级组成见 src/rbd_replay/Replayer.hpp。线程规模与任务分发主程序按 CPU 核数自动决定并发度unsigned int nthreads boost::thread::hardware_concurrency(); Replayer replayer(2 * nthreads 1);见 src/rbd_replay/rbd-replay.cc。2 * nthreads 1是 action tracker动作完成记录器的个数——之所以取奇数是因为 action 按id % num_trackers哈希到不同的 tracker 上源码注释明确建议该值最好大于核数且为质数/奇数以降低哈希冲突Replayer.hpp。轨迹驱动的线程模型回放文件中的每条 action 都带thread_id。Replayer::run()顺序读取文件遇到StartThreadAction时创建新的Worker线程并启动Replayer.cc其余 action 按thread_id投递到对应 Worker 的有界缓冲区BoundedBuffer容量 100文件读完后join 所有 Worker随后清空镜像缓存Replayer.cc。这保证了轨迹中每个原始线程的请求都被同一个回放线程串行执行从线程维度还原原始并发结构。依赖图与延迟还原每个 action 携带Dependencies前驱列表Worker::run()的循环是action m_buffer.pop_back(); m_replayer.wait_for_actions(action-predecessors()); action-perform(*this); m_replayer.set_action_complete(action-id());见 src/rbd_replay/Replayer.cc。wait_for_actions()逐个等待前驱完成并取所有前驱释放时刻的最大值作为本 action 的释放时间——这正是请求间隔延迟的还原机制time_delta纳秒乘上latency_multiplier换算为微秒后叠加到前驱完成时刻Replayer.cc。异步 IO 与完成跟踪rbd-replay 支持同步与异步两类请求。异步请求AioReadAction等通过PendingIO跟踪action 执行时add_pending(io)IO 完成回调触发remove_pending(io)并标记 action 完成Replayer.cc。Worker 停止前会等待所有 pending IO 完成避免进程提前退出导致异步请求丢失。值得注意的细节AioWriteAction写入的数据是伪造的 1MB 循环填充数据create_fake_data()见 actions.cc因为轨迹只记录了请求的偏移与长度并不包含真实数据内容WriteAction则写入零填充缓冲。这意味着回放会真实产生写入流量并占用容量但数据内容与原始负载不同适合压测而非数据一致性校验。可支持的 action 类型轨迹文件中可能出现的 action 类型在 src/rbd_replay/ActionTypes.h 中完整定义枚举值Action说明0 / 1StartThread / StopThread线程生命周期管理2 / 3Read / Write同步读写4 / 5AioRead / AioWrite异步读写6 / 7OpenImage / CloseImage打开/关闭镜像8 / 9AioOpenImage / AioCloseImage异步打开/关闭镜像当前实现实际仍为同步源码注释标有 TODO10 / 11Discard / AioDiscard同步/异步裁剪未知或当前版本不支持的 action 类型会被Action::construct()静默跳过actions.cc保证向后兼容性。五、实战建议与注意事项压测前先验证回放文件用rbd-replay-prep --verbose观察事件转换结果确认动作序列符合预期再投入正式回放。善用--read-only与--map-image组合在共享或生产环境回放时强烈建议--read-only配合镜像映射既验证读路径又零风险。--latency-multiplier0的语义全速压测时写请求仍会真实写盘注意目标池的容量与 OSD 负载。多客户端回放注意预置镜像rbd-replay-many不会分发配置和回放文件也不会自动创建镜像各客户端的foo-0、foo-1等目标镜像需提前用rbd create创建。性能计数器输出是实验性的若依赖该输出做分析请固定 Ceph 版本并先在小规模回放上验证输出格式。六、相关文档与源码索引工具手册页rbd-replay、rbd-replay-prep、rbd-replay-many、rbd源码入口rbd-replay.cc、rbd-replay-prep.cc核心执行逻辑Replayer.cc、Replayer.hpp、actions.cc、actions.hpp数据格式与映射ActionTypes.h、ImageNameMap.cc、rbd_loc.hpp构建配置src/rbd_replay/CMakeLists.txtrbd-replay依赖 librbd、librados、rbd_replay、ceph-commonrbd-replay-prep额外依赖 babeltrace【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址: https://gitcode.com/gh_mirrors/ce/ceph创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →