在这十年的发展过程中,Ceph 似乎越来越向着云计算的方向靠拢,最先的 CephFS 文件系统已经不再是开发重点,甚至开发已经陷入了停滞状态。而与虚拟化相关的 RBD、RGW 则成了发展重点,成为发展最快的模块。但是从代码中仍然能够看到各种遗迹,似乎在告诉后来人这段饶了一个大弯的历史。
Ceph 发展现在仍然快的眼花缭乱,让我们暂时停下脚步,看看经过十年发展后,现在 Ceph 的优势与缺点。
一、优势
CRUSH 算法
CRUSH 算法是 Ceph 最初的两大创新之一(另一个是基于动态子树分区的元数据集群),也是整个 RADOS 的基石,是 Ceph 最引以为豪的地方。
CRUSH 在一致性哈希基础上很好的考虑了容灾域的隔离,能够实现各类负载的副本放置规则,例如跨机房、机架感知等。同时, CRUSH 算法支持副本和 EC 两种数据冗余方式,还提供了四种不同类型的 Bucket(Uniform, List, Tree, Straw),充分考虑了实际生产过程中硬件的迭代式部署方式,虽然实际生产中大多数情况下的都是只用了一种 Straw。
另外根据 Sage 的论文,CRUSH 算法具有相当好的可扩展性,在数千 OSD 的情况下仍然能保证良好的负载平衡。但这更多是理论层面的,目前还没有人给出在数 PB 规模的生产环境中的测试结果。
总的来看,CRUSH 算法仍然是目前经过实践检验的最好的数据分布算法之一。
统一存储架构
Ceph 最初设计的 RADOS 是为其实现一个高性能的文件系统服务的,并没有考虑对于块设备、对象存储的支持,也就没有什么 RBD、RADOS GateWay,跟别提 OpenStack 和 qemu 之类的了。但谁想无心插柳柳成荫,由于 RADOS 出色的设计和独立简洁的访问接口,再加上 Sage 敏锐的眼光,Ceph 社区果断推出了用于支持云计算的分布式块存储 RBD 和分布式对象存储 RADOS GateWay,并将开发中心全面转向云计算领域。
不得不说,RADOS 的设计还是非常的优秀。从架构上来看,RBD 和 RADOSGateWay 实际上都只是 RADOS 的客户端而已,但得益于 RADOS 的优秀设计,RBD 和 RADOSGateWay 的设计和实现都很简单,不需要考虑横向扩展、冗余、容灾、负载平衡的等复杂的分布式系统问题,同时能够提供足够多的特性和足够优秀的性能,因此迅速得到了社区的认可。另一方面,Ceph 为 OpenStack 提供了良好的支持,成为了目前最火的 OpenStack 底层存储系统。乘着云计算和 OpenStack 的东风,Ceph 作为一个统一存储系统,似乎大有舍我取谁之势。
丰富的特性
Ceph 的特性不可谓不多,从分布式系统最基本的横向扩展、动态伸缩、冗余容灾、负载平衡等,到生产环境环境中非常实用的滚动升级、多存储池、延迟删除等,再到高大上的 CephFS 集群、快照、纠删码、跨存储池缓存等,不可谓不强大。
但是就像大多数开源系统一样,Ceph 的基本特性,或者说真正在生产环境中用的上的特性还是非常靠谱的,但其他“高级”特性就只能打一个问号了。特别是在 CephFS 模块,由于 Ceph 社区目前的开发重点主要还是与云计算相关的部分,即 RBD 和 RADOSGateWay,导致 CephFS 的开发停滞了很久,相关的特性,例如元数据集群、快照等,目前都不满足生产环境的要求。
二、缺点
代码质量
代码质量的问题,实际上是个仁者见仁智者见智的问题。
Ceph 主要使用 C/C++ 语言编写,同时外围的很多脚本和工具用了 Python。之所以要说明 Ceph 的语言构成,是因为代码质量实际上是和语言具有密切的关系。不否认用 C++ 也能写出优雅的代码,但相比于更加“现代”的语言,要想写出具备同样可读性、结构良好、调理清晰代码,C++ 要困难很多。但是,由于存储作为底层系统,对效率的追求是无止境的,因此不太可能舍弃对于内存等底层系统资源的控制,而使用 Java/Python 这类的语言。而作为一个开源项目,期望所有的贡献者都是 C++ 的高手,未免有些强人所难,这似乎成了一个死结。其他类似的开源项目怎么办呢?貌似他们都用的纯 c……
另一方面,Ceph 广泛使用了 STL,在部分核心代码中还是用了 BOOST,这两者在底层核心系统代码中的可用性也一直存在争议。这更加加剧了代码质量的挑战性。
最关键的是,Ceph 似乎已经被太多已经背负了太多的历史包袱,比如最核心的 osd 模块,最初的设计包含 OSD 和 PG 类,其中 PG 类负责 PG 的通用逻辑,OSD 负责管理所有的 PG。然后 PG 的子类 ReplicatedPG 实现了以副本作为冗余模式的 PG。这里就存在了两个半类:OSD、PG 及其子类 ReplicatedPG,这两个半类实现了 osd 模块 99% 的逻辑,可以想象这两个半类会有多大。
在目前的 master 分支上,相关文件的大小分别是:
OSD.h+OSD.cc = 2383 行 +8604 行 = 10987 行 PG.h+PG.cc = 2256 行 +7611 行 = 9867 行 ReplicatedPG.h+ReplicatedPG.cc = 1487 行 +12665 行 = 14152 行
需要特别注意的是,从 C++ 继承的角度上,理解一个类,必须理解他的父类,也就是说,如果你想理解 ReplicatedPG,理论上你必须同时理解 PG,也就是说,要同时理解 20000+ 行代码!
更加丧心病狂的是,这两个半类之间存在密切而复杂的调用关系,相互之间直接使用整个类,而没有什么实际上的接口隔离。严重加剧了理解代码的难度。
在 EC 功能以一种奇葩的方式加入到 osd 中之后,整个场面更加混乱。按照最初的设计,实现 EC 应该增加 PG 的一个子类,类似 ErasureCodePG。但是由于 ReplicatedPG 包含了太多通用的代码,实际上已经和 PG 合二为一了,所以 EC 只能在 ReplicatedPG 的基础上改造。于是又出现了 PGBackend 的概念和相关的实现,这只能说是挑战人脑的极限了。
Ceph 社区也曾试着梳理代码,比如添加 OSDService 类,作为 PG 与 OSD 通讯的接口。这样所有的 PG 全部调用 OSDService 而非 OSD,相当于做了 OSD 与 PG 之间的隔离。但是似乎并没有起到足够的效果,现在已经名存实亡了。
Ceph 在这样的代码质量下,还能向前走多久,委实是一件令人担忧的事情。
性能
Ceph 的性能总的来说还是不错的,基本上能发挥出物理硬件的性能,但是存在以下几个隐患:
1)数据双倍写入。Ceph 本地存储接口(FileStore)为了支持事务,引入了日志(Journal)机制。所有的写入操作都需要先写入日志(XFS 模式下),然后再写入本地文件系统。简单来说就是一份数据需要写两遍,日志 + 本地文件系统。这就造成了在大规模连续 IO 的情况下,实际上磁盘输出的吞吐量只有其物理性能的一半。
2)IO 路径过长。这个问题在 Ceph 的客户端和服务器端都存在。以 osd 为例,一个 IO 需要经过 message、OSD、FileJournal、FileStore 多个模块才能完成,每个模块之间都涉及到队列和线程切换,部分模块在对 IO 进行处理时还要进行内存拷贝,导致整体性能不高。
3)对高性能硬件的支持有待改进。Ceph 最开始是为 HDD 设计的,没有充分考虑全 SSD,甚至更先进的 PCIe SSD 和 NVRAM 的情况 NVRAM。导致这些硬件的物理性能在 Ceph 中无法充分发挥出来,特别是延迟和 IOPS,受比较大的影响。
CephFS
CephFS 现在在整个 Ceph 系统中处于一个较为尴尬的情况,因为 POSIX 这种借口似乎在云计算中没有用武之地,导致了社区对这个模块的关注不足,也就没有什么进展。
CephFS 作为最初 Ceph 的设计目标,Sage 投入了巨大的精力,几乎实现了所有需要的特性,并且进行了大量工程层面的优化。
正所谓成也萧何败萧何,Ceph 想把 CephFS 模块做到足够强大,甚至是最强大,但强大的同时也意味着不菲的代价。元数据动态子树分区、目录分片、快照、权限控制、IOPS 优化、故障恢复、分布式缓存、强弱一致性控制,这些高大上的名词背后都意味着复杂的工程性任务,更不要说将这些叠加在一起。很多时候,叠加不是想加,而是相乘的关系。最终的结果就是整个 MDS 的工程难度已经超过了可以掌控的程度,无法做出足够成熟、稳定的系统。
目前 CephFS 宣称其单 MDS 的模式是稳定的,MDS 的集群的模式是不稳定的。而快照功能默认关闭,今后也够呛会有开启的可能了。
业务连续性
Ceph 中的 RADOS 采用强一致性设计,即 Write-All-Read-One,这种模式的好处在于读取效率较高,而且工程难度较低,比较适合与读多写少的系统。
Write-All-Read-One 的特点是必须等待所有的副本全部写入完毕才算是写入成功,这实际上对系统硬件的可靠性要求较高,因为如果在写入过程中存在任意硬件故障,则写入过程都要受影响。通常表现为卡顿,一般在数秒级别,时间长短和判断故障的机制以及故障恢复过程中 IO 的处理策略相关。
但是当集群非常非常大时,Write-All-Read-One 对于硬件可靠性的要求几乎是无法满足的。想象一下一个 10PB 的系统,按照最大 4TB 每块盘的计算,就有 2500 块磁盘。按照我们以往的运维经验,每周存在一块磁盘故障是完全正常的。这种场景下,如果数据分布足够分散,实际上一块磁盘可能涉及到很多数据块,也就是说一块磁盘故障会影响很多 IO,而这种情况每周发生一次。这对业务连续性的影响是已经是不可忽略的。
生产环境中的场景比这个更加复杂,因为磁盘或者硬件的故障可能不仅表现为不可写,还有可能是慢或者不稳定。这些情况对于业务连续性的影响也更加严重。
社区
Ceph 社区现在已经有很多厂商实际上或者号称参入进来,其中不乏 Intel、Dreamhost、SanDisk 这样的大厂,也不乏 UnitedStack 这样的 Start-Up 公司,还有电信、大学、研究所这类非存储领域的公司或单位。但实际上整个 Ceph 还是掌握在 Inktank 或者说 RedHat 的手中,绝大多数核心代码由他们贡献,也是他们 Review 和 Merge。总的来说还是一个集权组织。
更加重要的是,Ceph 相比 OpenStack 这种成熟完善的开源社区,缺乏足够的基础设施,例如成熟的单元测试、集成测试、测试环境、Reivew 流程、贡献指引、代码规范等。导致整个社区仍然是人治、而非法制的过程,代码和系统的发展方向本质是由 RedHat 公司控制的。
对于以上这些问题,Ceph 社区也非常清楚,并且正在或者将要改进。例如为了增加了对于 SSD 的支持,改进数据双倍写入问题以及更完善的社区建设和基础设施等。这些都增加了人们对 Ceph 的信心。
总的来说,Ceph 瑕不掩瑜,仍然是一个优秀,甚至出色的开源存储系统。如果说分布式存储在云计算时代是风口上的猪,那么 Ceph 也是一直优秀的猪。
未来是什么样子,我们拭目以待。
编后语
为了更好地向读者输出更优质的内容,InfoQ 将精选来自国内外的优秀文章,经过整理审校后,发布到网站。本篇文章作者为袁冬,原文链接为『关于Ceph 现状与未来的一些思考』。
感谢郭蕾对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。
评论