4. NVMe命名空间管理

命名空间(Namespace)这个概念,说白了就是NVMe协议里对存储空间的一种抽象。你可以把它想象成一块独立的“虚拟硬盘”。每个命名空间都有自己的LBA范围、自己的属性,甚至可以被不同的主机独立访问。

我刚开始接触NVMe时,总觉得命名空间和传统硬盘的分区差不多。后来踩过坑才明白——两者完全不是一回事。分区是对一块物理盘做逻辑切割,而命名空间是NVMe协议层定义的独立存储对象。一个NVMe设备可以有多个命名空间,每个命名空间都有自己的ID(NSID),从1开始编号。

核心要点:命名空间是NVMe存储资源分配的最小单元。你创建、删除、附加、分离、格式化,都是在操作这个单元。

NVMe命名空间管理 命名空间概念 创建与删除 附加与分离 命名空间格式化 核心操作:ns create / ns delete / ns attach / ns detach / ns format 工具:nvme-cli 命令行工具集

4.1 命名空间概念

每个命名空间都有一个唯一的NSID。主机通过namespace-id来访问对应的存储空间。NVMe协议规定,一个控制器最多支持1024个命名空间(实际取决于实现)。

命名空间有几个关键属性:

  • NSID:命名空间ID,从1开始
  • LBA范围:起始LBA和大小
  • 块大小:通常是512字节或4K
  • 保护信息:是否启用端到端数据保护
  • 格式化状态:是否已格式化

我的经验:在企业级部署中,我习惯给每个应用分配独立的命名空间。比如数据库用NSID 1,日志用NSID 2。这样隔离性好,故障时互不影响。

4.2 命名空间创建与删除

创建命名空间,用的是nvme create-ns命令。你需要指定大小、块大小等参数。

# 创建一个100GB的命名空间,块大小4K
nvme create-ns /dev/nvme0 --nsze=26214400 --ncap=26214400 --flbas=0

# 参数说明:
# --nsze:命名空间大小(LBA数量)
# --ncap:命名空间容量(LBA数量),通常等于nsze
# --flbas:格式LBA大小,0表示4K,1表示512B

删除命名空间更简单:

# 删除NSID为1的命名空间
nvme delete-ns /dev/nvme0 --namespace-id=1

注意:删除命名空间会丢失所有数据!我曾经在测试环境里手滑删错了NSID,还好只是测试盘。生产环境一定要再三确认NSID。

创建完命名空间后,它还不能直接用。你需要把它“附加”到控制器上。

4.3 命名空间附加与分离

附加(Attach)和分离(Detach),是命名空间管理里最容易搞混的操作。我刚开始也迷糊过。

简单说:附加是把命名空间绑定到某个控制器上,主机才能看到它。分离就是解除绑定。

# 将NSID 1附加到控制器0
nvme attach-ns /dev/nvme0 --namespace-id=1 --controllers=0

# 将NSID 1从控制器0分离
nvme detach-ns /dev/nvme0 --namespace-id=1 --controllers=0

为什么要分离?嗯,场景很多。比如你要做固件升级,可以先分离命名空间,升级完再附加上去。或者做多路径故障切换时,分离一个路径的命名空间,让另一个路径接管。

关键点:分离命名空间不会删除数据。它只是让主机暂时“看不见”这块盘。附加上去后数据还在。

4.4 命名空间格式化

格式化命名空间,用的是nvme format命令。这个操作会清空所有数据,并重新初始化元数据区域。

# 格式化NSID 1,使用4K块大小,不启用保护信息
nvme format /dev/nvme0 --namespace-id=1 --lbaf=0 --pi=0

# 参数说明:
# --lbaf:LBA格式索引,0通常对应4K
# --pi:保护信息类型,0=无,1=CRC64,2=CRC32

格式化时,你可以选择不同的LBA格式。比如从512B切换到4K,或者反过来。但要注意:格式化会改变命名空间的块大小,上层文件系统必须重新创建。

操作 命令 数据是否丢失 典型场景
创建 nvme create-ns 否(新空间) 分配新存储资源
删除 nvme delete-ns 是 回收存储资源
附加 nvme attach-ns 否 使命名空间可用
分离 nvme detach-ns 否 临时下线维护
格式化 nvme format 是 重置元数据、改块大小

避坑指南:我曾经在格式化一个正在使用的命名空间时,忘记先卸载文件系统。结果格式化到一半卡住了,整个控制器都挂了。正确的做法是:先umount,再分离,最后格式化。

格式化完成后,记得重新附加命名空间,然后创建文件系统:

# 格式化完成后,重新附加
nvme attach-ns /dev/nvme0 --namespace-id=1 --controllers=0

# 创建文件系统(以ext4为例)
mkfs.ext4 /dev/nvme0n1

# 挂载使用
mount /dev/nvme0n1 /mnt/data

嗯,到这里命名空间管理的基本操作就讲完了。其实核心就五条命令:create、delete、attach、detach、format。但每个操作背后的原理和注意事项,才是真正值钱的东西。

我个人建议,在测试环境里多练几遍。先创建几个命名空间,来回附加分离,再格式化看看效果。踩过坑才能记得牢。