第 8/20 天
引言:存储池——Ceph 数据组织的核心抽象
在前面的章节中,我们已经完成了 Monitor、Manager 和 OSD 节点的部署,并深入解析了 CRUSH Map 的故障域规划。此时集群已经具备了存储数据的硬件基础,但数据究竟如何被组织、分发和管理?这就引出了 Ceph 架构中最关键的逻辑抽象层——存储池(Pool)。
存储池是 Ceph 对外提供存储服务的逻辑分区。每一个 Pool 拥有独立的副本策略、纠删码策略、PG 数量、CRUSH 规则集和 QoS 配置。RBD 镜像、RGW 对象、CephFS 文件系统都建立在 Pool 之上。而 Placement Group(PG) 则是 Pool 内部的数据分片单元,是 CRUSH 算法进行数据映射的粒度——对象先被哈希到某个 PG,再由 CRUSH 将 PG 映射到一组 OSD。
PG 数量的规划直接影响集群的均衡度、恢复速度和资源开销。PG 太少会导致数据倾斜和单 OSD 压力过大;PG 太多则会增加 Monitor 和 OSD 的内存占用及 Peering 开销。本篇将系统讲解 Pool 与 PG 的架构原理,并在 Ubuntu 24.04 LTS 上基于 Ceph Squid v19 进行完整的实战部署。
架构与原理:Pool、PG 与数据映射机制
存储池的分层架构
Ceph 的数据组织采用三级抽象:Pool → PG → OSD,整个映射流程如下:
客户端写入对象
│
▼
Pool(逻辑分区,绑定 CRUSH Rule + 副本/EC 策略)
│
▼
PG(Placement Group,数据分片,CRUSH 映射的最小粒度)
│
▼
OSD Set(Primary + Replicas,实际存储节点)
│
▼
BlueStore(底层存储引擎,写 RocksDB + WAL)
关键概念解析
| 概念 | 说明 | 生产意义 |
|---|---|---|
| Pool | 逻辑存储分区,绑定副本策略和 CRUSH 规则 | 数据隔离、多租户、不同 SLA |
| PG (Placement Group) | 对象的分组容器,CRUSH 映射粒度 | 决定数据分布的均衡度 |
| PGP | 用于 Placement 的 PG 数(PG 的上限) | 控制实际数据分布的广度 |
| PG Num | Pool 配置的 PG 总数 | 影响 Peering 速度和内存占用 |
| CRUSH Rule | 定义数据如何选择故障域 | 跨机架/机房分布 |
| Replicated Pool | 多副本存储(通常 3 副本) | 高 IOPS、低延迟场景 |
| Erasure Coded Pool | 纠删码存储(k+m 数据块) | 冷数据、大对象存储 |
PG 映射的完整流程
当客户端写入一个对象时,Ceph 的映射过程分为以下步骤:
- 对象 → PG:通过
hash(对象名) & mask = pgid计算对象所属的 PG,其中 mask 为pg_num - 1 - PG → Up Set:CRUSH 算法根据 PG ID 和 CRUSH Rule 计算出理论上应该承载该 PG 的 OSD 列表
- Up Set → Acting Set:考虑 OSD 的状态(up/down),确定实际写入的 OSD 集合
- Primary OSD 接收写入:Acting Set 中的第一个 OSD 为主 OSD,负责接收客户端写入并同步给副本 OSD
PG 数量的黄金公式
Ceph 官方推荐的 PG 数量计算公式为:
PG总数 = (OSD数量 × 每OSD目标PG数) / 副本数
每OSD目标PG数通常为 100~200(Squid 版本推荐 100 左右)
例如:30 个 OSD、3 副本,则每个 Pool 建议的 PG 数为 (30 × 100) / 3 = 1000。再根据 Pool 存储的数据量占比进行分配。
PG 自动调优机制
从 Ceph Nautilus(v14)起引入了 PG Auto-scaling 机制,Manager 的 pg_autoscaler 模块会根据每个 Pool 的实际数据量、OSD 数量和目标 PG 数自动调整 pg_num。Squid v19 中这一机制默认开启,极大减轻了运维负担。

部署实战:创建存储池与 PG 规划
环境准备
假设我们已完成前 7 天的部署,当前集群状态如下:
# 查看集群整体健康状态
ceph -s
# 查看当前 OSD 数量和分布
ceph osd tree
# 查看 Manager 模块状态
ceph mgr module ls
预期输出中集群状态为 HEALTH_OK,且已有多个 OSD 处于 up/in 状态。
检查 PG 自动调优模块
# 启用 pg_autoscaler 模块(Squid 默认已启用)
ceph mgr module enable pg_autoscaler
# 查看当前所有 Pool 的 PG 调优建议
ceph osd pool autoscale-status
输出示例:
POOL SIZE TARGET SIZE RATE RAW CAPACITY BIAS PG_NUM NEW PG_NUM AUTOSCALE
.mgr 0.5G 3.0 4560G 1.0 8 8 on
cephfs_data 0 3.0 4560G 1.0 32 32 on
rbd-pool 100G 3.0 4560G 1.0 64 64 on
手动创建副本存储池
在生产环境中,很多场景需要精确控制 PG 数量(如禁用自动调优或进行初始规划):
# 语法:ceph osd pool create <pool_name> <pg_num> [<pgp_num>] [replicated|erasure]
# 创建 RBD 专用存储池,3 副本,PG=128
ceph osd pool create rbd-pool 128 128 replicated
# 设置副本数为 3(生产环境最低要求)
ceph osd pool set rbd-pool size 3
# 设置最小副本数(低于此值拒绝写入)
ceph osd pool set rbd-pool min_size 2
# 关联应用类型(Squid 强制要求,否则告警)
ceph osd pool application enable rbd-pool rbd
PG 数量计算脚本
在创建 Pool 前,使用以下脚本计算合理的 PG 数量:
#!/usr/bin/env python3
"""Ceph PG 数量计算器 – 生产环境 PG 规划工具"""
import math
def calculate_pg_num(osd_count, replica_count, pool_data_ratio=1.0, target_pg_per_osd=100):
"""
计算 Pool 的推荐 PG 数量
参数:
osd_count: 集群 OSD 总数
replica_count: 副本数(replicated pool 为副本数,EC pool 为 k+m)
pool_data_ratio: 该 Pool 预计存储数据占总数据量的比例 (0.0~1.0)
target_pg_per_osd: 每个 OSD 的目标 PG 数 (Squid 推荐 100)
返回:
推荐的 PG 数(2 的幂次)
"""
raw_pgs = (osd_count * target_pg_per_osd * pool_data_ratio) / replica_count
# 向上取最近的 2 的幂次
power = math.ceil(math.log2(max(raw_pgs, 1)))
recommended = 2 ** power
# Squid 限制单个 Pool 最大 pg_num
recommended = min(recommended, 32768)
recommended = max(recommended, 8)
print(f"OSD 数量: {osd_count}")
print(f"副本数: {replica_count}")
print(f"数据占比: {pool_data_ratio * 100:.0f}%")
print(f"目标 PG/OSD: {target_pg_per_osd}")
print(f"原始计算 PG 数: {raw_pgs:.1f}")
print(f"推荐 PG 数 (2^n): {recommended}")
print(f"建议命令: ceph osd pool create <pool> {recommended} {recommended}")
return recommended
# 示例:30 个 OSD,3 副本,该 Pool 占 40% 数据量
calculate_pg_num(osd_count=30, replica_count=3, pool_data_ratio=0.4)
运行结果:
OSD 数量: 30
副本数: 3
数据占比: 40%
目标 PG/OSD: 100
原始计算 PG 数: 400.0
推荐 PG 数 (2^n): 512
建议命令: ceph osd pool create <pool> 512 512
创建并配置 CephFS 数据池
CephFS 需要 metadata 池和数据池,metadata 池建议使用低延迟、高 IOPS 配置:
# 创建 CephFS 元数据池(PG 较少,延迟优先)
ceph osd pool create cephfs_metadata 32 32
ceph osd pool set cephfs_metadata size 3
# 创建 CephFS 数据池(PG 较多,吞吐优先)
ceph osd pool create cephfs_data 128 128
ceph osd pool set cephfs_data size 3
# 创建 CephFS 文件系统
ceph fs new stellardata cephfs_metadata cephfs_data
# 为 CephFS 池关联应用类型
ceph osd pool application enable cephfs_metadata cephfs
ceph osd pool application enable cephfs_data cephfs
验证 Pool 状态
# 查看所有 Pool 的详细信息
ceph osd pool ls detail
# 查看 PG 映射与分布状态
ceph pg dump | head -20
# 检查 PG 分布是否均衡(每个 OSD 上的 PG 数)
ceph osd df
# 查看特定 Pool 的 PG 状态
ceph pg ls-by-pool rbd-pool
ceph osd df 输出示例:
ID CLASS WEIGHT REWEIGHT SIZE RAW USE DATA OMAP META AVAIL %USE PGS
0 hdd 1.00000 1.00000 1000G 120G 100G 256M 1.2G 880G 12.0 64
1 hdd 1.00000 1.00000 1000G 122G 101G 256M 1.3G 878G 12.2 64
2 ssd 1.00000 1.00000 1000G 118G 98G 256M 1.1G 882G 11.8 64
…

关键配置参数详解
# ceph.conf 中的 Pool 相关参数(通常通过 ceph tell 动态设置)
# 注意:Squid 版本推荐使用 ceph config set 命令而非编辑 ceph.conf
# — PG 相关参数 —
# osd_pool_default_pg_num: 新建 Pool 的默认 PG 数
ceph config set global osd_pool_default_pg_num 32
# osd_pool_default_pgp_num: 新建 Pool 的默认 PGP 数(通常与 pg_num 相同)
ceph config set global osd_pool_default_pgp_num 32
# osd_pool_default_size: 默认副本数
ceph config set global osd_pool_default_size 3
# osd_pool_default_min_size: 默认最小副本数(低于此值写操作被拒绝)
ceph config set global osd_pool_default_min_size 2
# — PG 自动调优参数 —
# mon_max_pg_per_osd: 每个 OSD 承载的最大 PG 数(Squid 默认 250)
ceph config set mon mon_max_pg_per_osd 250
# — 恢复参数 —
# osd_max_backfills: 同时进行 Recovery 的 PG 数上限
ceph config set osd osd_max_backfills 4
# osd_recovery_max_active: 每个 OSD 同时活跃的恢复操作数
ceph config set osd osd_recovery_max_active 8
存储池配额与 QoS 限制
生产环境中多租户隔离需要设置 Pool 级别的配额:
# 设置 Pool 最大存储容量为 500GB
ceph osd pool set-quota rbd-pool max_bytes 536870912000
# 设置 Pool 最大对象数为 100 万
ceph osd pool set-quota rbd-pool max_objects 1000000
# 取消配额限制
ceph osd pool set-quota rbd-pool max_bytes 0
ceph osd pool set-quota rbd-pool max_objects 0
# 查看当前配额设置
ceph osd pool get-quota rbd-pool
生产环境注意事项与踩坑提示
1. PG 数量不可随意缩减
PG 数量只能增加,不能随意减少。ceph osd pool set <pool> pg_num <new> 增大 PG 数时会触发数据重平衡(split),但减小 PG 数会导致数据不可逆迁移,生产环境中应避免此操作。如果确实需要调整,必须通过新建 Pool + 数据迁移的方式完成。
2. PGP Num 必须与 PG Num 同步
pgp_num 控制实际进行数据分布的 PG 数。增大 pg_num 后必须同步增大 pgp_num,否则新 PG 不会接收数据。正确做法是分步操作:
# 先增大 pg_num(创建新 PG,但数据暂不迁移)
ceph osd pool set rbd-pool pg_num 256
# 再增大 pgp_num(触发数据实际迁移到新 PG)
ceph osd pool set rbd-pool pgp_num 256
3. 警惕 PG Peering 风暴
大量 OSD 同时重启或网络抖动会导致大量 PG 进入 degraded 或 peering 状态。Squid 版本引入了 PG peering 限流机制,但仍建议在批量重启前设置:
# 降低恢复并发度,减少 Peering 压力
ceph config set osd osd_max_backfills 1
ceph config set osd osd_recovery_max_active 3
4. SSD 与 HDD 混合部署的 PG 差异
当集群中同时存在 SSD 和 HDD 时,不同设备的 PG 负载差异巨大。SSD 设备能承受更高 PG 数(因为 Peering 速度快),而 HDD 设备建议减少 PG 数以避免磁盘抖动。建议使用 CRUSH Device Class 将不同类型设备分配到不同 Pool。
5. PG 自动调优的局限性
pg_autoscaler 虽然方便,但在大规模集群(500+ OSD)中自动调优可能反应迟缓。建议在大规模生产环境中将关键 Pool 的 pg_autoscale 设为 off 并手动管理 PG 数量,避免自动调优在业务高峰期触发大规模数据迁移。
6. Erasure Coded Pool 的 PG 规划特殊考量
EC Pool 的 PG 计算公式中”副本数”应替换为 k + m(数据块+校验块)。例如 8+3 EC 策略,计算时使用 11 作为除数,而非 3。这会导致同样数据量下 EC Pool 的 PG 数远低于 Replicated Pool。
常见问题
Q: 新建 Pool 后 ceph -s 报 HEALTH_WARN “application not enabled on 1 pool(s)”,如何处理?
A: Squid 版本要求每个 Pool 必须关联应用类型(rbd、cephfs、rgw 或自定义)。执行 ceph osd pool application enable <pool_name> <app_type> 即可消除告警。例如 RBD 池用 rbd,CephFS 池用 cephfs,RGW 池用 rgw。
Q: PG 增加后集群一直在 rebalancing,业务卡顿严重怎么办?
A: 这是正常的 Recovery 过程,但可以通过参数控制恢复速率。使用 ceph config set osd osd_max_backfills 1 降低并发,设置 osd_recovery_op_priority 1 降低恢复线程优先级让业务 I/O 优先。也可通过 ceph osd set norebalance 暂时停止重平衡,业务低峰期用 ceph osd unset norebalance 恢复。
Q: autoscale-status 显示 NEW_PG_NUM 比 PG_NUM 大很多,是否应该手动增加?
A: 不建议手动增加。pg_autoscaler 会自动分批增加 PG 数(每次翻倍),避免一次性迁移大量数据。如果急需调整,可以手动设置 ceph osd pool set <pool> pg_num <new> 并同步设置 pgp_num,但需确保在业务低峰期执行。
总结
本篇系统讲解了 Ceph 存储池与 PG 的核心架构:Pool 是逻辑分区,PG 是 CRUSH 映射的最小粒度,二者共同决定了数据的分布策略。我们掌握了 PG 数量的黄金计算公式 (OSD × target_pg) / replica,了解了 PG 自动调优的工作机制,并通过实战完成了副本池、CephFS 数据池的创建与配额配置。
生产环境中最关键的认知是:PG 数量是集群健康度的核心调节器——过多增加内存和 Peering 开销,过少导致数据倾斜。理解了 Pool 和 PG,我们才能进入下一篇更深入的话题——副本策略与纠删码策略的深度对比。
下期预告
明天我们将发布第 9 天:副本与纠删码存储池策略对比实战。将深入对比 Replicated Pool 和 Erasure Coded Pool 在存储效率、读写性能、恢复速度上的差异,并通过实际部署 EC Pool 来演示如何在保证数据可靠性的前提下将存储成本降低 50% 以上。
系列目录
- ✅ 第 1 天:架构概述与生产环境选型指南
- ✅ 第 2 天:Ubuntu 系统准备:内核调优与磁盘规划
- ✅ 第 3 天:Cephadm 部署工具详解与集群引导初始化
- ✅ 第 4 天:Monitor 节点部署与高可用配置
- ✅ 第 5 天:Manager 节点部署与模块启用
- ✅ 第 6 天:OSD 存储节点部署:BlueStore 配置与磁盘管理
- ✅ 第 7 天:CRUSH Map 架构解析与故障域规划
- 📌 第 8 天:存储池(Pool)创建与 PG 数量规划(本文)
- 🔜 第 9 天:副本与纠删码存储池策略对比实战
- 🔜 第 10 天:Ceph 块存储 RBD 配置与生产实践
- 🔜 第 11 天:Ceph 对象存储 RGW 网关部署与 S3 兼容
- 🔜 第 12 天:CephFS 分布式文件系统部署与挂载
- 🔜 第 13 天:Ceph 网络架构:集群网络与公共网络分离
- 🔜 第 14 天:Ceph 认证体系 cephx 与用户权限管理
- 🔜 第 15 天:Ceph 集群监控:Prometheus + Grafana + 内置仪表盘
- 🔜 第 16 天:Ceph 性能调优:OSD 参数与缓存分层
- 🔜 第 17 天:Ceph 集群扩容实战:OSD 动态添加与 CRUSH 重平衡
- 🔜 第 18 天:Ceph 高可用与容灾设计:多副本、跨机房与异地灾备
- 🔜 第 19 天:Ceph 故障排查与数据恢复实战
- 🔜 第 20 天:Ceph 生产环境升级维护与版本迭代策略

















暂无评论内容