查看日志
# 查看参数来源(谁覆盖了谁)
ceph config log
这是一个非常专业、非常"运维工程化"的问题 ,已经不只是"会用 Ceph",而是 如何做集群级配置对比与审计 。
我会给你一套可落地、可自动化、可对比的方法,而不是零散命令。
核心结论先给出
在 cephadm 管理的集群中:
- ❌ 不存在一个"完整配置文件"可以直接拷走对比
- ✅ 必须从 4 个维度导出配置快照,组合后才是"集群真实配置"
这 4 个维度分别是:
1️⃣ 集群级配置(ceph config DB)
2️⃣ 服务部署规格(orchestrator spec)
3️⃣ MON / OSD 拓扑与元数据
4️⃣ 主机与设备映射信息
下面我按 "导出什么 → 怎么导出 → 如何对比" 的逻辑讲。
一、整体导出思路(你要对比什么)
如果你想对比 两个集群 A / B 的 OSD、MON 等配置,合理的对比对象是:
| 对比项 | 命令来源 |
|---|---|
| MON 数量 / IP / quorum | ceph mon dump |
| OSD 数量 / 分布 / 权重 | ceph osd tree |
| OSD 磁盘映射 | ceph osd metadata |
| 生效配置参数 | ceph config dump |
| cephadm 部署规则 | ceph orch ls |
| 主机与磁盘 | ceph orch device ls |
👉 不是对比 /etc/ceph/ceph.conf
二、推荐的"标准导出目录结构"
在 每个集群上分别执行:
bash
mkdir -p ceph-config-export/{mon,osd,orch,config,host}
cd ceph-config-export
这样导出的内容可以直接 diff -r。
三、导出 MON 相关配置(集群控制面)
1️⃣ MON 拓扑与 quorum
bash
ceph mon dump > mon/mon_dump.txt
ceph mon stat > mon/mon_stat.txt
用于对比:
- MON 数量
- IP / 端口
- 是否启用 v2
2️⃣ MON 生效配置
bash
ceph config dump | grep '^mon\.' > mon/mon_config_dump.txt
或者更全面:
bash
ceph config show mon > mon/mon_config_show.txt
四、导出 OSD 相关配置(最重要)
1️⃣ OSD 拓扑结构(必做)
bash
ceph osd tree > osd/osd_tree.txt
用于对比:
- OSD 分布
- host / rack 结构
- 权重是否一致
2️⃣ OSD 全量元数据(关键)
bash
ceph osd metadata > osd/osd_metadata_all.json
这是 对比 OSD 的"黄金文件",包含:
- OSD → 主机
- 使用的磁盘
- BlueStore / WAL / DB
- Ceph 版本
3️⃣ 单个 OSD 配置参数(可选但专业)
bash
for id in $(ceph osd ls); do
ceph config show osd.$id > osd/osd_${id}_config.txt
done
用于发现:
- 是否有单 OSD 特殊调优
五、导出集群"真实生效配置"(非常关键)
1️⃣ 导出 config DB
bash
ceph config dump > config/config_dump.txt
这是 最终生效配置的权威来源。
📌 对比时重点看:
who = globalwho = osdwho = mon
2️⃣ 导出 config diff(更高级)
bash
ceph config log > config/config_log.txt
用于审计:
- 哪些配置被改过
- 是否有人为调优差异
六、导出 cephadm / orchestrator 配置(决定"部署方式")
1️⃣ 服务规格(Spec)
bash
ceph orch ls --format json > orch/orch_ls.json
重点关注:
- mon / osd 的 placement
- 是否使用 osd spec
2️⃣ 服务运行状态
bash
ceph orch ps --format json > orch/orch_ps.json
3️⃣ 磁盘设备清单(非常重要)
bash
ceph orch device ls --format json > host/device_ls.json
用于对比:
- 哪些磁盘被用
- 哪些磁盘空闲
- 设备命名差异
七、主机层信息(辅助但很有价值)
bash
ceph orch host ls --format json > host/host_ls.json
八、如何对比两个集群(实操建议)
假设你有:
text
clusterA/ceph-config-export
clusterB/ceph-config-export
1️⃣ 直接目录级对比
bash
diff -ruN clusterA clusterB | less
2️⃣ 对 JSON 做结构化对比(推荐)
bash
jq -S . osd_metadata_all.json > a.json
jq -S . osd_metadata_all.json > b.json
diff a.json b.json
3️⃣ 你真正应该重点看的差异
| 类别 | 影响 |
|---|---|
| OSD 数量 / 权重 | 数据均衡 |
| public / cluster network | 网络性能 |
| osd_memory_target | 内存占用 |
| mon_allow_pool_delete | 安全性 |
| OSD 设备类型 | 性能 |
九、总结成一句"运维级认知"
Ceph 的"配置"是分散的、动态的、声明式的
真正可对比的不是一个文件,而是:
"状态 + 拓扑 + 生效参数 + 部署规则"的组合快照
十、如果你愿意,我可以进一步帮你
你下一步可以直接让我做这些事之一:
- ✅ 给你写一个 一键导出脚本(bash)
- ✅ 告诉你 哪些差异是"危险差异"
- ✅ 帮你 解读一份 diff 结果
- ✅ 指导你 把配置纳入 Git 管理
你可以直接说:
"帮我写一个导出脚本" 或
"我有两份导出结果,帮我分析差异"
这两个问题问得非常好,而且是"真正理解 Ceph 数据路径"必须要想清楚的问题 。
我会严格区分概念、给你因果链条,避免"似是而非"的理解。
下面我按问题分别讲,并在最后给你一个统一的数据路径认知模型。
一、问题 1
👉 Ceph 写数据时,条带化(striping)是一定会进行的吗?
结论先行
不是一定会进行"多对象条带化"
但:
逻辑上的 striping 机制一定存在,只是可能退化为"单对象"
这是一个非常关键的区分点。
1️⃣ Ceph 中"条带化"到底指什么?
在 Ceph 中,条带化发生在 RADOS 层,对象(object)是最小存储单元:
- 一个 RBD / RGW 对象
- 会被切分成多个 RADOS object
- 每个 object 再映射到 PG → OSD
这个过程叫 object striping。
2️⃣ 什么情况下"看起来没有条带化"?
默认 RBD 参数(很关键)
text
object_size = 4MB
stripe_unit = 4MB
stripe_count = 1
这意味着:
- 每个 object = 4MB
- stripe_count = 1 → 一次只写一个 object
- PG 映射只涉及 一个 PG
📌 结果:
逻辑上有 striping 机制,但实际 I/O 路径只有一个对象
这在表现上就像"没有条带化"。
3️⃣ 什么时候一定会发生"多对象条带化"?
只要满足任意一个条件:
✅ 情况一:数据大于 object_size
- 写入 > 4MB
- 自动拆成多个 object
✅ 情况二:显式配置 stripe_count > 1
bash
rbd create img --size 100G \
--stripe-unit 4M \
--stripe-count 8
这时:
- 一个 I/O 会被并发打到 多个 PG / OSD
- 明确发生 striping
4️⃣ 那 Ceph "一定会发生的"是什么?
一定会发生的是:
- 对象化(objectization)
- PG 映射
- CRUSH 分布
但不一定发生的是:
- 并行多对象 I/O
5️⃣ 一个非常重要的误区(你可能正好在想)
"Ceph 是不是像 RAID 0 一样,写一次一定拆成多份?"
不是。
- RAID striping 是块级
- Ceph striping 是对象级
- Ceph 允许退化成单对象 I/O
二、问题 2
👉 内核 rbd 明明更快,为什么还要 librbd?
这是一个架构层面的设计问题,不是"性能孰优孰劣"这么简单。
1️⃣ 先给出结论(非常重要)
kernel rbd 追求的是:
- 稳定
- 低延迟
- 标准块设备语义
librbd 追求的是:
- 灵活
- 可扩展
- 云 / 容器 / 用户态集成能力
👉 它们不是"替代关系",而是 定位不同。
2️⃣ 为什么 kernel rbd 按"道理"会更快?
数据路径对比(简化)
kernel rbd
App
↓
VFS
↓
rbd kernel driver
↓
RADOS
- 全在内核态
- 少一次用户态 ↔ 内核态切换
- page cache / bio 路径成熟
📌 优势:低延迟、小 I/O
librbd
App
↓
librbd (user space)
↓
librados
↓
kernel TCP
- 用户态 I/O
- 更多上下文切换
- 更多内存拷贝
📌 理论上延迟更高
3️⃣ 那为什么还要 librbd?(这是重点)
① 内核无法快速迭代新特性
内核 rbd:
- 必须跟随 Linux kernel 发布周期
- 功能非常保守
而 Ceph 是一个 快速演进的分布式系统。
② 大量 Ceph 高级特性只能在 librbd 中实现
例如:
| 功能 | kernel rbd | librbd |
|---|---|---|
| 快照链高级管理 | ❌ | ✅ |
| 镜像迁移 | ❌ | ✅ |
| 动态 QoS | ❌ | ✅ |
| 异步 I/O | 部分 | 完整 |
| RBD mirroring | ❌ | ✅ |
| 云平台集成 | ❌ | ✅ |
③ 云 / 容器环境根本无法用 kernel rbd
典型场景:
- Kubernetes(Rook / CSI)
- OpenStack(cinder)
- QEMU / libvirt
它们:
- 不能要求宿主机加载特定内核模块
- 不能控制内核版本
👉 只能用 librbd
④ 用户态带来的"可控性"是内核无法比的
librbd 支持:
- 用户级限流
- I/O hook
- trace / debug
- 与应用紧密绑定
这在云平台是 刚需。
4️⃣ 一个反直觉但真实的结论
在 大 I/O、并发、高队列深度 场景下:
librbd 不一定比 kernel rbd 慢
原因:
- 更激进的并发
- 更灵活的调度
- 更少内核锁争用
三、把两个问题统一起来看(核心认知模型)
Ceph 的数据路径本质是:
Block I/O
↓
Object mapping (striping optional)
↓
PG
↓
CRUSH
↓
OSD
而:
- striping 是否并行 → 取决于 object / stripe 配置
- kernel rbd vs librbd → 取决于"性能 vs 灵活性"的取舍
四、给你几个"工程级判断标准"
什么时候选 kernel rbd?
- 裸金属
- 单机性能敏感
- 功能需求简单
什么时候选 librbd?
- 云平台 / 容器
- OpenStack / K8s
- 需要高级 RBD 特性
五、如果你愿意继续深入
你可以接着问我:
- striping 参数如何影响 PG hot spot
- kernel rbd 和 librbd 的 一致性差异
- Ceph 写路径的 完整调用栈
- BlueStore 在条带化下的真实写放大
这些问题,已经是 Ceph 内核级理解 了。
可以,而且这是 RBD 性能调优中非常核心、但也最容易被误用的一组参数 。
我会按 "能不能设 → 怎么设 → 什么时候该设 → 设错会怎样" 四个层次给你讲清楚。
一、结论先给出(非常重要)
✅ 这三个参数都是"可以设置的"
❌ 但 只能在 RBD 镜像创建时设置
❌ 创建后不能修改
也就是说:
text
object_size
stripe_unit
stripe_count
属于 RBD 镜像的不可变布局参数(immutable layout)。
二、这三个参数分别控制什么(精准定义)
1️⃣ object_size
- 含义:RADOS object 的大小
- 默认值:4MB
- 作用层级 :
👉 决定 一个 RBD 对象 = 多大
2️⃣ stripe_unit
- 含义:一次写入在单个 object 内的 stripe 大小
- 默认 :等于
object_size - 作用层级 :
👉 决定 I/O 在 object 内如何切分
3️⃣ stripe_count
- 含义:一次 I/O 并行涉及多少个 object
- 默认:1
- 作用层级 :
👉 决定 是否发生多对象并行 striping
三、如何设置?(标准命令)
在创建 RBD 镜像时:
bash
rbd create testimg \
--size 100G \
--object-size 8M \
--stripe-unit 1M \
--stripe-count 8
或者显式写成字节:
bash
--object-size 8388608
四、参数之间必须满足的约束(非常重要)
❗ 这三个参数不是"随便配"的
必须满足:
text
stripe_unit × stripe_count ≤ object_size
否则:
text
rbd: error: invalid stripe parameters
合法 / 非法示例
| object_size | stripe_unit | stripe_count | 合法 |
|---|---|---|---|
| 4MB | 4MB | 1 | ✅ |
| 8MB | 1MB | 8 | ✅ |
| 4MB | 1MB | 8 | ❌ |
| 8MB | 4MB | 4 | ❌ |
五、如何查看一个已有 RBD 镜像的这些参数?
bash
rbd info pool/image
输出示例:
stripe unit: 4194304 B
stripe count: 1
object size: 4194304 B
六、什么时候应该改这些参数?
这是最容易踩坑的地方,我给你明确建议。
场景 1:随机小 I/O(数据库、VM 系统盘)
👉 不要改,默认就是最优解
text
object_size = 4MB
stripe_unit = 4MB
stripe_count = 1
原因:
- 减少对象碎片
- 减少 PG fan-out
- 减少锁争用
场景 2:顺序大 I/O(备份、日志、流媒体)
👉 可以增大并行 striping
示例:
text
object_size = 8MB
stripe_unit = 1MB
stripe_count = 8
效果:
- 单次 I/O 并发打到多个 OSD
- 吞吐量显著提升
场景 3:高并发虚拟机数据盘(谨慎)
- stripe_count 过大 → PG 热点
- 恢复时间变长
- rebalance 成本高
👉 只建议在 专用大盘池 使用
七、为什么"创建后不能改"?(底层原因)
因为:
- RBD 对象命名包含 stripe 信息
- 已存在 object 无法重排
- 修改等价于 重写整张盘
所以 Ceph 干脆禁止。
八、如果已经创建错了,怎么办?
唯一正确方式:
bash
rbd create newimg --object-size ...
rbd export oldimg old.img
rbd import old.img newimg
或者用:
bash
rbd deep copy
九、一个很重要但很多人忽略的事实
RBD striping ≠ 性能一定更好
错误配置会导致:
- OSD fan-out
- PG lock 放大
- 恢复时间成倍增长
十、给你一个"工程级判断口诀"
小 I/O 用默认,大吞吐才条带化
改参数之前,先想清楚 I/O 模型
如果你愿意继续深入
你可以接着问我:
- stripe 参数如何影响 PG 映射公式
- 为什么 object_size 改大反而可能变慢
- RBD striping 与 BlueStore 写放大的关系
- Ceph 在 NVMe 场景下的最佳 stripe 策略
这些已经是 Ceph 性能调优的核心区。