试试SPDK的trace

作者简介:

刘孝冬 Intel 高级软件工程师

专注于开源存储SPDK及ISA-L软件的开发。


曾梦想仗剑走天涯,看看这繁华的世界。刚推门迈了几步,后台拦住你,“你的进程怎么把IO搞丢了!”
年少的心总有些轻狂,你以为打几句LOG就能揪出这BUG。可是,这次把源码打的千疮百孔,也没有打出个名堂。
每一刻难过的时候,别光想着打LOG看LOG,想想是不是有个叫trace的工具还没用?

试试SPDK的trace

1

SPDK Trace

介绍

软件开发人员需要了解程序运行时的行为,以便在出现故障时做代码调试,或性能分析时查找热点。通常当日志所记录的信息无法提供足够细节、无法包含足够类型时,软件跟踪技术(Trace)就会被用来记录特定相关类型事件的发生和相应上下文信息,并将记录内容写入到指定文件内,待后续分析使用。

SPDK中有一个跟踪框架*SPDK tracing,用于在运行时捕获底层事件信息。跟踪点(Tracepoint)提供了一个在运行时可行的高性能跟踪机制。它们被实现为共享内存中的环形缓冲区,这样在SPDK进程向环形缓冲区写入记录时,其他进程也可以访问缓冲区上的内容。

试试SPDK的trace

Figure1 Diagram of SPDK trace utility

SPDK内多个应用和函数库已经使用SPDK tracing的跟踪点进行监测,以支持对性能和进程崩溃进行分析。不过,目前对SPDK tracing 框架的规范化和相应文档还在进行中。

2

如何使能SPDK的

trace功能

默认情况下,即使在configure时未使能debug flag,SPDK的trace库libspdk_trace.a是会被编译链接到相应SPDK应用中。但tracing功能在运行时是默认关闭的。若要开启SPDK tracing功能,有两种方法,一是在启动SPDK应用时,通过--tpoint-group-mask (-e)参数指定要开启tracing功能的模块;或者通过SPDK trace RPC方法来开启或关闭某些模块的tracing功能。

Tracing功能被使能后,一旦相应事件一发生,SPDK进程就会准备在它对应的trace文件中写入相应事件信息。目前SPDK应用的trace文件会写入到/dev/shm下,它以SPDK应用名称,加“_trace.pid”,再加应用的进程ID号,如bdev_svc_trace.pid67924。

3

SPDK的trace

工具

SPDK目前有两个trace相关的工具,spdk_trace (位置app/trace目录下)和spdk_trace_record  (位于app/trace_record目录下)。其中,spdk_trace_record用于转储share memory下trace文件到其他位置。Spdk_trace用于查看trace文件内容,以便进行相关分析。

试试SPDK的traceFigure2 usage of spdk_trace

spdk_trace的参数可分为两类,一类是关于指定要分析的trace文件,另一类是定义显示内容。指定trace文件可以直接使用”-f”参数, 后接某个trace文件的路径;也可根据当前SPDK应用名称及进程号,让spdk_trace按照默认规则去目录”/dev/shm”下寻找对应的trace文件。很多情况下,SPDK应用运行在不止一个CPU core上,而且IO通常是由一个CPU core 运行到完成(run-to-completion),所以为了减少trace分析的记录输出量,可以使用”-c”参数指定仅仅分析某一个CPU core上的trace 记录。

Spdk_trace根据事件的不同,每个事件的输出内容会略有不同。从左到右大致的格式遵循:

1 <CPU Index>

2 <Event Occur Time in us>

3 <Group Type Prefix>+<Poller ID>

4 <Specific Type Info>

5 <Event ID> 

6 <Completion Time in us>

例如一个Core 0上Bdev IO的开始与结束的输出:

试试SPDK的traceFigure3 Output of spdk_trace for bdev IO

4

Hands-on SPDK trace

这里用SPDK Bdev的一个测试应用 bdev_svc(位于test/app/bdev_svc/), 简要运行一个tracing Bdev IO的例程。

1.启动bdev_svc, 并获取其进程ID

./test/app/bdev_svc/bdev_svc

2.使能Bdev的tracing

./scripts/rpc.py enable_tpoint_group bdev

3.创建基于内存的Bdev

./scripts/rpc.py bdev_malloc_create -b TestBdev 1024 4096

4.将该Bdev 导出为Kernel的NBD设备,并向Bdev发起IO请求

./scripts/rpc.py start_nbd_disk TestBdev /dev/nbd0

fdisk -l /dev/nbd0

./scripts/rpc.py stop_nbd_disk /dev/nbd0

5.查看产生的trace记录

./app/trace/spdk_trace -s bdev_svc -p 72791

试试SPDK的traceFigure4  SPDK trace sample output

6.查看Core 1上的trace记录,可以看到Core0上没有任何event。(因为NBD仅仅运行在Master Core, 即Core 0上)

./app/trace/spdk_trace -s bdev_svc -p 72791 –c 1

7.查看Core 0上的trace记录

./app/trace/spdk_trace -s bdev_svc -p 72791 –c 0

可以看到SPDK trace记录了NBD 的发起IO。每个IO都被唯一标识,由于Bdev目前仅仅设置了两个事件,即BDEV_IO_START和BDEV_IO_END;而且仅仅Bdev的tracing功能被开启, 所以此例程里,记录事件的类型仅有这两种。在SPDK 的NVMe over RDMA, NVMe over TCP, FTL以及ISCSI和Blobfs里面都有更丰富的事件类型。在SPDK网址的documentation中有关于NVMe over RDMA Target的一些trace细节,可参考https://spdk.io/doc/nvmf_tgt_tracepoints.html

END

试试SPDK的trace

    转载须知