资讯动态

Ceph分布式存储实战:核心组件解析、集群部署与故障自愈验证

发布时间:2026/10/14 22:44:56 来源:尧图企业网站定制
1. 为什么我需要一套分布式存储最开始看到分布式存储这几个字的时候我以为就是几台服务器挂一堆硬盘组个大容量空间用。后来真正把自己的业务放上去才发现这事远没那么简单。当你手里有几十TB甚至上百TB的数据而且这些数据还不能丢、不能停单台服务器就算插满硬盘也扛不住容量和吞吐的瓶颈更别说一块盘坏了要怎么办。分布式存储解决的根本问题就是三件事容量不够时的横向扩展、单点故障时的数据安全、以及并发读写时的性能分摊。我最后选了Ceph不是因为它最炫而是因为它在开源方案里生态最成熟既能当块设备用也能当对象存储用还能当文件系统用一套集群三种入口对于内部基础设施来说很划算。先说个最容易误导人的地方。很多人以为Ceph是某个公司做的商业软件其实它是开源项目。社区版本和商业发行版都有底层内核是一样的。我当前部署的这套环境是自建的社区版本协议层走得是标准的Ceph后端没有厂商绑定换硬件、扩容节点都很自由。这个自由度在生产系统里非常重要因为你不知道两年以后你的存储需求会变成什么样早期绑定一个封闭方案后面想改架构会痛不欲生。Ceph这套系统最迷人的一点在于它把存储逻辑和物理硬件彻底解耦了。你可以理解成它先把你扔进来的所有数据切成很多小片然后用一套算法决定每个小片放在集群里的哪三块盘上。这个算法不是查表而是纯数学计算所以不需要一个中心节点来记录数据在哪任何客户端只要知道集群的拓扑和规则就能算出自己要找的数据在哪个位置。这个设计是Ceph的灵魂理解了这个后面看什么CRUSH、PG、OSD都不会晕。这篇文章是系列的第一篇我按从零开始的思路来写——先把核心概念和价值讲清楚然后把单节点怎么搭起来、怎么把数据真的写进去讲明白。适合两类人一类是刚接触分布式存储、想在公司内部搭一套测试环境的开发者另一类是已经用过其他存储方案、想横向对比Ceph架构的人。文章里的所有操作我都在干净环境里跑过一遍照着做基本不会翻车。2. 先搞懂Ceph的四大核心组件2.1 Monitor集群的方向盘Monitor是Ceph的大脑它不存业务数据但它掌握着整个集群的状态地图。每个Monitor都保存着Cluster Map包括有哪些OSD在线、每个OSD承载了多少PG、网络拓扑长什么样、当前有没有异常节点。客户端要和Ceph交互第一步必须先问Monitor拿最新的Cluster Map之后才知道该去哪台机器上读写数据。有个非常重要的细节是Monitor本身是一个强一致的系统。它内部跑着Paxos协议多个Monitor节点之间通过投票来保证状态完全一致。这就是为什么Ceph要求生产环境至少部署3个Monitor——当一个Monitor挂了其他节点还能继续对外提供集群状态。而1个Monitor虽然能跑但它就是单点挂掉整个集群就失去方向盘了。我们在测试环境里可以只起1个Monitor但在后续规划生产时Monitor节点必须独立出来并且做奇数部署。我还想提醒一个新手很容易忽略的问题Monitor对时间同步非常敏感。Ceph的健康检查里有个MON_CLOCK_SKEW告警就是Monitor之间时钟偏差太大时会出来报警。时钟不同步会导致Monitor之间无法正确判断对方的心跳甚至可能触发错误的故障切换。所以在装系统的时候我把NTP/Chrony服务就配好了这个事千万别等到集群报警了再处理后面排查起来非常痛苦。2.2 OSD数据真正住的地方OSD全称是Object Storage Daemon可以把它理解成每块硬盘前面的一个小管家。通常一块物理盘对应一个OSD进程Ceph的所有数据最终都是以对象的形式落在这些OSD上。Ceph做的各种数据冗余、故障域隔离、数据回填都是围绕OSD来操作的。OSD不仅管读写还定期向Monitor汇报自己的状态包括容量、负载、读写延迟等。Monitor根据这些信息来判断OSD是活着还是挂了是up还是down。在Ceph的世界里OSD down意味着对应硬盘上的数据可能需要被重建到其他节点上这时候集群会进入recovery状态数据副本重新补全。这个过程如果没控制好参数可能会把网络带宽打满影响正常的业务IO。我后面在调优章节会详细说怎么限速。每个OSD启动时系统会在它所在的机器上维护一个日志盘或者日志分区。早期版本默认用与数据盘同盘存储journal后来版本可以独立配置db和wal。如果条件允许我强烈建议把WAL/DB放到SSD上机械盘只做数据存储这个组合在读写性能上的提升非常明显尤其是随机写场景。2.3 PGCeph的中间管理层PG全称Placement Group。如果说OSD是物理世界的硬盘PG就是逻辑世界的容器。客户端的数据进来后先被切分成一个个对象然后每个对象根据哈希计算映射到某个PG这个PG再通过CRUSH算法被放置到一组具体的OSD上。为什么要多加PG这一层如果对象直接映射到OSD那么集群里的对象数量可能上亿管理这些细粒度映射关系会是天文数字。有了PG这一层集群只要管理几百几千个PG就够了每个PG内部再管理大量的对象。你可以把PG理解成快递分拣站——每个快递对象先按区域分到某个分拣站PG然后分拣站再统一配送到对应的片区OSD。这样管理效率高得多。PG还有个非常关键的属性叫PG数。这个值决定了一个池子里数据分散的粒度。PG数设置太小单个OSD上承担的数据量和IO压力就不均匀设置太大PG元数据又占资源重建和迁移的粒度也变碎。Ceph社区有个经典建议公式总PG数约等于OSD总数 × 100/ 副本数然后取靠近的2的幂我按这个思路在这套环境里算出的结果会在实操部分展示。2.4 CRUSH不用查表也能找到数据CRUSH是Ceph里最天才的算法。它做的事可以简单描述为给定一个数据对象通过一种确定性哈希计算直接算出一组OSD的编号。客户端拿到这个结果后直接去对应的OSD上读写整个过程中不需要向任何中心节点询问数据在哪。这个设计和传统存储相比优势很明显。传统的集中式元数据方案比如早期的一些分布式文件系统所有客户端都要先访问元数据服务器拿不到授权就没办法操作数据。元数据服务器一旦成为瓶颈整个集群的吞吐量就上不去了。而CRUSH相当于把元数据计算分摊到了每个客户端本地所有客户端只要持有一份Cluster Map就能各自独立算出数据位置。当然CRUSH不是没代价。它要求集群的拓扑信息比如每台机器的weight、bucket类型、故障域层级必须准确一旦拓扑信息变了CRUSH计算结果的分布就可能变化可能引发数据迁移。所以生产上调整OSD weight或者增加新节点时Ceph会触发数据rebalance这个过程要在业务低峰期做并且要先把recovery的限速参数配好。3. 部署前必须想明白的几件事3.1 集群规模规划到底怎么定我先给出一套适合入门测试的小集群配置本篇文章的实操部分也是基于这个配置来的。三台物理或虚拟机都可以每台机器上放两个OSD另外单独用一台或者复用其中一台机器跑Monitor。具体规格如下角色数量配置Monitor1~32核CPU、4GB内存、系统盘50GBOSD节点34核CPU、8GB内存、每节点2块1TB数据盘网络-千兆以上OSD节点之间尽量走独立网段这套配置整体约6个OSD、容量约5.4TB可用三副本下打出67%的利用率算出的可用空间。如果只是为了跑通功能、看看Ceph怎么工作这套够了。但如果想模拟故障切换、节点宕机我建议至少用3个Monitor且每台节点只跑一个角色的方式避免测试故障时互相干扰。生产环境规划的逻辑不太一样。你需要先明确自己要的是性能优先还是容量优先然后才能定OSD承载的PG数量、选择副本还是纠删码策略。比如日志型业务单盘容量不用太大但IO延迟要低所以尽量每个OSD都用机械盘之外再配一块SATASSD做WAL而归档型业务重点是单位成本能装多少数据这时候大容量机械盘配合纠删码策略优势就出来了。3.2 操作系统与存储介质的选择Ceph对Linux的兼容性最好我这边用的是Ubuntu Server 20.04 LTS内核版本5.4以上能很好支持Ceph最新的特性。CentOS/RHEL也可以不过现在社区重心渐渐往Debian系倾斜文档和踩坑案例都更丰富。如果你是第一次接触我更推荐Ubuntu。文件系统方面Ceph OSD的底层数据盘通常有两种选择XFS和ext4。社区官方推荐XFS原因是它在处理大文件和高并发写放大时有更稳定的表现并且支持扩展属性这些Ceph依赖的功能。我试过一次在ext4上部署后来检查到部分Ceph功能受限虽然不影响基本使用但既然有官方推荐没必要在这个地方给自己埋坑。数据盘先不需要手动分区格式化这看起来有点反直觉——正常装系统不是要先把盘格式化吗Ceph的部署工具ceph-volume会在初始化OSD的时候自动完成分区、格式化、挂载和systemd管理你只需要确保那块盘是空的系统能识别到设备名就行。3.3 网络设计的底层逻辑Ceph集群最容易被忽视的就是网络规划。一台OSD节点通常至少需要两个网口一个用于公共网络承担客户端对Ceph的访问流量另一个用于集群网络承担OSD之间的数据复制、心跳、rebalance流量。这不只是理论建议实测中如果不分开业务高峰期的大流量备份任务会把内部数据同步也拖慢客户端读写延迟直接往上飙。比如我这套环境里公共网络用192.168.10.0/24集群内部网络用192.168.20.0/24。在Ceph配置里用cluster_network和public_network两个参数显式指定。如果没有独立网段退而求其次也要用VLAN隔离保证二层广播域内OSD之间是打通的。网络带宽决定了一个很硬性的上限数据恢复速度永远受限于最小链路带宽。三副本下如果一块1TB的盘坏了理论上至少要往其他节点传1TB的数据。拿千兆网来说理论极限是约110MB/s实际跑满8成已经算不错意味着坏一块盘至少需要好几个小时来恢复。这期间如果业务还在持续写入恢复时间会更长。所以规划网络时我建议至少预留20%的带宽余量给恢复场景别让恢复和业务互相抢带宽。4. 从裸机到集群手把手部署实录4.1 配置软件源与基础依赖所有节点都需要先更新系统并安装必要的包。我这里直接贴出在Ubuntu上执行的命令包括设置hostname、配置hosts、添加Ceph源和安装cephadmCeph的新一代部署管理工具。# 更新系统基础软件 sudo apt update sudo apt upgrade -y # 设置主机名每台机器分别执行 sudo hostnamectl set-hostname ceph-mon01 # 编辑/etc/hosts把三台机器都加进去 192.168.10.11 ceph-mon01 192.168.10.12 ceph-osd01 192.168.10.13 ceph-osd02 # 安装docker与cephadm sudo apt install -y docker.io sudo systemctl enable --now docker # 下载cephadm最新版本 curl --silent --remote-name --location https://download.ceph.com/rpm-17.2.6/el9/mnoarch/cephadm chmod x cephadm sudo mv cephadm /usr/local/bin/这里多解释一句cephadm的定位。早期的Ceph部署工具叫Ceph-Ansible后来官方推出了cephadm它直接用容器化的方式来管理Ceph组件。每个Ceph服务mon、mgr、osd都运行在容器里系统层面只需要Docker环境。这个变化让升级和回滚变得非常干净要回退版本只需要把镜像指到旧版本重新部署即可。4.2 部署第一个Monitor节点下面这段命令会在当前节点上引导出一个全新的Ceph集群。目前我是先用单Monitor把集群拉起来后续如果需要加Monitor节点用ceph mon add命令继续加。# 使用cephadm引导集群指定monitor节点IP sudo cephadm bootstrap --mon-ip 192.168.10.11 # 验证集群状态 sudo ceph -sbootstrap过程会自动创建集群的初始配置、生成client.admin密钥、启动一个monitor和manager还会把/etc/ceph/ceph.conf和密钥拷贝到当前节点。一旦看到Bootstrap complete说明Monitor已经跑起来了。这时ceph -s会输出一个比较空的列表没有OSD没有池这正常。有件事必须注意bootstrap之后cephadm生成的SSH密钥默认只在这个节点上有效。你要把公有密钥分发到其他OSD节点上让cpehadm可以通过SSH远程管理它们。简单方式是sudo cephadm shell -- ceph orch host add ceph-osd01这个命令会自动把当前用户通常是root的SSH公钥同步到目标节点。也可以手动把/etc/ceph/ceph.pub内容追加到目标机器的authorized_keys文件里效果一样。4.3 添加OSD节点和磁盘假设现在三台机器加进来了我用以下命令把主机添加进集群然后列出所有可用的磁盘。# 添加主机 sudo ceph orch host add ceph-osd01 192.168.10.12 sudo ceph orch host add ceph-osd02 192.168.10.13 # 查看所有节点上发现的磁盘 sudo ceph orch device lsdevice ls会列出每台机器上的所有未被占用的磁盘。如果一切正常你应该能看到例如/dev/sdb、/dev/sdc这样的设备它们的状态标记为available。你可以手动指定哪些盘变成OSD也可以让Ceph自动接管所有可用盘。对于入门测试手动指定更稳妥避免误把系统盘也给接管了# 逐个添加OSD sudo ceph orch daemon add osd ceph-osd01:/dev/sdb sudo ceph orch daemon add osd ceph-osd01:/dev/sdc sudo ceph orch daemon add osd ceph-osd02:/dev/sdb sudo ceph orch daemon add osd ceph-osd02:/dev/sdc每次添加会返回一个osd编号例如osd.0。这个编号是永久的即使OSD以后故障重建编号也不会复用这在日志分析和数据追踪时非常有用。全部添加完后再看ceph -s会多出osd: 6 osds: up这一行。4.4 设置副本数与创建第一个存储池现在集群空转着还没有池。创建池之前需要先决定副本数。默认是3副本这个值在测试环境里有点奢侈1副本完全够用但生产上我还是强烈不建议低于2最好3。创建池的命令如下# 创建名为testpool的池设置PG数为128副本数为3 sudo ceph osd pool create testpool 128 3 # 如果测试环境想省空间也可以改成2副本 # sudo ceph osd pool create testpool 128 2这里有个点一定要理解pg_num是池的逻辑分片数不是实际副本数。128的意思是这个池会被分成128个PG每个PG承载部分对象。PG数不是越大越好很多新人一上来就设置4096结果每个PG里就几个对象元数据开销倒是异常庞大。在没有明确的容量估算之前先用上面的公式算一个基准值。验证池是否创建成功并查看使用状态# 查看池列表 sudo ceph osd lspools # 查看每个PG的状态分布 sudo ceph pg stat # 查看集群整体容量 sudo ceph df如果ceph df里显示SIZE是5.4TAVAIL可能是3.6T左右这是因为三副本带来空间加倍消耗。你还会看到一个USED值刚创建完池还没写数据的时候它显示0一切正常。4.5 启用RBD块设备并挂载到客户端池建好之后接下来就是真正往里面写数据。Ceph最常用的方式是RBD块设备它可以把池导出成一个块设备客户端像使用普通硬盘一样完成格式化然后挂载使用。# 在管理节点上创建一个1GB的块设备 sudo rbd create testpool/image01 --size 1024 # 将块设备映射到本地内核 sudo rbd map testpool/image01 # 格式化并挂载 sudo mkfs.ext4 /dev/rbd0 sudo mkdir -p /mnt/ceph-test sudo mount /dev/rbd0 /mnt/ceph-test到这一步你已经可以往/mnt/ceph-test里写文件了。看起来像用了一块本地硬盘但数据实际已经打散并复制到了多台OSD上。需要注意一点RBD默认精简置备也就是说创建1GB的块设备没有写数据的时候并不会实际占用存储空间等你真正写入数据才会占用。这个机制对节约空间很友好但如果你需要预留空间或者对延迟敏感可以考虑预置全量。4.6 用rados bench快速验证读写性能写完数据后最好做一次性能验证确认这套部署是正常的。rados bench是Ceph自带的基准测试工具# 写入1024个4MB对象测试4MB顺序写 sudo rados -p testpool bench 120 write --max-objects 1024 -t 16 # 测试4MB顺序读 sudo rados -p testpool bench 120 seq -t 16 # 测试随机读 sudo rados -p testpool bench 120 rand -t 16输出结果里要重点看Bandwidth (MB/sec)和Average Latency(s)。在千兆网络、6个机械盘OSD的测试环境里顺序写带宽一般能做到400~600MB/s顺序读能上800MB/s以上。如果带宽只有几十MB/s我建议先检查网络是否在走集群网络以及OSD的日志是否在频繁刷写。5. 故障模拟与自我修复机制验证5.1 手动将OSD标记为down部署完集群你还应该亲手做一次故障演练不然真出了事才发现监控没配好、恢复参数没调那就晚了。以下操作要在确认数据已经落到存储池后再执行。# 将某个OSD标记为down sudo ceph osd down 0 # 观察集群状态变化 sudo ceph -s过几秒再看ceph -s会看到类似osd.0 is down的信息同时pg_num里会出现activedegraded状态。degraded表示有PG的副本数不达预期Ceph正在尝试从剩余OSD上把缺失的数据重新复制出来。这里有个容易引起恐慌的点down一个OSD不代表它对应的数据已经丢失。Ceph只要还有一个副本在另一个OSD上它就能通过那个副本把数据恢复到其他OSD。只有当某个PG的所有副本对应的OSD都同时down了数据才真正不可恢复。5.2 观察数据恢复过程数据恢复不是一个瞬时的操作。为了防止恢复过程影响正常业务Ceph默认会把恢复速率调得比较保守。观察恢复进度可以用# 查看正在恢复的PG sudo ceph pg ls | grep recovering # 查看恢复相关参数 sudo ceph config get osd osd_max_backfills sudo ceph config get osd osd_recovery_max_active如果恢复速度太慢或者你是在测试环境希望快速看到效果可以临时把恢复限速调高sudo ceph config set osd osd_max_backfills 4 sudo ceph config set osd osd_recovery_max_active 8但注意这些都是测试期的临时手段。在生产环境里恢复限速应该根据业务特征谨慎调整毕竟恢复流量和业务流量是抢同一份带宽的。5.3 恢复完成后验证数据完整性数据恢复完成后ceph -s会回到HEALTH_OK状态所有PG变成activeclean。这时可以去客户端挂载目录里验证之前写入的文件是否完整。# 在挂载目录里生成几个测试文件 dd if/dev/urandom of/mnt/ceph-test/testfile bs1M count100 # 掉线模拟前先记录MD5 md5sum /mnt/ceph-test/testfile # 恢复完成后再次校验 md5sum /mnt/ceph-test/testfile如果前后两次MD5一致说明Ceph在你完全没干预的情况下自动把丢失的副本从其他节点补了回来。这就是三副本机制的核心价值——用户无感知的数据自愈。做一次这个实验你对Ceph的信心就不是从文档里看来的而是实际验证过的。6. 常见问题与排查技巧实录6.1 第一次集群部署ceph -s卡住无输出很多第一次部署的人会碰到这个情况。命令敲下去光标在闪烁什么都不显示。先别急首先要确认的是Monitor进程是否在运行sudo cephadm shell -- ceph -s如果cephadm shell能正常进入说明集群上层没问题可能是/etc/ceph/ceph.conf里mon_host配置指向了错误的IP。这个问题常见于多网卡机器上bootstrap的时候没显式指定mon-ip系统自己挑了一个不对的IP导致后续客户端连不上Monitor。解决方式是检查并修正ceph.conf里的mon_host和mon_addr。6.2 新增OSD成功但集群不健康ceph -s里的状态如果出现HEALTH_WARN常见原因有很多比如PG数量分布不均、时钟偏差、OSD版本不一致等。先用ceph health detail看具体告警项不要看到HEALTH_WARN就慌了。我在这套环境里遇到过一次PG_AVAILABILITY告警原因是新增了一批OSD后没有创建新池而旧池的PG全部落在老OSD上新OSD没承担数据。表面上看集群是扩容了实际数据还是挤在老地方。解决办法是给相关池调整pg_num或者干脆手动把一部分PG迁移到新OSD上。6.3 为什么要保持Ceph各节点版本一致Ceph对版本混跑有严格的兼容限制。不同的minor版本之间可以共存但major版本最好不要混用。如果你在一部分节点上升级到了新版另一部分还是旧版Monitor之间和OSD之间的通信协议可能不兼容轻则告警重则IO卡死。我在测试中养成一个习惯每次升级前先看ceph versions确认所有组件版本一致升级时先升级Monitor再升级OSD并且一次只升级一个节点观察ceph -s从HEALTH_WARN回到HEALTH_OK后再继续下一个。这套流程虽然保守但能最大化保证升级不翻车。6.4 性能到底卡在哪个环节如果发现读写性能比预期低很多我通常会按照下面的顺序排查网络带宽是否跑满查看port counters有没有dropped。OSD所在机器的iostat是否显示磁盘util接近100%。PG在OSD上的分布是否均匀ceph pg dump里看有没有热点PG。Monitor是否CPU占用过高Monitor在处理大量心跳上报时也可能成为瓶颈。客户端到集群的网络延迟ping测试是否能保持在1ms以内。其中第二点最容易被忽略。机械盘本身随机写性能就弱如果WAL和DB没有放到SSD上随机写场景下OSD会成为第一个瓶颈。所以安装OSD时有条件就一定要分配高速存储给WAL/DB这是最立竿见影的优化手段。7. 初版使用心得与下一步规划这套三节点集群我已经跑了大约两周稳定性没问题测试数据读写都能正常工作。对我来说最有价值的不是部署本身而是通过故障演练真正理解了Ceph的副本机制是怎么运作的。看到自己手动down掉的OSD在几分钟内被集群自动补齐副本数据端到端校验一致那种感觉比读十篇文档都有用。有几个实际踩坑经验分享出来。第一系统时间同步必须在部署之前做好不然后期出现的各种诡异告警会浪费你大量排查时间。第二Ceph的容器化部署让组件管理方便了很多但也意味着主机上的Docker不能随便停否则所有daemon都会掉线。第三如果你打算在生产环境使用务必在部署前就想清楚网络分隔方案和扩容策略这些架构层面的决定在后期很难低成本推翻。下一篇文章我会围绕Ceph的RGW对象存储网关和CephFS文件系统来展开把同一套集群怎么同时提供三种存储入口讲透。此外关于CRUSH Map的自定义故障域配置比如让副本分布在不同的物理机架上这部分内容也需要单独用一篇来详细拆解。到时候我们继续聊。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑