准备长期研究和运维 DAOS 之前,最容易踩的坑不是代码看不懂,而是环境从一开始就选错了:装了个 Ubuntu,或者挑了个”看起来差不多”的 Rocky 8,结果连官方 RPM 仓库都没有对应目录;再或者兴冲冲买了新至强服务器,才发现 DAOS 依赖的傲腾持久内存早已停产。
这篇文章把 DAOS 每个版本认哪些操作系统、每种硬件该怎么配一次讲清楚。结论全部来自 daos-stack/daos 仓库里各版本标签的 docs/release/support_matrix.md(支持矩阵)、docs/admin/(管理指南)、utils/config/(配置样例),以及 daos.io 官网,不是凭印象给的建议。文中会标出关键依据的文件位置,方便你后续自己复核。
说明:本地仓库当前
master的VERSION是2.9.100、TAG是2.9.100-tb,最新提交日期为 2026-11-09;按 DAOS 的语义化版本约定,奇数次版本号是开发版,所以这条线是通往 3.0 的开发主线,而仓库里v2.8.1标签(发行说明标注 2026-09-30)是目前的稳定版。下文的 3.0 内容来自support_matrix.draft.md草案,尚未 GA,只作前瞻,不作选型依据。
〇、一句话和一张图
一句话:DAOS 对”版本 ↔ 操作系统小版本”的绑定极严,几乎是一个 DAOS 版本只认两三个具体的 Linux 次版本;硬件上它要的是”元数据用字节可寻址的 SCM、数据用 NVMe、网络走 RDMA”这三件套,而新项目已经可以用 MD-on-SSD(用 DRAM + NVMe 日志替代停产的傲腾)把这套要求落到普通服务器上。
先看整体架构,理解它为什么这么挑环境:
flowchart TB
subgraph CLIENT["客户端节点 Client"]
APP["应用进程 / dfuse POSIX 挂载 / libdaos"]
AGENT["daos_agent 控制面代理"]
APP --> AGENT
end
subgraph ADMIN["管理节点 Admin"]
DMG["dmg 管理命令"]
end
subgraph SERVER["服务器节点 Server(集群内必须同一发行版)"]
CP["daos_server 控制面进程"]
subgraph ENGINE["daos_engine 数据面进程(每个 NUMA 节点一个)"]
T["targets:I/O 服务线程"]
end
subgraph HW["硬件层:全部用户态直通,绕过内核"]
SCM["SCM 元数据层:PMem 或 DRAM 加 tmpfs"]
NVME["NVMe SSD 数据层:SPDK 用户态驱动"]
NIC["高速网卡:libfabric 或 UCX 走 RDMA"]
end
CP --> ENGINE
ENGINE --> SCM
ENGINE --> NVME
ENGINE --> NIC
end
subgraph OSL["操作系统底座"]
OS["EL 9.6 / 9.7 或 SLES 15 SP6 / SP7 或 Leap 15.6<br/>x86_64 加 IOMMU 加 hugepages 加 关 THP"]
end
AGENT -.->|"控制面 TCP 10001"| CP
DMG -.->|"控制面 TCP 10001"| CP
APP -->|"数据面 RDMA 或 TCP"| NIC
SERVER --> OSL
关键就在”用户态直通”这四个字:DAOS 的数据面用 SPDK 直接操作 NVMe(不走内核块设备栈),用 libfabric / UCX 直接操作网卡(不走内核网络栈),元数据还可能通过 DAX 直接映射持久内存。这些路径全都紧贴内核接口、驱动和固件,所以内核小版本、OFED 版本、网卡固件一旦对不上,出的问题往往不是”性能差一点”,而是”根本起不来”。这就是支持矩阵写得如此具体的原因。
一、先把术语和版本规则弄明白
1.1 DAOS 是什么
daos.io 官网对它的定位是 “面向 AI 与 HPC 的开源存储平台”(Distributed Asynchronous Object Storage,分布式异步对象存储)。官网强调的几个数字和特性:完全分布式的元数据、在有 RDMA 时首字节延迟低于 20 微秒、原生并行文件系统,以及可以按对象/文件、按数据集/目录动态设置纠删码与副本策略。
先解释后面会反复出现的一组名词,零基础也能读下去:
| 名词 | 大白话解释 |
|---|---|
| SCM(Storage Class Memory) | 存放”目录/索引”这类元数据的快速存储层,要求 CPU 能按字节直接读写,而不是按块读写 |
| PMem / 傲腾持久内存 | Intel Optane 持久内存条,断电不丢数据、又能按字节寻址,是 SCM 的经典实现(现已停产) |
| PMDK / DAX | PMem 的编程库,以及 Linux 让应用直接映射持久内存、跳过页缓存的机制 |
| MD-on-SSD | 没有 PMem 时的替代方案:元数据放 DRAM,靠 WAL(预写日志,先记流水账再改账本)和检查点把元数据刷到 NVMe 上 |
| SPDK | 让程序在用户态直接驱动 NVMe 的工具包,省掉内核中断和上下文切换 |
| RDMA | 网卡直接读写远端机器内存,不经过对方 CPU 和内核网络栈 |
| libfabric / UCX | 两套”高速网络抽象层”,provider(如 ofi+tcp、ucx+dc_x)决定底层走哪种网络和协议 |
| engine / target | 一个服务器上跑一个或多个 daos_engine 进程(通常一个 NUMA 节点一个),每个 engine 里再开若干个 target I/O 线程,一个 target 大致对应一块 NVMe 的一个分片 |
| NUMA 亲和 | 双路服务器上,CPU 访问”插在自己这路”的内存和 PCIe 设备最快,跨路走 UPI 会变慢 |
| bdev_role | MD-on-SSD 下给 NVMe 盘分配的角色:wal(日志)、meta(元数据检查点)、data(用户数据) |
1.2 版本号怎么读
仓库 docs/release/version_interop.md 写明:DAOS 用 MAJOR.MINOR.PATCH 语义化版本,奇数 MINOR 是开发版,偶数 MINOR 是稳定版。所以 2.1、2.3、2.5、2.7、2.9 都是开发线,2.0 / 2.2 / 2.4 / 2.6 / 2.8 才是能上生产的线。
同一份文档还规定了互操作规则,运维必须记牢:
- 同一个 DAOS 系统里,所有服务器必须是同一个 DAOS 版本、同一个 Linux 发行版;客户端可以跑别的发行版。
- 客户端与服务器的
MAJOR.MINOR最多差一个次版本(例如 2.8 客户端可以连 2.6 或 2.8 服务器),管理节点的dmg必须与服务器同版本。 docs/release/upgrading.md规定:2.8.x → 3.0 是离线升级(要停系统、保留池数据),而低于 2.8 的版本必须先升到 2.8.x 再升 3.0。
1.3 依据在哪儿,以及一个容易误读的细节
每个版本的官方口径都在 docs/release/support_matrix.md。但直接从 master 读会踩两个坑:
master上的support_matrix.md只有一句话——”3.0 尚未发布,请看最新稳定版”,真正的内容在support_matrix.draft.md里。- 历史版本要切到对应 git 标签读。例如
v2.6.0标签里的支持矩阵其实是个占位符(”2.6 还在开发中,计划 2023 年底发布”),2.6 的权威口径在v2.6.5这样的后期维护标签里。
更有意思的是:3.0 草案自身就有口径冲突——开头的 General Support 和 release_notes.draft.md 写”EL 9.7/9.8”,正文却写”支持 EL 9.6 和 9.7,9.8 验证计划在未来维护版本”。这正说明草案不能当选型依据,也说明读源码比读二手资料可靠。
二、版本 ↔ 操作系统对照表(核心)
下面这张表是我逐个 git show <tag>:docs/release/support_matrix.md 核对出来的。”主验证平台”是官方主要跑测试的组合,优先照抄它,出问题最容易得到社区支持。
| DAOS 版本 | 主验证平台 | EL8 系(RHEL / Rocky / Alma) | EL9 系 | SUSE 系 | 已淘汰 / 明确不支持 |
|---|---|---|---|---|---|
| 2.0 | CentOS Linux 8 + openSUSE Leap 15.3 | CentOS 8.4/8.5、RHEL 8.4 EUS/8.5;CentOS/RHEL 7.9 仅限二代至强 Cascade Lake | 无 | Leap 15.3、SLES 15 SP3 | Rocky、AlmaLinux、Ubuntu、CentOS Stream、Oracle Linux |
| 2.2 | Rocky Linux 8.6 + Leap 15.3 | RHEL 8.4 EUS/8.6、Rocky 8.6;CentOS/RHEL 7.9 仅限二代至强 | 无 | Leap 15.3、SLES 15 SP3 | CentOS Linux 8 已 EOL、AlmaLinux、Ubuntu、Fedora |
| 2.4 | Rocky Linux 8.6 + Leap 15.4 | EL 8.6 EUS(RHEL/Rocky/Alma),8.8 验证中 | 明确不支持,文档写”9.2+ 将在 2.6 加入” | Leap 15.4、SLES 15 SP4 | CentOS 7 / RHEL 7 被移除、CentOS 8、Ubuntu |
| 2.6 | Rocky 8.8、Rocky 9.2、Leap 15.5 / 15.6 | EL 8.8 EUS、EL 8.10 | EL 9.2 EUS、EL 9.4 | Leap 15.5/15.6、SLES 15 SP5/SP6(SP6 与 15.6 自 2.6.3 起) | EL 8.9、EL 9.3 未验证;CentOS 7/8、Ubuntu、Fedora、RHEL 7 |
| 2.8 / 2.8.1 | Rocky 9.6、Rocky 9.7、Leap 15.6、SLES 15 SP7 | 未验证(8.10 是 EL8 最后一版),官方建议升 EL9 | EL 9.6、EL 9.7;9.8 计划后续维护版 | Leap 15.6、SLES 15 SP6 / SP7(注意不存在 Leap 15.7) | EL8 全系、RHEL 7、CentOS 全系、Ubuntu、Fedora、Tumbleweed、Oracle Linux;RHEL 10 与 SLES/Leap 16 未验证 |
| 3.0(草案,未 GA) | Rocky 9.7 / 9.8、Leap 15.6、SLES 15 SP7 | 未验证 | 正文 EL 9.6/9.7(草案内部对 9.8 口径不一致) | SLES 15 SP6/SP7、Leap 15.6 | 同 2.8;仅供前瞻 |
几个反复出现、值得单独拎出来的硬规则:
- 架构只支持 x86_64。社区有人在小端 ARM64 上编译通过并做了基础测试,但
docs/release/support_matrix.md明确说这不是 CI 覆盖范围内的配置,生产环境不予支持。 - 同一个 DAOS 系统里的所有服务器必须跑同一个 Linux 发行版;客户端可以不同发行版,但 2.0–2.8 的客户端支持清单与服务器完全相同。
- Ubuntu 全系列都在”不支持”名单里。但
docs/QSG/build_from_scratch.md提供了utils/scripts/install-ubuntu.sh,仓库里也有utils/docker/Dockerfile.ubuntu(默认ubuntu:26.04)和 CI 里的ubuntu:noble构建任务。所以准确定位是:Ubuntu 可以用来编译和学习源码,不能用来部署 DAOS 服务器。 - 官网与社区/商业支持是分开的:社区支持走邮件列表、Slack 和 JIRA,尽力而为无 SLA;商业支持由 DAOS 生态伙伴提供,且可能附带更严格的版本约束。
下面这张迁移图把”版本 ↔ OS”的演进路径画出来,选路线时照着走就行:
flowchart LR
subgraph OLD["EL7 / EL8 时代(已退役)"]
V20["DAOS 2.0<br/>CentOS 8 / RHEL 8.4-8.5<br/>Leap 15.3"]
V22["DAOS 2.2<br/>Rocky 8.6 / RHEL 8.6<br/>Leap 15.3"]
V24["DAOS 2.4<br/>EL 8.6 EUS<br/>Leap 15.4"]
V26["DAOS 2.6<br/>EL 8.8 EUS / 8.10<br/>EL 9.2 EUS / 9.4<br/>Leap 15.5 / 15.6"]
V20 --> V22 --> V24 --> V26
end
subgraph NOW["EL9 时代(当前推荐)"]
V28["DAOS 2.8.1 稳定版<br/>EL 9.6 / 9.7<br/>SLES 15 SP6 / SP7<br/>Leap 15.6"]
V30["DAOS 3.0 开发中<br/>草案:EL 9.6 / 9.7<br/>MD-on-SSD Phase 2"]
V28 -.->|"离线升级,需先到 2.8.x"| V30
end
subgraph BAD["不要选"]
X["Ubuntu / Fedora / CentOS 全系<br/>RHEL 8 / 10 / ARM64<br/>Tumbleweed / Oracle Linux"]
end
V26 -->|"EL8 退役,先升 OS 再升 DAOS"| V28
OLD -.->|"仅作历史维护参考"| X
2.1 具体怎么选(给你一个明确答案)
| 你的场景 | 推荐组合 | 理由 |
|---|---|---|
| 新项目 / 开发运维研究(首选) | DAOS 2.8.1 + Rocky Linux 9.6 或 9.7 | 免费、社区资料最多、EL9 是当前唯一被验证的红帽系,dnf 装 RPM 最省事;仓库 .github/workflows/ci2.yml 的构建矩阵也用 rockylinux/rockylinux:9 |
| 已有红帽订阅的企业 | DAOS 2.8.1 + RHEL 9.6 / 9.7 | 同上,且能拿到 RHEL 的 EUS 与商业支持 |
| 已有 SUSE 技术栈 | DAOS 2.8.1 + SLES 15 SP6 / SP7(或学习用 Leap 15.6) | 官方主验证平台之一,zypper 装包 |
| 只想读代码、跑单元测试 | Ubuntu 24.04 / 26.04 容器 + install-ubuntu.sh |
能编译,但别把结论外推到部署环境 |
| 维护老集群 | 按上表锁定原版本对应 OS,先升到 2.8.x 再考虑 3.0 | 跨大版本只能离线升级,且要遵守 N±1 互操作 |
一句话:别在操作系统上”创新”。研究 DAOS 的乐趣在于分布式事务、纠删码、rebuild 这些地方,不在于跟驱动版本搏斗。
三、硬件推荐:先弄懂”为什么”,再看清单
3.1 一台 DAOS 服务器长什么样
docs/admin/hardware.md 说得很直白:DAOS 的服务器设计本质是平衡网络带宽与本地 NVMe 的聚合带宽。文档举的例子是:一块 200Gbps 的 PCIe4 x4 网卡,纯读负载大约 4 块 NVMe4 x4 SSD 就能喂饱,写负载因为 SSD 写比读慢,需要约 8 块。
同时,双路至强的 PCIe 设备天然归属于某一路 CPU,PMem 也有 NUMA 特性。所以官方做法是 每个 CPU socket 起一个 engine,只访问本路的 PMem、NVMe 和网卡,尽量避免跨 UPI 访问:
flowchart TB
subgraph HOST["一台双路 x86_64 存储服务器"]
subgraph S0["Socket 0 / NUMA 0"]
E0["daos_engine 0<br/>targets 加 nr_xs_helpers"]
P0["SCM 层:Optane PMem 200<br/>或 DRAM 加 tmpfs"]
N0["本地 NVMe SSD 4 至 12 块<br/>bdev_roles 分 wal / meta / data"]
I0["本地高速网卡端口 ib0"]
E0 --> P0
E0 --> N0
E0 --> I0
end
subgraph S1["Socket 1 / NUMA 1"]
E1["daos_engine 1<br/>targets 配置必须与 engine 0 相同"]
P1["SCM 层:同容量同型号"]
N1["本地 NVMe SSD 4 至 12 块<br/>配置与 engine 0 完全一致"]
I1["本地高速网卡端口 ib1"]
E1 --> P1
E1 --> N1
E1 --> I1
end
UPI["UPI 互连:跨路访问会变慢<br/>用 pinned_numa_node 绑核规避"]
S0 <--> UPI
S1 <--> UPI
CP["daos_server 控制面<br/>自动探测 NUMA 亲和并拉起各 engine"]
CP -.-> E0
CP -.-> E1
end
FABRIC["高速交换网络<br/>所有 engine 使用同型号适配器"]
I0 --> FABRIC
I1 --> FABRIC
docs/admin/hardware.md 还给了两条容易忽略的约束:HDD、SATA SSD、SAS SSD 都不支持(必须是 NVMe,通过 SPDK 用户态访问);SCM 容量相对 SSD 容量至少 6%,否则会出现”数据盘还有空间、元数据区先满了”的尴尬。
3.2 一次写请求走过的路
理解了分层,再看一次写 I/O 的时序,就明白每个硬件层在干什么、为什么 MD-on-SSD 要多一步 WAL:
sequenceDiagram
autonumber
participant App as 应用进程(客户端)
participant Lib as libdaos
participant Ag as daos_agent
participant Ctl as daos_server 控制面
participant Eng as daos_engine(target)
participant Meta as SCM 层 / WAL
participant Disk as NVMe SSD(SPDK)
App->>Ag: 首次连接,请求系统与证书信息
Ag->>Ctl: 控制面查询(TCP 10001)
Ctl-->>Ag: 返回 rank 列表与访问凭据
Ag-->>Lib: 下发可用 fabric provider 与地址
App->>Lib: daos_obj_update 写对象
Lib->>Eng: 经 RDMA 或 TCP 直接发数据面请求
Eng->>Meta: 先在 SCM 更新元数据索引
alt 有 PMem 的服务器
Meta-->>Eng: PMDK 直接持久化到持久内存
else MD-on-SSD 的服务器
Meta->>Disk: 元数据变更先追加写 WAL 日志
Disk-->>Meta: 日志落盘确认
Note over Meta,Disk: 后台异步把检查点刷到 meta 角色盘
end
Eng->>Disk: 用户数据写入 data 角色 NVMe
Disk-->>Eng: 写完成
Eng-->>Lib: 返回成功
Lib-->>App: 调用返回
图里 alt 分支就是两条硬件路线的根本差别:PMem 路线靠硬件本身断电不丢;MD-on-SSD 靠”先写日志再异步落盘”换来了对普通 DRAM + NVMe 的支持。
3.3 两条路线对比:新项目基本只能选 MD-on-SSD
| 维度 | PMem 路线 | MD-on-SSD 路线 |
|---|---|---|
| SCM 怎么来 | Intel Optane PMem 100 系列(二代至强 Cascade Lake)/ 200 系列(三代至强 Ice Lake),通过 PMDK 访问 | DRAM 放元数据,NVMe 上用 WAL + 异步检查点持久化 |
| 现状 | 300 系列(四代至强)已被 Intel 取消,DAOS 不支持;傲腾整体停产,新机器买不到 | 2.6 起 Phase 1 生产可用;2.8 中 Phase 2 为技术预览(降低 DRAM 需求);3.0 草案计划把 Phase 2 + allocator v2 作为新建池默认 |
| 内存要求 | 强烈建议每个内存通道插 1 条 DRAM + 1 条 PMem,且所有 PMem 模块容量相同 | 强烈建议每个内存通道都插满 DRAM DIMM |
| NVMe 配置 | 单个 engine 管理的所有 NVMe 容量必须相同,建议同型号 | 分成 wal / meta / data 三种角色;同一角色组合的盘容量必须相同,不同角色之间可以不同容量(如 wal/meta 用高耐久小容量盘) |
| 限制 | 配置最”正统”,但硬件已断供 | wal 与 data 不能放在同一个 tier;最多 3 个 bdev tier;class: dcpm 时不允许指定 bdev_roles |
| 适合谁 | 维护既有傲腾集群 | 所有新项目、所有自建研究环境 |
这里的”角色”约束来自 docs/admin/deployment.md,配置样例在 utils/config/examples/daos_server_mdonssd.yml。官方还给了个实用的策略提示:盘少(4–5 块/engine)时,把所有角色放在同一个 tier 反而比”1 块盘独占 WAL”更快,因为多盘聚合带宽更高。
3.4 关键参数速查表
这些值散落在 docs/admin/predeployment_check.md、docs/admin/hardware.md 和 utils/config/daos_server.yml 的注释里,汇总如下:
| 项目 | 推荐值 | 依据与原因 |
|---|---|---|
| SCM : NVMe 容量比 | ≥ 6% | hardware.md,保证元数据放得下 |
| Hugepages | 每个 target 1 GiB,建议开机 hugepages=N 预分配 |
daos_server.yml 注释:2 engines × 16 targets × 1GiB / 2MiB = 16384 页 |
| Transparent HugePage | 关闭 | predeployment_check.md,避免内存碎片导致 DMA 缓冲分配失败 |
| IOMMU | BIOS 开 VT-d + 内核 intel_iommu=on,走 VFIO |
predeployment_check.md,让非 root 的 daos_server 能直通 NVMe |
| NVMe 逻辑块大小 | 4 KiB(LBA Format #03) | predeployment_check.md,DAOS 按 4K 粒度做 I/O,避免对齐损失 |
vm.max_map_count |
提高到 约 1000000 | 默认 65530 太小,会拖累 Argobots 的 ULT 栈分配 |
rmem_default / rmem_max |
≥ 1 MB | 否则 SPDK 报 Failed to set socket option |
memlock |
unlimited | 否则 SPDK 报 cannot set up DMA remapping |
| 时间同步 | 全节点 NTP / chrony | DAOS 事务模型依赖时间戳 |
| 防火墙 | 放行 TCP 10001 | dmg 与 daos_agent 连不上服务器多半是这里 |
targets / engine |
官方验证范围 4–32;上限约为 NVMe 盘数 × 64(PMem)/ × 21(MD-on-SSD) | 支持矩阵 + 配置注释 |
nr_xs_helpers |
EC 场景约 targets 的 1/4(16 targets 配 4) | daos_server.yml 注释,需留足物理核 |
| 全系统一致性 | 所有 engine 的 NVMe 配置、target 数、网卡型号必须一致 | 支持矩阵明确说异构配置未测试 |
| 架构上限 | 65536 个 target | 128 位对象 ID 里只用 16 位编码 target |
3.5 网络:版本差异最大的一块
网络栈的推荐随 DAOS 版本变过,做版本升级时一定要连驱动一起规划:
| DAOS 版本 | 推荐栈 | 关键版本约束 |
|---|---|---|
| 2.4 | libfabric 1.18.1rc1;IB 可用 UCX 1.14.0-1(MOFED 5.8),ucx+dc_x |
老版本,不建议新建 |
| 2.6 | libfabric 1.19.1 / 1.22.0;MLNX_OFED 24.04-0.6.6.0,UCX 1.17.0/1.18.0,推荐 ucx+dc_mlx5 |
低于 24.04 的 MOFED 不支持 |
| 2.8 / 2.8.1 | libfabric 1.22.0;NVIDIA IB/RoCE 改走 DOCA-OFED 3.1.0/3.2.0/3.2.1(推荐 3.2.1)+ UCX 1.20.0 + ucx+dc_x,配合包内 mercury 2.4.1 |
MLNX_OFED 及低于 3.1 的 DOCA-OFED 不再支持;ucx+dc_mlx5 在大规模 IB 重负载下有不稳记录 |
| 3.0 草案 | 同上,另验证 Slingshot SHS 13.1 / 14,推荐 SHS ≥ 13.1 | 草案口径 |
还有几条跨版本通用的硬规则:
- 每个 engine 一个高速端口,2.8/3.0 不支持单 engine 多端口;多端口就多起几个 engine。两个 engine 共用一个端口只可用于开发测试。
- 不要用发行版自带的 inbox OFED,必须装厂商 DOCA-OFED,并把网卡固件刷到该版本自带的级别;所有服务器和客户端用同一版本、同一型号适配器。
ofi+tcp在所有网卡上都能跑但不走 RDMA,是学习和功能验证的首选;ofi+verbs可用但 RC 资源消耗限制扩展性;ofi+cxi专供 HPE Slingshot;ofi+psm3、ofi+psm2、ofi+opx均有已知问题或未经支持。- 从 libfabric 1.18.0 起
ofi+tcp不再自动加rxm,要用得显式写成ofi+tcp;ofi_rxm。 - 规模参考:官方 2.8 已验证 800 台服务器 / 8000 客户端 / 每 engine 4–32 targets / 每 engine 4–12 块 NVMe / 单池 100 容器。
四、面向”开发 + 运维研究”的三档配置
不同研究目标需要的硬件差一个数量级,先定档再花钱:
| 档位 | 目标 | CPU / 内存 | SCM | NVMe | 网络 | 软件 |
|---|---|---|---|---|---|---|
| A 入门:能跑通就行 | 读源码、改代码、跑通 pool/container/dfuse、看日志 | ≥ 4 核、≥ 16 GB RAM(官方 QEMU 文档下限) | tmpfs 模拟 | 普通文件模拟(class: file) |
普通网卡 + ofi+tcp |
Rocky 9.6/9.7 虚拟机 + DAOS 2.8.1 |
| B 单机进阶:摸真实路径 | 真实 NVMe、MD-on-SSD、telemetry、故障与 rebuild 演练 | 8–16 核、64–128 GB DRAM,内存通道插满 | DRAM + tmpfs(MD-on-SSD) | 2–4 块 NVMe,4K LBA,尽量同型号同容量 | 25/100GbE 或一张 IB/RoCE 卡 | EL 9.6/9.7 + 2.8.1 + 官方 RPM |
| C 准生产:集群行为 | 多节点 EC、扩缩容、升级演练、性能调优 | 双路至强,每路 ≥ 16 核,通道插满 | MD-on-SSD(或存量 PMem 200) | 每 engine 4–12 块,全集群同构 | 200/400G IB(DOCA-OFED 3.2.1 + ucx+dc_x)或 Slingshot(SHS ≥ 13.1) |
全集群统一 EL 9.6/9.7 或 SLES 15 SP7 + 2.8.1 |
A 档的两条”模拟”路径在
docs/QSG/qemu-vms.md、docs/QSG/docker.md和utils/config/examples/daos_server_local.yml里都有现成做法。注意这两份 QSG 文档偏旧:QEMU 文档写的是 Rocky Linux 8.9,Docker 文档写的是rockylinux:8.9+ DAOS 2.6,而 2.8 已经不验证 EL8 了——照抄时把镜像换成 Rocky 9.6/9.7、DAOS 换成 2.8.1。Docker 方案还有两个硬前提:必须用 host 网络(bridge/loopback 支持不好)、宿主机至少预留 4096 个 2MiB hugepage。另外官方明确说明:用文件/内存模拟 NVMe 与 SCM 仅用于开发测试,生产不支持。
4.1 示例一:在 EL9 上从零编译 DAOS(完整脚本)
做二次开发迟早要自己编译。下面脚本在 Rocky/Alma/RHEL 9.6 或 9.7 上从零拉源码、装依赖、编译,逐行都有注释,可直接保存为 build-daos-el9.sh 使用:
#!/usr/bin/env bash # 指定用 bash 解释执行本脚本
set -euo pipefail # 任一命令失败、变量未定义、管道出错都立即停止,避免带病继续
DAOS_SRC="${DAOS_SRC:-/opt/daos-src}" # 定义源码目录,固定为 root 可写的路径,可用环境变量覆盖
DAOS_VER="${DAOS_VER:-v2.8.1}" # 定义要编译的版本标签,默认为当前稳定版 2.8.1
if [[ $EUID -ne 0 ]]; then # 判断当前用户是否为 root(安装系统依赖需要 root)
echo "请用 sudo 运行:sudo bash $0" >&2 # 非 root 时打印可直接复制的正确命令到标准错误
exit 1 # 立即退出,防止依赖只装了一半
fi # 结束 root 权限判断
if [[ ! -d "$DAOS_SRC/.git" ]]; then # 判断源码目录是否已经存在且是个 git 仓库
git clone --recurse-submodules https://github.com/daos-stack/daos.git "$DAOS_SRC" # 首次克隆,并一并初始化 raft 子模块
fi # 结束克隆判断
cd "$DAOS_SRC" # 进入源码根目录,后续相对路径都基于这里
git fetch --tags origin # 同步远端标签,确保目标版本标签在本地可见
git checkout "$DAOS_VER" # 切换到指定稳定版标签(要跟开发主线就改成 master)
git submodule update --init --recursive # 把子模块同步到该标签对应的提交
./utils/scripts/install-el9.sh # 安装 EL9 编译依赖:gcc、golang、daxctl、libfabric 开发包等
python3 -m venv "$DAOS_SRC/venv" # 创建独立 Python 虚拟环境,不污染系统 Python
"$DAOS_SRC/venv/bin/pip" install --upgrade pip # 升级 pip,避免老版本解析依赖失败
"$DAOS_SRC/venv/bin/pip" install -r requirements-build.txt # 安装 scons、ninja、meson 等构建工具
source "$DAOS_SRC/venv/bin/activate" # 激活虚拟环境,让 scons 进入 PATH
scons --jobs "$(nproc)" --config=force --build-deps=yes install # 用全部 CPU 核编译 DAOS 及依赖,产物装入 install/ 目录
echo "构建完成,二进制位于:$DAOS_SRC/install/bin" # 打印产物位置,方便继续验证
运行方式(在 Rocky Linux 9.6/9.7 上,需能联网):
chmod +x build-daos-el9.sh # 给脚本加上可执行权限
sudo bash ./build-daos-el9.sh # 以 root 身份执行(首次编译较久,会下载并编译 SPDK 等依赖)
/opt/daos-src/install/bin/daos_server version # 编译完成后验证二进制可用
要换目录或换版本时用 sudo env DAOS_SRC=/data/daos DAOS_VER=master bash ./build-daos-el9.sh;验证命令中的路径也要同步替换。
docs/QSG/build_from_scratch.md 里对应的是 install-el9.sh / install-leap15.sh / install-ubuntu.sh 三个入口和同一条 scons 命令。注意:从源码安装比 RPM 多一堆手工活——/run/daos_server 目录、daos_server_helper 的 setuid、memlock、vm.max_map_count、socket buffer 都得自己配,官方在 predeployment_check.md 末尾明确说”RPM 安装是生产首选,手工安装适合开发与 PoC”。所以哪怕你走开发路线,也建议用 RPM 起服务、用源码只做代码改动和验证。
4.2 示例二:上线前环境自检(完整脚本)
这个脚本只读不写,把前面速查表里的项目一次性过一遍,适合每台的服务器和客户端都跑一次。逐行注释,可直接保存为 daos-precheck.sh:
#!/usr/bin/env bash # 指定用 bash 解释执行本脚本
ok() { printf ' [OK] %s\n' "$1"; } # 定义函数:打印检查通过的信息
warn() { printf ' [WARN] %s\n' "$1"; } # 定义函数:打印需要人工确认的信息
echo "=== 1. 操作系统与架构 ===" # 打印第一组检查的标题
if [[ -f /etc/os-release ]]; then # 确认系统提供了标准的发行版信息文件
. /etc/os-release # 读入 PRETTY_NAME 等变量
echo " PRETTY_NAME = ${PRETTY_NAME:-unknown}" # 打印发行版全名,人工对照支持矩阵
else # 没有 os-release 文件的分支
warn "找不到 /etc/os-release,请手动确认发行版" # 提示人工确认
fi # 结束发行版判断
echo " uname -m = $(uname -m)" # 打印 CPU 架构,必须是 x86_64
echo " kernel = $(uname -r)" # 打印内核版本,便于与 DOCA-OFED 兼容性对照
echo "=== 2. IOMMU 与透明大页 ===" # 打印第二组检查的标题
if grep -qE 'intel_iommu=on|amd_iommu=on' /proc/cmdline; then # 检查内核启动参数是否开启了 IOMMU
ok "IOMMU 已在内核命令行启用" # 已开启则通过
else # 未开启的分支
warn "未检测到 intel_iommu=on,SPDK/VFIO 直通 NVMe 可能失败" # 提示需要改 grub 并重启
fi # 结束 IOMMU 判断
thp=$(cat /sys/kernel/mm/transparent_hugepage/enabled 2>/dev/null || echo unknown) # 读取 THP 当前状态,读不到则记为 unknown
echo " THP = ${thp}" # 打印 THP 状态,期望出现 [never]
echo "=== 3. 内存相关内核参数 ===" # 打印第三组检查的标题
echo " nr_hugepages = $(sysctl -n vm.nr_hugepages 2>/dev/null || echo NA)" # 打印已分配的大页数
echo " vm.max_map_count = $(sysctl -n vm.max_map_count 2>/dev/null || echo NA)" # 打印 mmap 区域上限,建议约 1000000
echo " net.core.rmem_max = $(sysctl -n net.core.rmem_max 2>/dev/null || echo NA)" # 打印 socket 接收缓冲上限,应 >= 1MB
echo " ulimit -l (memlock) = $(ulimit -l)" # 打印内存锁定上限,期望 unlimited
echo "=== 4. 存储设备 ===" # 打印第四组检查的标题
if command -v nvme >/dev/null 2>&1; then # 检查是否安装了 nvme-cli 工具
nvme list 2>/dev/null | head -n 20 # 列出 NVMe 设备,核对型号、容量与 PCI 地址
else # 未安装 nvme-cli 的分支
warn "未安装 nvme-cli,可用 lspci | grep -i nvme 粗查" # 给出替代检查命令
fi # 结束存储检查
echo "=== 5. 网络与时间 ===" # 打印第五组检查的标题
echo " fabric 接口:" # 提示下面列出网卡
ip -br link 2>/dev/null | head -n 20 # 简要列出网络接口,确认 fabric_iface 名称
if command -v chronyc >/dev/null 2>&1; then # 检查是否安装了 chrony 客户端
chronyc tracking 2>/dev/null | head -n 5 # 打印时间同步状态,确认时钟已同步
else # 未安装 chrony 的分支
warn "未检测到 chronyc,请用 timedatectl 确认 NTP 已启用" # 给出替代检查命令
fi # 结束时间同步检查
echo "=== 6. 控制面端口 ===" # 打印第六组检查的标题
if command -v ss >/dev/null 2>&1; then # 检查是否有 ss 工具
ss -ltn '( dport = :10001 )' 2>/dev/null # 查看 10001 端口监听情况,未启动时为空属正常
fi # 结束端口检查
echo "=== 检查结束:请把 [WARN] 项与支持矩阵逐条核对 ===" # 打印结束提示
运行方式(无需 root,纯只读):
chmod +x daos-precheck.sh # 给脚本加上可执行权限
bash ./daos-precheck.sh # 在每台服务器和客户端上执行,逐条核对输出
4.3 示例三:单机学习环境的完整配置
A 档最省事的起步方式:把 SCM 用 tmpfs 模拟、NVMe 用文件模拟,ofi+tcp 走普通网卡。下面配置改自仓库的 utils/config/examples/daos_server_local.yml,逐行注释,保存为 /etc/daos/daos_server.yml:
name: daos_server # DAOS 系统名,同一系统内所有节点必须一致
mgmt_svc_replicas: ['localhost'] # 管理服务副本,单机实验环境就填本机;生产建议 3 至 5 台
provider: ofi+tcp # 数据面网络 provider,开发用 TCP 即可,有 RDMA 再换 ucx+dc_x 等
control_log_file: /var/log/daos/daos_server.log # 控制面日志路径,需保证 daos_server 用户可写
transport_config: # 控制面通信的 TLS 配置段
allow_insecure: true # 仅实验环境关闭证书校验;生产必须生成证书并设为 false
telemetry_port: 9191 # Prometheus 遥测端口,学习阶段可用来观察指标
engines: # 数据面 engine 列表,单机先起一个
- pinned_numa_node: 0 # 把 engine 绑到 NUMA 0,双路机器可按路起多个 engine
targets: 1 # I/O 线程数;真实 NVMe 环境按 4 至 32 调整,每 target 预留 1GiB 大页
nr_xs_helpers: 0 # 校验和/RPC 卸载线程数,EC 场景建议约 targets 的四分之一
fabric_iface: eth0 # 数据面网卡名,务必改成 `ip -br link` 查到的真实名称
fabric_iface_port: 31416 # 数据面监听端口,多 engine 时每个用不同端口
log_file: /var/log/daos/daos_engine.0.log # engine 日志路径
env_vars: # 传给 engine 的环境变量列表
- FI_SOCKETS_MAX_CONN_RETRY=1 # TCP provider 连接重试次数,避免学习环境里长时间等待
- FI_SOCKETS_CONN_TIMEOUT=2000 # TCP provider 连接超时,单位毫秒
storage: # 存储分层定义,顺序固定:先 SCM 层,再 NVMe 层
- class: ram # SCM 用 tmpfs(内存)模拟,断电不保数据,仅限学习
scm_size: 8 # tmpfs 大小,单位 GiB;生产用 MD-on-SSD 需按容量规划
scm_mount: /mnt/daos # tmpfs 挂载点,目录需存在
- class: file # NVMe 用普通文件 + Linux AIO 模拟
bdev_size: 16 # 模拟盘大小,单位 GiB
bdev_list: [/tmp/daos-bdev] # 模拟盘文件路径,需可写且剩余空间充足
运行方式(Rocky 9.6/9.7,用官方 RPM,避免源码安装的手工配置)。这一段从空系统开始,包含仓库、依赖、三份配置和启动,不需要假设前面做过任何一步:
sudo wget -O /etc/yum.repos.d/daos-packages.repo https://packages.daos.io/v2.8/EL9/packages/x86_64/daos_packages.repo # 配置 DAOS 2.8 的 EL9 官方 RPM 仓库
sudo rpm --import https://packages.daos.io/RPM-GPG-KEY # 导入官方包签名公钥,否则 dnf 会拒绝安装
sudo dnf install -y epel-release # 启用 EPEL,部分依赖包来自该源
sudo dnf install -y mercury-libfabric # 安装 ofi+tcp 所需的 Mercury 网络插件
sudo dnf install -y daos-admin daos-server daos-client # 单机同时装管理端、服务端与客户端
sudo mkdir -p /etc/daos /var/log/daos /mnt/daos # 创建配置、日志与 tmpfs 挂载目录
sudo cp ./daos_server.yml /etc/daos/daos_server.yml # 安装上一步写好的服务端配置
sudo tee /etc/daos/daos_control.yml >/dev/null <<'EOF' # 写 dmg 管理端配置,单机实验关闭 TLS
name: daos_server # 系统名,必须与 daos_server.yml 一致
hostlist: ['localhost'] # 管理命令连接本机
port: 10001 # 控制面默认端口
transport_config: # 控制面通信设置
allow_insecure: true # 仅实验环境;生产要签发证书并设为 false
EOF
sudo tee /etc/daos/daos_agent.yml >/dev/null <<'EOF' # 写客户端代理配置,同样关闭 TLS
name: daos_server # 系统名,必须与服务端一致
access_points: ['localhost'] # 客户端从本机接入点获取系统信息
port: 10001 # 控制面默认端口
transport_config: # 控制面通信设置
allow_insecure: true # 仅实验环境;生产要签发证书并设为 false
EOF
sudo systemctl start daos_server # 启动 DAOS 服务端
dmg storage format # 首次使用必须格式化(会清空模拟盘数据,交互式确认时可加 --force)
sudo systemctl start daos_agent # 启动客户端代理
daos system query --verbose # 验证系统连通,看到 Joined 状态即成功
仓库地址与安装顺序依据 v2.8.1 标签的 docs/QSG/setup_rhel.md,三份配置模板来自 utils/config/daos_control.yml、utils/config/daos_agent.yml。生产环境务必反过来做:生成并分发 /etc/daos/certs/ 下的证书,把三份配置里的 allow_insecure 全部改回 false,mgmt_svc_replicas 换成 3–5 台不同故障域的主机。
4.4 运维视角:版本与 OS 升级的顺序
最后用一张时序图说明”为什么顺序不能乱”。docs/release/upgrading.md 要求 2.8.x → 3.0 整体停机、所有节点同时升级:
sequenceDiagram
autonumber
participant Ops as 运维
participant All as 全部服务器 / 客户端 / 管理节点
participant Os as 操作系统与固件
participant Rp as DAOS RPM 与网络栈
participant Sys as DAOS 系统
Ops->>Sys: 按 stopping-daos.md 完整停止系统
Ops->>Os: 先升 OS 到 3.0 支持矩阵内的版本
Ops->>Os: 升 DOCA-OFED / SHS 并刷新网卡固件
Note over Ops,Os: Slingshot 环境还要同步更新 LD_LIBRARY_PATH
Ops->>Rp: 配置新版本 RPM 仓库,执行 dnf 或 zypper update
Ops->>All: 确认所有节点 DAOS 版本一致,管理节点同版本
Ops->>Sys: 按 starting-daos.md 重启系统
Ops->>Sys: 检查并升级 pool version,或迁移数据到新池
Note over Ops,Sys: 低于 2.8 的旧环境必须先升到 2.8.x 再走本流程
五、常见坑速查
| 现象 | 根因 | 处理 |
|---|---|---|
| 官方 RPM 仓库里找不到对应目录 | 用了 Ubuntu / EL8 / Leap 15.7(该版本根本不存在)等未支持系统 | 换成 EL 9.6/9.7 或 Leap 15.6 / SLES 15 SP6/SP7 |
daos_engine: EAL: cannot set up DMA remapping |
memlock 太小 |
ulimit -l unlimited,用 systemd 时确认 LimitMEMLOCK=infinity |
spdk_pci_event_listen: Failed to set socket option |
socket 接收缓冲 < 1 MB | 调高 rmem_default / rmem_max |
mkdir /var/run/daos_server: permission denied |
源码安装缺运行时目录 | 用 RPM 安装,或按 predeployment_check.md 建目录 / 配 tmpfiles.d |
| 性能忽高忽低、大页分配失败 | THP 开着或大页运行时才分配导致碎片 | 关 THP,开机用 hugepages=N 预分配 |
| 跨路访问导致带宽不达标 | engine 与 NVMe / 网卡不在同一 NUMA | 设 pinned_numa_node,每 socket 一个 engine |
| 升级后客户端连不上 | 忽略 N±1 互操作,或管理节点版本没跟上 | 客户端与服务器最多差一个次版本,dmg 必须与服务器同版 |
| IB 网络大规模下不稳定 | 用了旧 ucx+dc_mlx5 或 inbox OFED |
2.8 用 DOCA-OFED 3.2.1 + ucx+dc_x + mercury 2.4.1 |
| 照抄 QSG 的 QEMU/Docker 文档跑不起来 | 文档仍写 Rocky 8.9 / DAOS 2.6,已落后于 2.8 支持矩阵 | 镜像换成 Rocky 9.6/9.7,DAOS 换 2.8.1 |
六、总结
- 版本选 2.8.1,系统选 EL 9.6 / 9.7(或 SLES 15 SP6/SP7、Leap 15.6),这是当前唯一”稳定版 × 被验证系统”的组合。3.0 还在草案阶段,而且草案里对 EL 9.8 的口径自相矛盾,别拿来定方案。
- Ubuntu 只能编译、不能部署;CentOS 全系、RHEL 7/8、Fedora、ARM64、RHEL 10 都不在支持清单内。同集群服务器必须同发行版同版本,客户端可不同发行版但版本要遵守 N±1。
- 新硬件一律走 MD-on-SSD:傲腾 PMem 300 系列已被取消、产品线停产,2.8 的 Phase 1 已可生产使用。DRAM 通道插满、NVMe 分好
wal/meta/data角色、留意wal与data不能同 tier。 - 记住几个数字:SCM:NVMe ≥ 6%、每 target 1 GiB 大页、NVMe 4KiB LBA、targets 4–32、
nr_xs_helpers≈ targets/4、控制面端口 10001、架构上限 65536 targets。 - 研究的正确起步姿势:A 档 Rocky 9.6/9.7 虚拟机 + 官方 RPM +
class: ram/class: file模拟,先把 pool/container/dfuse 和日志跑熟;要碰性能、EC、rebuild 再上 B 档真 NVMe 与 RDMA。模拟配置只适合学习,别拿它的性能数字做结论。
参考来源
- 本地仓库
D:\Codes\github\daos,master@788f8773(2026-11-09):docs/release/support_matrix.draft.md、docs/release/release_notes.draft.md、docs/release/upgrading.md、docs/release/version_interop.md、docs/admin/hardware.md、docs/admin/deployment.md、docs/admin/predeployment_check.md、docs/QSG/*、utils/config/daos_server.yml、utils/config/examples/*.yml、.github/workflows/ci2.yml - 历史版本标签:
v2.0.0(docs/release/support_matrix_v2_0.md)、v2.2.0、v2.4.0、v2.6.5、v2.8.1的docs/release/support_matrix.md与docs/release/release_notes.md - 官网:https://daos.io/;在线文档:https://docs.daos.io/latest/;包仓库:https://packages.daos.io/v2.8/