【前言】
这是一次充满曲折与反转的问题分析,资料很少,代码很多,经验很少,概念很多,当内核态,用户态,DIF,LBA,大页内存,SGL,RDMA,NVME和SSD一起迎面而来的时候,问题是单点的意外,还是群体的无奈?
为了加深记忆,也为了分享出来给人以启示,特记录这次问题分析过程。
【现象】
同事L在项目中需要使用NVMF写盘,发现写盘失败,疯狂打印错误码:

图片中虽然截取的比较少,但实际是疯狂的一直打印。
故障现象简要描述一下就是:
通过NVMF写盘失败,疯狂打印错误码15;
作为对照,通过本地写盘,一切正常。
注:这里的盘,都是指SSD盘。目前实验室使用的型号是公司V3版本(HWE3xxx)。
【分析】
在这里把涉及到的一些基本缩略语都记录一下:
| 缩写 |
英文名称 |
中文名称 |
说明 |
| SSD |
Solid-State Disk |
固态硬盘 |
固态电子储存芯片阵列制成的硬盘,含控制器和存储单元;按Block写入,按Page清除,修改前面写入的数据,实际是新写入Block,将原来的Block标记为垃圾,等后面按Page来清除; |
| NVME |
Non-Volatile Memory Express |
非易失性内存规范 |
非易失性内存这种类型的设备管理与读写的规范;SSD是常见的形式,但不是唯一形式; |
| RDMA |
Remote Direct Memory Access |
远程直接内存访问 |
为了解决网络传输中服务器端数据处理的延迟而产生的; |
| NVMF |
NVMe Over Fabrics |
当前主要使用的是NVMe Over RDMA,NVMe协议通过RDMA来传输。因此存在一个请求端,存在一个服务端,后面统一使用请求端和服务端来描述吧;在SPDK的描述中,请求端有个标准术语initiator,服务端是target; |
|
| 用户态 |
当前应用基本运行在用户态,使用的三方组件DPDK,SPDK基本运行在用户态; |
||
| 内核态 |
在上一行描述中,使用了基本一词,也就是说,有少量的一部分还是在内核态,只有很薄的一层用于注册设备的; |
||
| DIF |
Data Integrity Field |
数据完整性字段 |
保护数据的,项目中会将SSD格式化为512+8的带DIF格式的; |
| LBA |
Logical Block Address |
逻辑块地址 |
标识写盘偏移位置; |
| 2M大页 |
为了提升CPU的Cache命中率,DPDK初始化时标配内存大页,当前主要使用2M大页; |
||
| SGL |
Scatter/Gather List |
分散聚合列表 |
数据列表,其中的单项叫SGE,NVMe在提交IO数据时的buffer,一般包含1个或多个SGE。本地写盘(NVMe Over PCIe)时,IO命令支持SGL和PRP(Physical Region page 物理内存区域页)两种格式,SGL中的SGE长度较为灵活,而PRP是按页(page)来取内容; RDMA传输数据也是使用SGL; |
| SGE |
Scatter/Gather Element |
分散聚合单元 |
SGL里的一个单元,SGL Segment,描述一段数据空间,实现上是一个结构体,含有地址,长度,key;地址一般是指向一段数据空间,但是,存在一种形式是指向另一个SGL; |
习惯了缩略语作为名词后,总是容易忽略其背后更多的含义,问题的分析,需要对这些有更深的理解,最初对这些理解不深,对数据处理流程不清晰,起步很艰难。
(一)
开始分析。。。
在下发IO时,通过变换IO的大小,队列深度,发现数据量较小时,则几乎没有问题,直接下发1M大小IO时,则必现。
因此,可以明显的推测出IO的大小与问题的出现紧密相关。
直接运行业务来验证问题,过于笨重了,而且非常麻烦,将问题直接简化为,一个服务端和一个请求端,发现均能稳定复现,他们分别是:
1. 运行SPDK自带的app,nvmf_tgt程序,这个就是NVMF的服务端了;

本文记录了一次复杂的NVMF写盘失败问题分析过程,涉及SSD、NVMe、RDMA等关键技术,通过逐步排查,最终定位并解决了由于SGE长度与块大小不对齐导致的写盘错误。
最低0.47元/天 解锁文章
320

被折叠的 条评论
为什么被折叠?



