blktrace
是一个强大的 Linux 工具,用于跟踪块设备的 I/O 操作。通过它,你可以捕获和分析块设备 I/O 请求的详细信息,比如队列时间、调度延迟、完成时间等。以下是 blktrace
的详细用法和常见分析场景。
1. 什么是 blktrace?
blktrace
是一个内核级工具,用于实时跟踪块设备的 I/O 请求。它提供了对以下信息的深入分析能力:
I/O 请求:读、写、同步、异步等。
调度过程:请求何时进入队列、被调度、发往设备。
延迟分析:队列时间、调度延迟、完成时间等。
2. 安装 blktrace
2.1 安装命令
在大多数 Linux 发行版中,你可以直接通过包管理器安装 blktrace
。
Debian/Ubuntu
bash
复制
sudo apt update
sudo apt install blktrace
RHEL/CentOS/Fedora
bash
复制
sudo yum install blktrace
# 或使用 dnf
sudo dnf install blktrace
检查安装
安装完成后可以通过以下命令验证:
bash
复制
blktrace --help
3. blktrace 的基本用法
3.1 跟踪块设备
要跟踪一个块设备的 I/O 操作,使用以下命令:
bash
复制
sudo blktrace -d <设备路径>
示例:
bash
复制
sudo blktrace -d /dev/sda
-d
:指定要跟踪的块设备(如/dev/sda
、/dev/nvme0n1
)。输出会显示实时的 I/O 事件信息。
3.2 保存跟踪数据到文件
如果需要将跟踪数据保存以便后续分析,可以使用 -o
选项:
bash
复制
sudo blktrace -d /dev/sda -o output
-o <文件名前缀>
:保存跟踪数据,生成多个文件(如output.blktrace.0
)。如果设备有多个队列或 CPU 核心,会为每个队列生成一个文件。
3.3 限制跟踪时间
你可以使用 -w
选项指定跟踪时长(单位为秒):
bash
复制
sudo blktrace -d /dev/sda -o output -w 10
该命令会对
/dev/sda
进行 10 秒的跟踪,并将数据保存到文件。
3.4 实时查看 I/O 事件
如果希望实时查看块设备的 I/O 请求,可以直接运行:
bash
复制
sudo blktrace -d /dev/sda
4. 分析 blktrace 的输出数据
blktrace
生成的原始数据不易阅读,需要配合 blkparse
工具对其进行解析。
4.1 使用 blkparse 解析数据
bash
复制
sudo blkparse -i output
-i
:指定输入文件的前缀(如output
)。输出的解析内容示例:
plaintext
复制
8,0 0 1 0.000000000 123 Q R 123456 + 8 [app] 8,0 0 2 0.000001000 123 G R 123456 + 8 [app] 8,0 0 3 0.000002000 123 I R 123456 + 8 [app] 8,0 0 4 0.000003000 123 C R 123456 + 8 [app]
字段解释
事件类型
4.2 使用 btt(Block Trace Tools)生成统计信息
btt
是一个分析工具,可以基于 blkparse
的输出生成统计摘要。
示例:
bash
复制
sudo blkparse -i output -o output.parsed
sudo btt -i output.parsed
输出示例:
plaintext
复制
Total Q2Q time: 123.45 ms Total IOs completed: 1000 Read IOs: 600 Write IOs: 400 Average Q2C time: 1.23 ms
Q2Q time:队列之间的时间。
IOs completed:完成的 I/O 请求数量(区分读写)。
5. 常见场景和用法
5.1 分析 I/O 请求延迟
通过 blktrace
捕获 I/O 请求的生命周期,并解析其延迟。例如:
bash
复制
sudo blktrace -d /dev/sda -o output -w 5
sudo blkparse -i output
结果中可以看到:
队列时间(
Q
到G
的时间差)。调度延迟(
G
到I
的时间差)。完成时间(
I
到C
的时间差)。
5.2 分析块设备的读写模式
通过解析结果,可以分析设备的读写分布:
bash
复制
sudo blkparse -i output | grep -E ' W | R '
R
:表示读操作。W
:表示写操作。
5.3 分析队列性能
通过 btt
生成的统计信息,可以分析队列性能。例如:
bash
复制
sudo btt -i output.parsed
队列延迟(
Q2Q
、Q2C
)可以用来判断设备或调度器的性能瓶颈。
5.4 实时跟踪设备 I/O
如果需要实时监控块设备的 I/O 请求,可以直接使用:
bash
复制
sudo blktrace -d /dev/sda
6. 注意事项
权限要求:
blktrace
需要管理员权限(sudo
),因为它直接访问内核的块设备层。
性能开销:
跟踪块设备的操作会产生一定的系统开销,尤其是在高负载场景下,可能对性能有轻微影响。
设备支持:
确保目标设备支持块设备跟踪(如普通硬盘、SSD、NVMe 等),某些虚拟设备(如 loop 设备)可能不支持。
内核支持:
blktrace
依赖于 Linux 内核的块层跟踪机制,确保内核版本足够新(大多数现代发行版都支持)。
7. 总结
blktrace
是一个强大的工具,适合用于:分析存储设备的性能问题。
调试 I/O 延迟和队列行为。
优化存储系统的读写模式。
常见用法:
实时跟踪:
sudo blktrace -d /dev/sda
保存数据:
sudo blktrace -d /dev/sda -o output -w 10
解析数据:
sudo blkparse -i output
生成统计:
sudo btt -i output.parsed
通过灵活使用 blktrace
、blkparse
和 btt
,可以深入了解存储系统的 I/O 行为,帮助优化性能并解决瓶颈问题。
/root fio --group_reporting --name=fiotest -filename=/mnt/data/testfile --rw=randread --size=1G --bs=4k --direct=1 --numjobs=1 --ioengine=io_uring --iodepth=1
fiotest: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=io_uring, iodepth=1
fio-3.33
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=34.0MiB/s][r=8696 IOPS][eta 00m:00s]
fiotest: (groupid=0, jobs=1): err= 0: pid=10482: Fri Jun 13 11:10:28 2025
read: IOPS=8690, BW=33.9MiB/s (35.6MB/s)(1024MiB/30165msec)
slat (usec): min=33, max=1463, avg=42.62, stdev= 9.46
clat (nsec): min=471, max=2890.4k, avg=71106.22, stdev=16524.54
lat (usec): min=76, max=2952, avg=113.73, stdev=19.36
clat percentiles (usec):
| 1.00th=[ 53], 5.00th=[ 57], 10.00th=[ 64], 20.00th=[ 65],
| 30.00th=[ 67], 40.00th=[ 68], 50.00th=[ 70], 60.00th=[ 71],
| 70.00th=[ 72], 80.00th=[ 75], 90.00th=[ 81], 95.00th=[ 90],
| 99.00th=[ 130], 99.50th=[ 159], 99.90th=[ 231], 99.95th=[ 273],
| 99.99th=[ 449]
bw ( KiB/s): min=30096, max=37096, per=100.00%, avg=34769.60, stdev=1205.79, samples=60
iops : min= 7524, max= 9274, avg=8692.40, stdev=301.45, samples=60
lat (nsec) : 500=0.01%, 750=0.01%, 1000=0.01%
lat (usec) : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.38%
lat (usec) : 100=96.90%, 250=2.64%, 500=0.06%, 750=0.01%, 1000=0.01%
lat (msec) : 4=0.01%
cpu : usr=1.21%, sys=44.63%, ctx=262123, majf=0, minf=11
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=262144,0,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=1
Run status group 0 (all jobs):
READ: bw=33.9MiB/s (35.6MB/s), 33.9MiB/s-33.9MiB/s (35.6MB/s-35.6MB/s), io=1024MiB (1074MB), run=30165-30165msec
评估一个存储系统,主要从功能,性能,可靠性,稳定性,可用性几个角度考虑。
存储不仅仅局限于文件存储,通常还包含块,对象。现在成熟的商业/开源存储除了通过传统的文件存储外,还提供了更多额外的功能以及特性,业内一般称为软件定义存储(SDS)。
常见存储架构/分层模型
This content is only supported in a Feishu Docs
第一层一般是接入层,负责实现各类协议,不处理实际的IO,只做协议转接,用于兼容和实现各类功能。主要分为4大类:
文件存储,一般为fuse(提供posix接口),内核文件系统,NFS/SMB(提供网络共享协议)等,
块存储,一般为ISCSI,NBD,NVMEOF等
对象存储,一般为amazon S3
lib/api接入,直接接入存储api,避免其他内核开销(如fuse),一般性能最好,但需要应用适配,也会使存储与业务耦合在一个进程内,彼此影响。
通过对外实现这些协议,这个存储就具备了常见的文件,块,对象服务。这些接口不一定需要存储自身实现,通常也可以接入其他开源服务来实现,例如存储不一定需要实现NFS,而采用nfs ganesha,通过在nfs ganesha内接自身的api适配即可,即协议本身的实现交由外部来做,又比如ISCSI,可以采用tgtd,tcmu等实现。实际上目前这些开源的协议本身都支持这种扩展的IO适配,存储自身只需要将自己的API接入适配即可。
接入层主要是兼容问题,底层存储能否提供足够的特性支持以支持这些不同协议的功能需求。
Fuse, 内核fs,api都是本地接入,主要区别在:
fuse灵活,实现在用户态,因此IO需要额外的上下文切换,性能相对较差。这个性能差是针对较差的CPU以及需要低us级延迟的存储而言的。 一般而言机械盘,使用fuse没有性能损失,机械盘为ms级。SSD主要表现在低深度时性能有所下降(IO路径的拉长),但在高并发时,性能可能并不会下降在CPU足够的情况下。fuse性能测试这里测试了一个基于本地ext4的fuse性能,
对比裸盘,性能损耗其实主要发生在ext4上,单深度对比ext4有所下降。但多深度时,性能并未下降,但需要额外的CPU开销。内核fs, 一般提供内核fs(如cephfs)是为了消除fuse切换的损耗,同时避免api接入的适配问题。但内核fs可维护性较差,对健壮性要求也更高
Api, 性能最好,内核fs这一层上下文切换也可以省略
第二层IO栈,这里实现存储自身的各种功能。如快照,cache,副本,分片,元数据,IO读写,以及存储自身的任务,如修复,数据同步等。这里也是不同存储最大的区别所在,这一层 可以继续细分为不同的架构。
一个比较大的区别是,是否存在元数据中心。无元数据中心的存储对于大量的文件的元数据操作会非常耗时,如ls所有的目录,通常需要遍历所有的节点所有的结构,并对结果进行合并,但好处是没有元数据中心限制,理论上可以无限横向扩展。是否存在元数据中心很大程度上决定了存储的实现以及限制。
通常IO实现层偏客户端层,即靠近IO发起侧,里面一些功能根据实现也可以放到第三层IO后端层处理,如锁等,主要解决数据处理以及数据路由问题。数据处理如对数据进行分片,将数据写入多份,路由问题则解决数据的位置,即数据实际存储在哪里(对应哪一个IO后端),如可能在别的机器。
第三层IO实际后端存储,是最终实现数据存储的地方,通常而言是实际的块设备如磁盘,或者文件系统,当然也有继续接其他类型的存储,例如后端存储再接iscsi,nfs,fuse等将IO丢给下一级存储处理。存储后端一般管理这台机器上的所有可用于存储的设备。
本地的文件系统也大致符合这个分层模型,即接入层是VFS,而实现层是具体的文件系统,IO后端则为真实的块设备。
对于分布式存储而言,接入层会更多,实现层的功能也更复杂,IO后端通常会直接接入本地文件系统或者裸块设备。
评估与测试
性能
评估指标:iops,吞吐,海量小文件(元数据处理),延迟,混合读写,并发度。指标之间并不是完全孤立的
主要测试工具:fio
评估对象:单盘,多盘(集群,存储池),即分别对单盘组成的存储,以及多块磁盘组成的存储进行评估测试。
注意性能评估一般指特定场景下的性能,即可以认为是该场景下的最好性能,这个性能并不代表实际使用场景的性能,因为实际的系统是多个因素下的共同作用结果,实际场景的性能一般采用业务测试办法。而这里主要做一个基准测试来了解存储的上限。
注意事项
电源开启性能模式,必要时需要锁cpu频率
NVME集群性能可能无法测出上限,由于单块pcie 5.0x4 NVME已经可以达到10G+/s,百万IOPS(如 三星pm1743,最大顺序读14G/s,随机读IOPS可达250W/s),而目前较广泛的普通的pcie nvme读也有7G/s左右,100W+ IOPS。特别是多块nvme组成集群时,其物理吞吐甚至超过了一些内存,测试这一类性能时,对cpu/内存本身硬件有较高的要求,同时一般需要采用io_uring poll模式/spdk测试,配合cpu,numa bind,zero copy等相关调优。
磁盘cache影响,这里的cache指的是磁盘本身的cache而非内存cache,性能测试本身采用DIRECT IO绕开内存cache。通常HDD的cache为MB级别,因此对性能测试影响不大,因为很快就会被填满,且HDD性能瓶颈都在机械盘本身。而SSD除了DRAM缓存可能还有SLC缓存, SATA SSD可能有GB级别的缓存,NVME更是可能有数十GB缓存。这可能会使测试的出来的数据不稳定,在缓存没满前,表现出非常高且平滑的性能,而cache满了后性能下降且抖动。
io引擎一般采用libaio或者io_uring,避免采用psync引擎带来的线程开销,同时采用direct io模式测试。
对于NUMA系统,需要注意CPU/内存的调度,避免IO在不同的NUMA节点间切换,通常可以使用numactl控制,或者fio自带的cpus_allowed, numa_cpu_nodes,numa_mem_policy等参数
设置正确的IO调度器,通常而言,机械盘采用deadline,SSD采用none, NVME采用none/kyber。
IOPS
主要用于评估存储的随机IO处理能力,一般而言评估IOPS采用4k块大小。通常需要测试磁盘本身的性能(即裸硬件最大性能,硬件标榜的性能),随后在测试部署存储系统后的性能,以及作为对比。
测试方式:单盘大文件,多盘多个大文件。并且文件需要预分配(或者预写)。使用预分配大文件是为了防止存储对于元数据处理的干扰。
需要从以下维度评估:
单深度随机IO,可以反映存储处理一个完整IO链的延迟,该延迟是存储的上限,即该指标是存储系统处理IO时的最小延迟。
多深度随机IO,常用的深度为4/8/16/32/64/128,分别进行测试。
最大深度随机IO,随着深度的增加,IOPS不再提升,甚至反而可能因为竞争导致性能下降。最终该最大性能即在该系统下的存储最大性能(注意,此时系统的性能瓶颈也可能不是存储本身,也可能是CPU,内存等)
通过上面的测试,我们可以获取到正常存储处理IO时的最小延迟,以及最大的IO队列,以及个个维度下粗略IOPS,延迟情况。
需要评估随即读,随机写,混合读写情况。
吞吐
主要评估存储的顺序IO吞吐处理能力,一般而言评估吞吐采用64K/128k块大小。与IOPS类似,通常需要测试磁盘本身的性能 ,随后在测试存储系统后的性能,以及作为对比。
评估方式同IOPS。
评估维度:
一般而言测试单深度,以及最大吞吐即可,因为存储/内核/硬件一般会对顺序IO进行合并。延迟指标对于吞吐而言不是大。
同样需要评估顺序读,顺序写,混合读写情况。
小文件
海量小文件对于存储而言是一个很大的挑战,不同的文件系统本身实现的侧重点不同,一些文件系统专门设计用来处理海量小文件,一些文件系统在在设计时就不适合处理大量小文件。
通常用于评估存储的元数据处理能力, 可以区分为获取,修改类。
需要从以下维度评估:
不同文件量级
少量小文件,< 1w
常规数量的小文件,< 100w
海量小文件:千万-亿级+。
op/s, 指每秒完成的元数据操作次数
延迟,指每个元数据操作的平均延迟
获取类通常包含以下操作:
文件属性的获取,目录属性获取,目录文件遍历,扩展属性的获取等。
修改类通常包含以下操作:
文件属性的设置,目录/文件的创建,文件/目录删除, 扩展属性的设置/删除,fallocate空间分配,link链接文件操作等
一般而言存储(内核)会尽量采用元数据cache,因此内核的内存cache策略对于文件系统元数据测试有比较大的影响,相关的cache选项如下
测试分为2种,不带entry cache,以及带entry cache,设置对应vm.vfs_cache_pressure,此外,一些文件系统本身(如fuse)提供类似于entry cache, cache timeout等相关的参数来控制元数据的缓存。
需要分别测试类似与获取/修改/混合场景。
测试方式:
fsstress
自行编写程序测试
常用场景测试,tar解压目录/cp目录等
延迟
延迟通常用于评估小块随即IO,以及元数据操作延迟,正如上面提到。除了平均延迟外,还需要额外关注95%, 99%延迟,长尾延迟情况。即延迟抖动情况,如果延迟抖动较厉害,说明存储存在部分路径阻塞导致IO抖动,会造成存储看起来不稳定的情况。长尾IO延迟可能导致应用卡顿、IO超时等问题,尤其是在高并发或大规模数据场景下,可能会造成连锁反应。
造成延迟不稳定的原因可能很多,常见的如资源竞争,队列分布不均,调度,numa,硬件磨损,SSD缓存,FLT层因素,SSD GC等等。
观测:fio结果, iostat, blktrace等,本地的文件系统可能没有提供元数据的延迟信息,可能需要自行编写
功能
从大类上分,目前存储主要分为文件存储,块存储,对象存储。每种存储有自己的适用场景。以及部分场景可能要求使用某类存储,例如操作系统需要块存储来提供磁盘服务。
除了提供传统的存储功能外,一般存储还需要提供其他额外的功能, 由于其在存储层实现会带来较好的性能,以及部分功能需要hold io,io fence这些只能在存储层实现。常见的功能如快照,quota,副本,分片等。
功能的评估主要看目前主流的存储提供的功能,其可能带来的影响以及一些实现上的问题。
目前我们的存储额外功能基于底层文件系统提供,这会带来不同的文件系统体验不一致,并且无法统一(因为有些功能只能在存储层实现),需要各自管理。
传统存储功能
文件存储
对于文件系统而言,主要测试posix兼容性,特别是对于nfs/samba等此类网络存储。
测试方式:pjdfstest
一般而言主要的不兼容接口集中在:flock,符号链接、扩展属性,稀疏文件,fallocate,lseek(SEEK_HOLE/SEEK_DATA)。
块存储
目前用的比较多一般为iSCSI,通常测试SCSI命令的兼任性,对于NVMEof,则测试nvme的兼容性,此外nbd也是使用较多的块设备协议之一。
对象存储
Amazon s3接口的兼容性
路由/数据分布/存储策略
也叫storage class,即指定存储位置。例如由一个SSD和HDD组成一个集群,显而易见的存储策略应该是,元数据,小文件,以及部分需要频繁访问的数据存放在SSD上,这样使用较低的成本即可带来更好的性能与体验。
一般而言该功能不会对存储造成其他额外的影响。
quota
配额,即对目录等进行空间,文件数量等限制。通常配额对目录深度较深时可能存在性能影响。
副本
常见的副本机制包括复制,ec等。副本用于提升数据的可靠性与可用性,某种程度上可能提升或降低性能。
副本隐含一个重要的机制,即副本一致性。目前采用底层的raid,因为是单节点,不存在网络分区的情况,且IO都必须经过同一个内核,因此可以认为这是一个存在中心节点的分布式存储,且通信是可靠的,理论上来说只要处理好异常事务,那么一致性应该不是问题。
基于raid的副本较大的问题在于副本的对象是磁盘级的,无法对副本数量做细粒度的控制,也对副本磁盘有大小要求。大部分现代存储支持对不同的目录/文件或者子卷设置不同的副本数满足同一个存储池上不同的副本需求。因为副本不基于磁盘,对磁盘的大小也没有特殊的要求。
分片/条带
即将数据切片存储,因为可以利用多个磁盘,因此对读写性能是提升的,同时也使得单文件可以突破单个磁盘的大小限制。但分片后的数据一般存在多个磁盘中,一个磁盘损坏可能导致所有数据不可用,因此一般分片会搭配副本使用。
快照
快照通常用于实现数据回滚,以及文件的lazy copy,链接克隆等。
通常分为COW以及ROW快照,ROW快照对写友好,COW快照对读友好。
目前业界一般采用COW快照,快照的层数对COW快照几乎没有影响,但存在IO放大问题。ROW快照因为是增量快照,存在回溯读的问题,快照链越深,读性能越差,因此一般需要附带剪枝分裂等,并且还需要额外的快照合并功能,实现起来较为复杂。COW一般对元数据有要求,而对于无元数据中心节点的存储一般采用ROW快照较多。
快照对读写都存在一定的性能影响。
CDP/备份
普通的备份一般可以通过外部实现,而CDP则需要基于存储自身实现,CDP是一种持续的备份,一般通过iolog实现,即对数据变更的日志记录,这样便可以通过回放,使数据恢复到任意时间点。
CDP对会产生大量的数据,且对性能造成一定的影响。
压缩/去重
分为离线压缩,去重,以及在线压缩去重。一般通过块级或者文件级指纹进行压缩去重,在线去重对性能影响较大。目前大部分存储的在线压缩去重都不算很成熟。而离线压缩去重从实现复杂度以及性能开销上都较小,但通常需要数据很少变更,而经常变更的数据则不适用。
可靠性
可靠性几乎是存储最重要的指标。简单而言,指存储返回成功写入的数据,在之后读出的数据应该总是与写入时一致的。常见的数据问题集中在:
cache,存储返回写入成功,但数据只写入到了cache里,没有持久化,在掉电时,数据丢失。这里的cache有存储层自身的cache,内核的cache,以及磁盘硬件内部的cache。
副本带来的一致性问题,副本意味着冗余,重复就可能导致数据不一致。
元数据损坏,导致文件/目录丢失,文件大小不正确导致数据被截断等
硬件问题,如磁盘静默错误,磁盘损坏导致数据无法读出等。
整个存储系统带来的bug,如并发时序,交叉写入,硬件出错带来的恢复机制异常等。
测试方法
工具的选择
通常需要一个事务性的验证程序来验证可靠性,该验证程序会写入带有自验证校验的数据,不断写入数据以及校验数据,在存储崩溃恢复后,校验这些数据是否符合预期。注意,验证程序的写入的模式需要能达到测试的目的,即IO模式需要覆盖能产生异常的场景,例如存在交叉写场景,存在append写等
此外也可以采用fio verify,数据库事务,以及其他重数据类的应用(例如存储在经历了诸多异常测试后,这些依赖数据类的应用能否正常工作)等辅助验证
测试的前置条件
测试的数据必须采用direct io写入,采用hdparm等关闭磁盘的非持久化cache
关闭存储/内核本身的cache,如元数据cache
常用测试方式
模拟或者制造各类故障,通常采用内核Fault Injection,或者设备热插拔,物理手段,以及kill进程等方式制造故障
通过随机制造上面的故障,如果存储能正常恢复,且能通过验证程序对数据的校验,则说明存储是较可靠的。
稳定性/可用性
稳定性与可用性通常指存储能长时间保持稳定,以及在故障恢复后,仍然可以保持对外提供正常服务的能力。
一般而言造成存储长期运行时稳定性/可用性问题主要表现在:
内存类问题,内存泄漏,存储coredump
性能下降,比如cache,或者资源未及时回收
外部异常恢复后,存储无法提供部分服务,例如仍保留故障时的状态
部分组件故障导致不可用,例如单个硬盘故障影响存储全局性能,功能等。
亚健康
磁盘亚健康也是影响存储可用性较大的因素,通常表现在性能上。
其他
监控/调试
由于存储的基础设施属性,不能随意中断服务。通常本身需要提供丰富的监控信息,信息导出,设置等,达到在不中断存储服务的情况下对存储内部的信息进行查看,以及做必要的修改。一般而言需要提供以下常见的信息:
iostat信息,即存储本身的iops,吞吐,延迟,队列深度等。相较于传统的iostat只需要提供一个磁盘的iostat,一般需要提供每个底层存储(如磁盘),集群,不同的服务接口(如对外提供的nfs, smb, iscsi)的iostat信息
元数据stat信息,通常需要提供常见元数据操作信息op/s, 延迟,如lookup, setattr, getattr, rm, rename, mkdir等
存储内部任务状态信息,例如数据平衡,数据修复,扩容同步等
每个接入点的iostat信息,元数据stat信息。
存储系统内部的信息,例如接入点数,文件数量,目录数量,节点(磁盘)的健康状态,资源的占用情况(如open fd数)等
节点(磁盘)的详细状态信息,如加入时间,上次离线时间,节点的延迟,节点任务状态,节点发生过的IO错误数
可设置的属性,这个类似与大部分存储提供的设置命令, 例如限制数据修复速度,暂停某些任务,io引擎的设置,节点的权重,队列大小等
扩展性
随着数据量的增加,存储的可扩展性同样很重要,特别是水平拓展能力。数据量总有可能超出起初规划的大小,按需增加的存储也能减少成本。通常情况下存储不允许停机,在这种情况下,在线扩展存储的功能或者hotfix也显得同样重要。
评估维度
能否接近线性的增加空间,接近线性增长的性能(同时损耗最小的物理设备性能)
增加空间时对现有存储的影响是否足够小,例如少量的数据迁移
增加一个存储功能是否足够方便,对现有存储的影响。
例如glustefs的功能扩展性做的比较好,每一个功能对应一个xlator,是一个动态库,一个xlator对应一个存储功能,可以通过配置(graph)动态增删xlator,实现存储功能的动态添加与删除。IO流从一个xlator流向另一个xlator,每个xlator只处理自己的数据流。例如需要实现存储加密,那么只需要对读写IO进行加密解密,实现对应的库,然后动态添加到图里即可。
在比如,默认情况下,它是分布式的,IO需要从client side通过网络写入到对应的server side。而只需要在配置上将server side的posix xlator(IO后端,真实写入数据的模块)配置在client side的AFR模块下,接入本地磁盘,那么它就变成本地的存储了,IO不需要跨进程也不需要走网络,并且同时具有副本,DHT等功能。
参考工具
https://github.com/linux-test-project/ltp
https://github.com/jepsen-io/jepsen
https://github.com/pjd/pjdfstest
https://docs.kernel.org/fault-injection/fault-injection.html