多命名空间结合cgroup保障存储QoS

Memblaze新品发布会展示了PBlaze5 NVMe SSD的多命名空间结合cgroup技术,有效保障存储QoS。通过将SSD用户空间划分为多个独立的namespace,并利用cgroup精确控制各namespace的I/O性能,即使在复杂的工作负载下也能确保稳定的响应时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

6月, Step Ahead 向前一步——Memblaze 新品发布会在北京召开,Memblaze在发布会现场围绕PBlaze5 910/916及510/516两大系列NVMe SSD的能源效率、Trim保障云业务、多命名空间与cgroup结合保障存储QoS等主题做了演示方案。这些方案全面展示了Memblaze新一代NVMe SSD产品的优势,而且对于企业用户部署和使用NVMe SSD,构建高速、高效的存储系统同样具有借鉴意义。

在此我们将对这些关键的技术细节通过系列文章解读,本文主要介绍的是多命名空间结合cgroup保障存储QoS的方案。

关于多命名空间和cgroup

多命名空间(为方便解释相关操作及原理,后文命名空间会写成namespace)是PBlaze5系列NVMe SSD的一项关键特性,用户空间被多个namespace划开。 在PBlaze5系列产品中,可以将逻辑块按需划分为最多32个namespace,每个namespace拥有独立逻辑地址和NSID,独立格式化和访问。Controller 就是通过 NSID 来引用特定的 namespace 。

划分了32个namespace的PBlaze5

每个namespace 都可以单独配置硬盘的参数,如配置不同的物理扇区大小、执行trim指令、数据保护、加密等。需要指出的是多名命空间在NVMe SSD的实现原理在NVMe标准协议中有明确的定义,但是不同厂商对其有不同的解释。

这就是多命名空间,他为上层的资源调度机制提供了一个基础平台。结合cgroup就可以控制存储的QoS。(关于多命名空间更多细节,参见文章《实锤,PBlaze5实力演绎multiplenamespaces 功能(上)》和《实锤,PBlaze5实力演绎multiplenamespaces 功能(下)》)。

cgroup(control group)是Linux内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:CPU, Memory, IO等)的机制。最初由Google的工程师提出,2007 年进入 Linux 2.6.24 内核。cgroup 也是 LXC/Docker 为实现虚拟化所使用的资源管理手段。可见cgroup对于Linux的资源管理和容器的实现都具有重要的意义,并且这是一项较为成熟的技术。

cgroup分v1和v2两个版本,v1实现较早但是应用较为广泛;v2则是重新设计之后的版本,该版本从Linux  4.5内核开始可以用于生产环境,并且v1和v2可以混合使用。由于当下cgroup v1版更加成熟,本文也使用v1版进行介绍。

使用cgroup之前需要介绍几个比较重要的概念:

• 任务(task)。在 cgroup 中,任务就是系统的一个进程; 

• 控制组(control group)。控制组就是一组按照某种标准划分的进程。cgroup 中的资源控制都是以控制组为单位实现。一个进程可以加入到某个控制组,也从一个进程组迁移到另一个控制组。一个进程组的进程可以使用 cgroup 以控制组为单位分配的资源,同时受到 cgroup 以控制组为单位设定的限制; 

• 层级(hierarchy)。控制组可以组织成 hierarchical 的形式,既一颗控制组树。控制组树上的子节点控制组是父节点控制组的孩子,继承父控制组的特定的属性; 

• 子系统(subsystem)。一个子系统就是一个资源控制器,本文介绍的方案使用的就是blkio子系统,其他的还有memory、cpu、cpuset等等子系统。子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。

关于cgoup的相关信息和使用方法都可以在其官方文档中找到,这里不多赘述,只对blkio子系统使用进行一个介绍。blkio子系统主要功能是控制磁盘等块设备的性能等参数,挂载cgroup root目录以及blkio子系统如下所示:

echo "259:0 102400" > blkio.throttle.read_bps_device
echo "259:0 10" > blkio.throttle.read_iops_device
在对应的子系统目录下通过mkdir创建资源组,rmdir可将对应资源组删除。
实际操作中,以读的IOPS和带宽为例,可以分别设置两个参数的上限,如下所示:
mount -t tmpfs cgroup_root /sys/fs/cgroup
mkdir /sys/fs/cgroup/blkio
mount -t cgroup -o blkio none /sys/fs/cgroup/blkio
第一条命令将259:0设备(这里的设备可以是namespace,下同)的读带宽限定在100KB/s,第二条命令将259:0设备读iops限定在10。

用户可以依照上面的命令格式对读和写的IOPS和带宽分别进行设置,cgroup会依据多个阈值对设备(这里可以是多个1到多个namespace)的性能进行精准的控制,如此一来,即便是读写混合、多种I/O size混合的应用场景,NVMe SSD的QoS仍然有保障。

测试结果展示
多命名空间结合cgroup保障存储QoS的方案能够实现的效果在日前Step Ahead 向前一步——Memblaze 新品发布会上进行了详细的展示,这里我们对进行再次解读。
测试条件
Server: PowerEdge R730xd
cpu:Intel(R) Xeon(R) CPU E5-2640 v3 @ 2.60GHz
Memory:64GB
Storage:PBlaze5 910 U.2 3.84T NVMe SSD

测试软件:fio-3.2

实验介绍
在戴尔的R730xd上装一块3.84TB的PBlaze5 910 NVMe SSD,创建8个相同容量的namespace。使用fio进行测试,并对读IOPS的控制效果,事实上用户可以依据自身需求对写IOPS,写带宽以及读带宽依照这个思路进行操作。

3.2 测试步骤
1) 创建8个相同容量namespace
2) 初始化处理,确保设备进入稳态
3) 进行IO测试1
前4个namespace读iops限制为3万
后4个namespace读iops限制为1万
4KB 100%随机读,fio queue depth=1,300秒
4) 进行IO测试2
前4个namespace读iops限制为6万
后4个namespace读iops限制为1万
4KB 100%随机读,fio queue depth=16,300秒
测试结果展示

 
I/O测试1:4个namespace的IOPS被控制为1万,另外四个控制在3万
 
I/O测试1:4个namespace的IOPS被控制为1万,另外四个控制在6万
 

多命名空间将NVMe SSD的用户空间划分为多个区域,不同的区域可以独立进行Trim、格式化等操作。并且上层的一些高级功能的实现构建了一个基础平台,cgroup就是这样高级功能中的代表。cgroup诞生于谷歌,并在Linux生态中实践多年,是一项对底层硬件资源管控的成熟技术。多命名空间与cgroup的结合是IT系统中一个软硬件结合并充分发挥各自优势的方案,各类虚拟化、容器、云计算、云存储等应用场景都可以借助这一方案保障存储系统的QoS。

相关阅读:

cgroup v1官方文档

https://www.kernel.org/doc/Documentation/cgroup-v1/cgroup.txt

cgroup v1中块设备控制文档

https://www.kernel.org/doc/Documentation/cgroup-v1/blkio-controller.txt

Cgroup与LXC简介

http://blog.51cto.com/speakingbaicai/1359825

CGroup 介绍、应用实例及原理描述

https://www.ibm.com/developerworks/cn/linux/1506_cgroup/index.html

测试结果视频

https://www.bilibili.com/video/av26458755/



<think>好的,我现在需要帮助用户解决Linux主命名空间的cgroup无法同步到子网络命名空间的问题。首先,我需要回顾之前的对话历史,看看用户之前遇到了什么问题,以及已经给出的建议。用户之前执行了一个在Dante网络命名空间中挂载tmpfs到/sys/fs/cgroup的命令,结果遇到了工作目录错误。我解释了错误原因,并提供了三种解决方法:切换到根目录、禁用挂载命名空间或更换挂载路径。用户现在的新问题是主命名空间的cgroup无法同步到子网络命名空间里,这可能与之前的操作相关。 接下来,我需要理解用户当前的问题:主命名空间的cgroup配置无法在子网络命名空间里生效。这可能涉及到Linux的命名空间隔离机制,特别是cgroup和网络命名空间的关系。根据我的知识,cgroup的命名空间和网络命名空间是不同的隔离机制,因此默认情况下,子网络命名空间不会继承主命名空间的cgroup配置。用户可能希望子网络命名空间中的进程能使用主命名空间的cgroup设置,或者希望同步配置,但发现无法实现。 我需要分析问题的原因。首先,确认cgroup和网络命名空间的关系。Linux中,每个命名空间(如PID、网络、挂载、cgroup等)是独立的。网络命名空间隔离网络资源,而cgroup命名空间隔离cgroup视图。默认情况下,创建新网络命名空间时,其他命名空间如cgroup可能未被隔离,因此子网络命名空间可能仍能看到主命名空间的cgroup。但用户遇到的问题可能是子网络命名空间中的进程没有被自动加入到主命名空间的cgroup中,或者挂载点的问题导致无法访问。 可能的原因包括: 1. **cgroup命名空间未隔离**:如果子网络命名空间没有单独的cgroup命名空间,它可能仍然使用主命名空间的cgroup结构,但挂载点可能不同。 2. **挂载点未传播**:主命名空间的cgroup挂载点可能未在子命名空间中自动挂载,需要手动挂载。 3. **进程未加入cgroup**:即使cgroup存在,子命名空间中的进程需要显式加入相应的cgroup控制器。 4. **systemd或init系统的管理**:现代系统使用systemd管理cgroup,可能在子命名空间中未正确初始化。 接下来,我需要考虑如何解决这些问题。可能的解决方案包括: - 手动挂载cgroup到子网络命名空间。 - 确保挂载使用正确的选项(如shared、slave等)以允许挂载传播。 - 使用工具(如nsenter)或在进入命名空间后手动配置cgroup。 - 检查systemd是否在子命名空间中运行,可能需要额外的配置。 另外,需要验证用户的操作是否正确。例如,用户是否在子命名空间中正确挂载了cgroup文件系统,或者在创建进程时是否将其加入到特定的cgroup中。可能还需要考虑用户是否混淆了cgroup v1和v2的区别,不同版本的行为可能不同。 用户可能希望子网络命名空间中的进程继承主命名空间的cgroup设置,但默认情况下,进程创建时可能会继承父进程的cgroup,但如果子命名空间中的挂载点不同,可能导致无法正确访问主命名空间的cgroup结构。因此,需要确保在子命名空间中正确挂载cgroup文件系统,并设置适当的传播属性。 最后,需要将这些思考整理成清晰的步骤,解释原因并提供解决方案,同时给出示例命令和注意事项,帮助用户理解和解决问题。</think>--- 在 Linux 中,**cgroup(控制组)** 和 **网络命名空间(netns)** 是两种不同的资源隔离机制,它们的隔离层级和默认行为存在差异,因此主命名空间的 cgroup 配置不会自动同步到子网络命名空间。以下是详细解释和解决方案: --- ### **问题原因** #### 1. **命名空间的独立性** - **网络命名空间(netns)**:仅隔离网络设备、IP 地址、路由表等网络资源。 - **cgroup 命名空间(cgroupns)**:控制进程对 `/sys/fs/cgroup` 目录的视图(即进程看到的 cgroup 层次结构)。 - **默认情况下**,创建新的网络命名空间时,**不会自动创建新的 cgroup 命名空间**。子网络命名空间中的进程仍能看到主命名空间的 cgroup 视图,但能否正确使用取决于挂载点和权限。 #### 2. **挂载点的隔离** - 如果子网络命名空间内未挂载 cgroup 文件系统,进程可能无法直接访问主命名空间的 cgroup 控制器(即使路径存在)。 - 示例:主命名空间的 `/sys/fs/cgroup/cpu` 在子网络命名空间中可能未挂载,导致无法操作该 cgroup。 #### 3. **进程归属问题** - 即使子网络命名空间中的进程能看到主命名空间的 cgroup,**新创建的进程默认不会自动加入主命名空间的 cgroup**,除非显式配置。 --- ### **解决方案** #### 方法 1:在子网络命名空间中手动挂载 cgroup 在子网络命名空间中挂载与主命名空间相同的 cgroup 结构,确保进程可以操作 cgroup。 ```bash # 进入网络命名空间并挂载 cgroup sudo ip netns exec dante bash -c ' mkdir -p /sys/fs/cgroup; mount -t cgroup2 none /sys/fs/cgroup; # 如果是 cgroup v2 # 或挂载特定控制器(cgroup v1) mount -t cgroup -o cpu,cpuacct cpu /sys/fs/cgroup/cpu; # 其他控制器同理 ' ``` #### 方法 2:启用挂载传播(Mount Propagation) 通过 `mount --make-shared` 或 `mount --make-slave` 设置挂载点的传播属性,允许挂载事件在命名空间之间传递。 ```bash # 主命名空间中设置共享挂载 sudo mount --make-shared /sys/fs/cgroup # 子网络命名空间会自动继承挂载点(需支持传播) sudo ip netns exec dante bash -c 'ls /sys/fs/cgroup' ``` #### 方法 3:显式将进程加入主命名空间的 cgroup 在子网络命名空间中启动进程时,直接将其加入主命名空间的 cgroup。 ```bash # 将进程 PID 加入主命名空间的 cgroup echo <PID> | sudo tee /sys/fs/cgroup/cpu/your_cgroup/tasks ``` #### 方法 4:使用 Systemd 管理(如果子命名空间运行 Systemd) 若子网络命名空间内运行 Systemd,它会自动挂载和管理 cgroup。 ```bash # 在子网络命名空间中启动 Systemd sudo ip netns exec dante systemd-run --scope --quiet your_command ``` --- ### **关键验证步骤** 1. **检查子命名空间的挂载点** ```bash sudo ip netns exec dante bash -c 'mount | grep cgroup' ``` 2. **验证进程的 cgroup 归属** ```bash # 在子命名空间中查看进程的 cgroup sudo ip netns exec dante bash -c 'cat /proc/$$/cgroup' ``` 3. **测试 cgroup 控制是否生效** ```bash # 在子命名空间中限制 CPU 使用 sudo ip netns exec dante bash -c ' echo "100000" > /sys/fs/cgroup/cpu/your_cgroup/cpu.cfs_quota_us; echo $$ > /sys/fs/cgroup/cpu/your_cgroup/tasks; stress -c 1 ' ``` --- ### **注意事项** 1. **cgroup v1 vs v2** - cgroup v2 使用统一层级,而 v1 按控制器分类。需根据系统版本调整挂载命令。 - 查看 cgroup 版本: ```bash stat -fc %T /sys/fs/cgroup/ ``` 2. **权限问题** - 子网络命名空间中的操作可能需要 `sudo` 权限。 - 确保挂载目录(如 `/sys/fs/cgroup`)在子命名空间中存在。 3. **临时性与持久化** - 手动挂载的 cgroup 在重启后失效,需将命令写入网络命名空间的初始化脚本。 --- ### **扩展:cgroup 与命名空间的关系** - **cgroup 命名空间(cgroupns)**:隔离进程对 `/sys/fs/cgroup` 的视图,但不影响资源控制。 - **网络命名空间(netns)**:隔离网络资源,与 cgroup 无直接关联。 - 默认情况下,**网络命名空间不隔离 cgroup**,但若未正确挂载或传播,可能导致 cgroup 操作失败。 --- 通过上述方法,可以解决主命名空间 cgroup 无法同步到子网络命名空间的问题。核心思路是确保子命名空间内正确挂载 cgroup 文件系统,并合理配置进程归属。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值