强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Ceph 存储运维完全指南 / 13 - 扩容与缩容

13 - 扩容与缩容

13.1 扩容概述

Ceph 支持在线不停机地添加节点和 OSD,新 OSD 加入后会自动触发数据再平衡(Rebalancing),将部分数据迁移到新 OSD 上。

扩容方式

方式 说明 场景
添加 OSD 在现有节点上添加新磁盘 单节点容量扩展
添加节点 添加新服务器和 OSD 集群整体扩容
替换大容量磁盘 逐个替换 OSD 磁盘 提升单节点容量
添加 SSD 缓存 添加 NVMe/SSD 做 WAL/DB 提升性能

13.2 添加 OSD

使用 cephadm(推荐)

# 查看可用磁盘
ceph orch device ls

# 方法一:自动发现所有可用磁盘
ceph orch apply osd --all-available-devices

# 方法二:指定节点和磁盘
ceph orch daemon add osd node3:/dev/sdd
ceph orch daemon add osd node3:/dev/sde

# 方法三:指定 WAL/DB 设备(混合存储)
ceph orch daemon add osd node3 --data /dev/sdb --wal /dev/nvme0n1p1 --db /dev/nvme0n1p2

# 方法四:使用设备过滤器
ceph orch apply osd --all-available-devices \
    --data-devices 'model:Samsung_SSD' \
    --wal-devices '/dev/nvme0n1' \
    --db-devices '/dev/nvme0n1'

# 查看 OSD 状态
ceph osd tree

手动添加 OSD

# 1. 准备磁盘
sudo wipefs --all /dev/sdd
sudo sgdisk --zap-all /dev/sdd

# 2. 创建 OSD
sudo ceph-volume lvm create --data /dev/sdd

# 3. 或者分步操作
sudo ceph-volume lvm prepare --data /dev/sdd --block.wal /dev/nvme0n1p1
sudo ceph-volume lvm activate <osd-id> <osd-uuid>

# 4. 验证
ceph osd tree
systemctl status ceph-osd@<new-osd-id>

13.3 添加节点

# 1. 准备新节点(参考第 2 章环境准备)
# - 安装操作系统
# - 配置主机名、hosts、NTP
# - 安装 cephadm

# 2. 添加节点到集群
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@new-node
ceph orch host add new-node 192.168.1.15 --labels _admin

# 3. 验证节点
ceph orch host ls

# 4. 部署 OSD
ceph orch daemon add osd new-node:/dev/sdb
ceph orch daemon add osd new-node:/dev/sdc

# 5. 更新 CRUSH Map(自动完成)
ceph osd tree

# 6. 如果需要,调整 CRUSH 层级
ceph osd crush move new-node rack=rack3

13.4 数据再平衡

新 OSD 加入后,Ceph 会自动触发数据再平衡。

再平衡原理

添加 OSD 前(3 OSD):
OSD.0: 33%  |  OSD.1: 33%  |  OSD.2: 34%

添加 OSD 后(4 OSD),自动再平衡:
OSD.0: 25%  |  OSD.1: 25%  |  OSD.2: 25%  |  OSD.3: 25%

数据自动从旧 OSD 迁移到新 OSD

控制再平衡速度

# 查看再平衡进度
ceph -w

# 控制恢复/再平衡速度
# 方法一:限制并发恢复数
ceph config set osd osd_recovery_max_active 3
ceph config set osd osd_recovery_max_active_hdd 3
ceph config set osd osd_recovery_max_active_ssd 10

# 方法二:限制 backfill 并发数
ceph config set osd osd_max_backfills 2

# 方法三:降低恢复优先级(减少对业务的影响)
ceph config set osd osd_recovery_op_priority 3  # 默认 3,最低优先级
ceph config set osd osd_recovery_sleep_hdd 0.1   # HDD 恢复间隔

# 方法四:带宽限制
ceph config set osd osd_recovery_max_single_start 1  # 单次恢复最大对象数

# 暂停再平衡(紧急情况)
ceph osd set nobackfill
ceph osd set norecover

# 恢复再平衡
ceph osd unset nobackfill
ceph osd unset norecover

再平衡监控

# 查看恢复进度
ceph pg dump_stuck unclean
ceph pg dump pgs | grep -c "backfilling"
ceph pg dump pgs | grep -c "recovering"

# 查看 OSD 负载分布
ceph osd df tree sort utilization

# 查看恢复带宽使用
ceph daemon osd.0 perf dump | jq '.recovery'

13.5 缩容(移除 OSD)

移除单个 OSD

# 方法一:使用 cephadm(推荐)
ceph orch osd rm <osd-id> --force

# 方法二:手动步骤

# 1. 标记 OSD 为 out(触发数据迁移)
ceph osd out osd.5

# 2. 等待数据迁移完成
ceph -w
# 确保所有 PG 都是 active+clean

# 3. 停止 OSD 服务
systemctl stop ceph-osd@5

# 4. 从 CRUSH Map 移除
ceph osd crush remove osd.5

# 5. 删除认证密钥
ceph auth del osd.5

# 6. 删除 OSD
ceph osd rm osd.5

# 7. 验证集群状态
ceph -s

安全缩容流程(不丢失数据)

# 关键原则:
# 1. 确保移除 OSD 后仍有足够的副本数
# 2. 等待数据完全迁移后再移除

# 设置 noout 防止意外
ceph osd set noout

# 逐步移除 OSD(每次一个)
ceph osd out osd.5

# 等待数据恢复完成
while ! ceph pg stat | grep -q "active+clean"; do
    echo "Waiting for recovery..."
    sleep 10
done

# 确认恢复完成
ceph -s

# 安全移除
ceph osd crush remove osd.5
ceph auth del osd.5
ceph osd rm osd.5

13.6 移除节点

# 1. 逐个移除节点上的 OSD
for osd_id in $(ceph osd tree new-node | grep osd | awk '{print $1}'); do
    ceph osd out osd.$osd_id
done

# 2. 等待数据迁移完成
ceph -w

# 3. 从集群移除节点
ceph orch host drain new-node

# 4. 等待 drain 完成
ceph orch osd rm status

# 5. 移除主机
ceph orch host rm new-node

# 6. 验证
ceph osd tree
ceph -s

13.7 调整 OSD 权重

# 查看当前权重
ceph osd tree

# 调整权重(控制数据分布比例)
# 降低权重(减少数据量)
ceph osd crush reweight osd.5 0.5

# 恢复默认权重
ceph osd crush reweight osd.5 1.0

# 使用 reweight(基于利用率的自动调整)
ceph osd reweight-by-utilization
ceph osd reweight-by-utilization 120   # 负载超过平均 120% 时降权

# 查看 reweight 建议
ceph osd test-reweight-by-utilization

# 取消 reweight
ceph osd reweight-all 1.0

13.8 CRUSH 层级调整

# 移动 OSD 到指定位置
ceph osd crush set osd.5 1.0 host=node3 rack=rack2 root=default

# 移动整个主机
ceph osd crush move node3 rack=rack2

# 添加新的故障域层级
ceph osd crush add-bucket dc1 datacenter
ceph osd crush move rack1 datacenter=dc1
ceph osd crush move rack2 datacenter=dc1
ceph osd crush move dc1 root=default

13.9 扩容最佳实践

扩容规划

扩容前评估:
├── 当前容量使用率
├── 预期增长率
├── 性能瓶颈(CPU/内存/网络/磁盘)
├── CRUSH 拓扑是否需要调整
└── PG 数量是否需要调整

扩容建议:
├── 容量使用超过 60% 开始规划扩容
├── 每次扩容至少增加一个完整故障域(如一个机柜)
├── 新节点配置应与现有节点一致
├── 扩容期间监控恢复进度和业务影响
└── 扩容后验证集群健康和性能

注意事项

事项 说明
不要一次性添加太多 OSD 触发大量数据迁移影响业务
新旧 OSD 配置一致 混合不同性能的 OSD 会导致不均匀
调整 PG 数量 扩容后可能需要增加 PG 数
监控恢复进度 确保恢复完成后再进行下一次操作
业务低峰期操作 减少对生产环境的影响

扩展阅读

  1. 添加/移除 OSD
  2. CRUSH Map 管理
  3. 数据再平衡

下一章14 - 容器化部署 — 学习 Docker 容器化部署 Ceph、ROOK 和 Kubernetes Operator 配置管理。