这两年主要工作在Hadoop技术栈,最近有幸接触到了Ceph。我觉得能够有机会体验到另一种大规模分布式存储解决方案是一件非常幸运的事情。因此,我可以比较一下HDFS和Ceph这两个几乎完全不同的存储系统的优缺点,以及它们分别适用于哪些场景。从一个SRE的角度来说,对于分布式存储,尤其是开源的分布式存储,我觉得主要是为商业公司解决以下几个问题:可扩展性,满足业务增长带来的海量数据存储需求。比商业存储便宜,大大降低了成本。稳定、可控、易于操作和维护。简而言之,目标是:易于使用、便宜且稳定。但现实似乎并没有那么美好……本文将从我认为的这三个基本价值观出发,分析我运维Ceph的经验,并与集中式分布式存储系统进行比较,比如HDFS,并横向谈论它。可扩展性Ceph号称可以无限扩展,因为它基于CRUSH算法,没有中心节点。其实Ceph确实可以无限扩展,但是Ceph无限扩展的过程并不美好。首先梳理一下Ceph的写入流程:Ceph中写入新对象需要先经过PG层预先定义的quotaHash分片,然后是PG,再经过硬盘组成的Hash集群中所有物理机的OSD,最终落入物理磁盘。因此,所有的Ceph对象首先被预哈希到固定数量的桶(PG)中,然后根据集群整体物理结构的crushmap选择落在特定的机器磁盘上。这对缩放有何影响?扩容粒度我对扩容粒度的定义是:一次可以扩容多少台机器。在实践中,Ceph的扩展是受“容错域”限制的,一次只能扩展一个“容错域”。容错域为:副本隔离级别,即同一个Replica的数据放在不同的磁盘/机器/Rack/机房。故障域的概念存在于许多存储解决方案中,包括HDFS。为什么Ceph会受到影响?因为Ceph没有中心化的元数据节点,数据放置策略受其影响。数据放置策略,即数据副本放置在哪台机器和硬盘上。中心化,比如HDFS,会在下面记录每个文件和每个数据块的存储位置。这个位置不会经常改变。它只会在文件新建、Balancer重新平衡、硬盘损坏、中心节点将数据重新放置在损坏的硬件上时发生变化。而Ceph,因为去中心化,存放数据的PG的位置会随着Crushmap的变化而变化。当新机器、硬盘到达时,需要为一些受影响的PG计算新位置。基于一致性哈希的技术在扩展时也面临同样的问题。所以Ceph的扩容需要PGs来调整。由于这次调整,Ceph受到了“故障域”的约束。例如:有一个PG,有3个副本,Ceph集群有一个配置,PG必须对外提供正常的服务,至少有2个完整的副本。并且当这个数据池的故障域为Host时,如果两台机器同时扩容,有的PG可能会将三份副本中的两份映射到两台新机器上。而这2个副本都是新的副本,都没有完整的最新数据。剩余副本不能满足旧机器至少有2个完整副本的要求,不能提供正常的读写服务。这将导致此PG中的所有对象停止对外服务。作为Admin,当然可以减少配置,将datapool的min_size减小为1。但是这样的配置,即使在正常情况下,也有可能因为磁盘故障导致数据丢失,所以一般不会这样设置。扩容时,一次只扩容一台机器安全吗?这将确保所有PG在旧机器上至少有2个完整副本。但是即使扩容一台机器,在扩容的时候老机器里面的硬盘坏了,导致PG的完整副本又降为1。虽然PG可能无法服务,但是数据持久化是没有问题的。国内AT云的服务可靠性不是特别高,做到三个九或者四个九,比如持久化。虽然不确定这两个大云里面的对象存储是不是用的Ceph,但是只要对象存储是基于CRUSH算法,或者一致性哈希等类似的去中心化技术,应该都是面向一些数据的。服务暂时不可用。暂且不谈最极端的情况,即假设在扩容时将机器添加为“容错域”时,暂时没有磁盘损坏。那么有什么办法可以增加扩展的粒度呢?方式是在开始规划Ceph集群的时候,设置更大级别的“容错域”,比如Rack。可以是真实机架,如果不是,也可以是逻辑机架。这样扩展的时候,可以扩展一个逻辑上的“容错域”,可以打破扩展一台机器的限制,扩展整个Rack,至少有几台机器。Tips:这里我没有说为什么小扩展粒度是坏事。在很多公司,数据的日均增长量很可能大于一台机器的存储容量。这样就会造成扩展速度跟不上写入速度的尴尬局面。这样对于一开始设计的不好,为了快速部署而搭建的集群,后期会造成很大的破坏。扩容时Crushmap发生变化。Ceph根据crushmap放置PG的物理位置。如果扩容到一半的时候硬盘坏了,Ceph的crushmap会发生变化,Ceph会重新对PG进行hash,很多PG的位置又会重新计算。如果运气不好,很可能一台机器的扩张进度被迫进行了很长时间才回到稳定状态。这种crushmap变化引起的Cephrebalancing不仅是大型存储集群几乎任何时候都头疼的问题,不仅仅是在扩容的时候。新建集群时,硬盘比较新,故障率不高。然而,在运行了2-3年的大型存储集群中,磁盘故障确实是家常便饭。1000个单位的集群一天2-3个盘出故障很正常。crushmap变化频繁,对Ceph内部不稳定影响很大。后续可能会出现整体IO下降(磁盘IO被反复rebalance占用),甚至部分数据暂时不可用。所以总的来说,Ceph的扩容有点不愉快。Ceph确实提供了无限的可扩展性,但扩展过程并不平滑或完全可控。crushmap的设计达到了很好的去中心化效果,但是也为集群变大后的不稳定埋下了坑。与元数据集中的HDFS相比,扩展几乎没有限制,你可以随心所欲地扩展容量。旧数据的迁移和重平衡将由一个单独的作业来处理,处理起来也非常高效。它采用全节点和空节点配对的方法,从旧节点移动足够的数据来填充新机器。集中式元数据在扩展和重新平衡时成为一个优势。扩容到一定程度后,需要调整PG的数量。如上图Ceph数据写入流程图所示,Ceph对象的最小放置单位是PG,PG会被放置在硬盘上。理论上PG越大越好。因为数据分片的随机性较好,可以较好地掩盖伪随机性导致的单盘容量偏差较大。但是实际上PG的数量并不是越大越好,它受限于CPU、内存、网络等硬件。所以我们在规划PG数量的时候,是不会盲目增加的。一般社区也推荐200pg/osd。假设我们现在有10台机器,每个硬盘一共有10个磁盘,共有1024个PG,而且PG都是单副本,那么每个磁盘会存储100个PG。这个时候这个设置是很健康的,但是当我们的集群扩展到1000台机器的时候,每个硬盘上只会放一个PG,这样会导致伪随机带来的不平衡放大。所以Admin面临着调整PG的数量,这带来了问题。调整PG基本上意味着整个集群都会进入严重异常状态。调整后PG涉及的对象中,近50%需要物理搬迁,导致服务质量严重下降。虽然调整PG并不是一件经常发生的事情,但是在大存储中,随着发展,必然会经历这样的大考。比商业存储更便宜我们所说的商业存储比较,一般是指与EMC、IBM等软硬件存储解决方案厂商,或者阿里云、AWS等云解决方案的比较。自己搭建机房在硬件单价上当然更便宜,但是需要考虑综合成本,包括:硬件成本自营运维人员成本话虽如此,本文只谈有趣的部分关于Ceph的硬件成本。按理说,如果自己搭建机房,硬件成本应该是无疑便宜的,那么这里的Ceph有什么特别的呢?问题是,集群的可靠利用。集群可靠利用率,即当整个集群的容量达到一定程度后,无法对外提供服务,或者无法维持服务的高可用。比如我们的手机闪存/电脑硬盘达到99%后还能正常工作吗?当然,因为是本地存储。对于云解决方案,这个问题自然不存在。对于商业存储解决方案,如EMC的Isilon分布式文件系统,即使98-99%的存储容量仍然可以对外提供服务。对于HDFS,95%以下,存储也能很好的对外提供服务。在HDFS上运行的Hadoop作业将挂起,因为它们无法在本地写入。至于Ceph,它在这方面的表现并不好。根据经验,当集群的整体利用率达到70%后,就有可能进入不稳定状态。为什么是这样?问题是去中心化带来的权衡。Ceph是一种去中心化的分布式解决方案,对象的元数据分布在每台物理机上。因此,所有对象都“伪随机”分配到每个磁盘。伪随机不能保证所有磁盘的完整均匀分布,不能降低很多大对象同时落在一个磁盘上的概率(我的理解是加一层PG,让PG有更多的replicas可以减少varianceof磁盘),所以总有一些磁盘的使用率高于平均水平。在集群整体利用率不高的时候是没有问题的。达到70%的利用率后,需要管理员干预。由于方差较大,很有可能会触及95%的红线。Admin开始减少超大磁盘的Reweight。但是,如果在这批磁盘reweighting完成之前,部分磁盘已经满了,那么在Ceph达到稳定状态之前,管理员必须强制再次对reweighting高的磁盘进行reweight。这导致了crushmap的另一个变化,导致Ceph离稳定状态越来越远。而如果这个时候扩容不及时,那就更糟了。而且,之前crushmap的中间状态也会导致部分PG被迁移一半,而这些“不完整”的PG并不会被立即删除,给本来就紧张的磁盘空间增加了负担。有的同学可能会疑惑,为什么一个磁盘满了,Ceph就不能用了。Ceph真的是这样设计的,因为Ceph不能保证新对象是落在空盘上还是落在满盘上,所以Ceph在满盘时选择拒绝服务。在咨询了一些同事和业内同行后了解到,基本上大家的Ceph集群利用率都在50%左右,即将开始准备扩容。这实际上是相当昂贵的,因为大量机器的存储资源必须是空置的。而且未来集群的规模越大,空置效应就越大,也就意味着更多的钱/电被浪费了。在很多传统的集中式分布式存储系统中,由于主控节点可以选择一台相对空闲的机器进行写入,不会出现部分磁盘写满而无法写入整个集群的问题。也确实是可以做到整体写95%,还保持可用性。我还没有真正计算过这种效果浪费的成本,但至少看起来有点不完美。比如我预估有50PB的存储,我需要300台物理机,实际上我还要提前另外采购200-300台物理机,不能马上用,得插电。所以Ceph不一定便宜,去中心化的分布式存储也没有那么美好。但是,中心化的危害似乎是一个没有争议的问题(单点问题、中心节点可扩展性问题等),所以分布式真的没有灵丹妙药,只有权衡。另一种方法是根据整个池扩展Ceph集群。当池已满时,容量将不会扩展。一个新的池被打开,新的对象只能写入到新的池中。可以删除和读取旧池中的对象。挑选。乍一看,这是一个很棒的解决方案,但仔细想想,它似乎和HDFS的federation,MySQL的分库分表,前端的bighash没什么区别。这不是“无限扩展”,还要写一个前面的路由层。稳定、可控、好运维。这种稳定好运维,基本上靠的是团队的硬实力。是否熟悉开源软件,是否有经验,真的有很大的不同。同时,这也受到开源社区文档质量的影响。Ceph的开源社区还是不错的。RedHat收购并主导Ceph后,重新整理了RedHat版本的Ceph文档。我认为它读起来更合乎逻辑。在公司内部积累自己的运维文档也是关键。一个新手很可能会犯很多错误,导致事故发生。但是对于公司来说,踩过一次坑,尽量不要踩第二次。这对公司的技术积累管理、技术文档管理、核心人才流失管理等提出了一定的挑战。我在Ceph运维中遇到了一个棘手的问题。即在Ceph集群达到80%后,磁盘往往会变满,此时管理员不得不介入,降低过高磁盘的Reweight。在这个磁盘的使用率下降之前,更多的磁盘已满,管理员不得不再次干预并调整Reweight。Ceph至今从未进入稳定状态,管理员必须时时刻刻关注集群。这就导致运维投入巨大,所以必须避免类似这样的事情发生,这对运维人员的士气是非常不利的。那么,是否应该尽早发出容量警告以启动采购流程?但这样做又回到了资源浪费的问题上。另外,Ceph对象没有last_access_time等元数据,所以Ceph对象的冷热区分需要二次开发和额外的工作。集群变大后,如何清理垃圾数据,如何归档冷数据也带来了很多挑战。综上所述,Ceph确实具备无限扩容的能力,但需要前期规划好,扩容过程并不完美。中心化创造了扩展的上限是单个Master节点的物理极限,创造了无限扩展的理论基础,但在实际扩展中,服务质量会受到严重制约。Ceph对硬件有点浪费,在成本核算上更应该考虑。Ceph本身去中心化的设计牺牲了很多元数据,比如lastacesstime,给未来的数据治理带来压力,需要更强的运维和二次开发团队。积累运维经验和一支运维团队,是把控开源分布式存储的核心。随着时间的推移,对手越来越强大,应对它的运维团队也需要越来越好,让生产关系匹配生产力需求。技术本身没有绝对的好坏,不同的技术用于解决不同的问题。但在场景中,技术有好有坏。因为在场景中,如果你有职位,你就会有需要解决的问题的优先级,你就可以根据优先级来选择最适合自己的技术。
