网易数帆存储负责人亲述:我眼中的 Curve 与 Ceph

原创
2020/11/09 14:48
阅读数 1W

关于作者

我是王盼,网易数帆存储团队负责人,资深系统开发工程师,具有10年云计算行业从业经验,做过几年Libvirt、OpenStack开发,也做过一年多Ceph(主要是H版本)的维护调优,对计算虚拟化、云计算平台、分布式存储系统等均有一定的开发和运维经验,个人技术博客:http://aspirer.wang/

Curve是我们团队寄予厚望的开源存储项目,写这篇科普文章,旨在让对分布式存储系统(Ceph、Curve等)感兴趣的运维、测试、开发人员,或者对底层存储系统感兴趣的云计算平台开发人员,更加了解我们的项目。如欲对文中内容深入研讨,可添加微信号opencurve加入Curve用户群沟通交流。也欢迎关注每周五晚19:00点的Curve技术直播。

Curve新版本介绍

9月下旬我们发布了curve的最新版本v1.1,这个版本重点是性能优化,不论是单client还是10 client场景下,相比v1.0版本,都有至少30%以上的提升,其中提升尤其明显的是4k随机读写场景下的性能(具体可参考releasenote),大部分场景下的提升都达到70%以上,部分场景性能几乎提升一倍,可谓是飞跃性的进步。这一个版本兑现了7月份curve发布时许下的性能提升30%的承诺,并带来了一点惊喜。

当然我们不会满足于当前的性能,我们可以清晰的看到,在大IO场景下curve还有很大的提升空间,这也是curve团队小伙伴们正在努力优化的,另外小IO场景下我们观察到也有较大的提升空间,期待curve下一个版本也能给大家带来惊喜。

下面的性能对比数据中curve部分如无特殊说明都是基于v1.1版本测试的。

参考:https://github.com/opencurve/curve/blob/master/CHANGELOG-1.1.md

架构

Ceph

架构图参考官网:https://docs.ceph.com/en/latest/architecture/

ceph是基于crush算法的去中心化分布式存储架构,最大的优势是不需要元数据服务器,client每次下发IO请求可以自己通过crush算法(输入osdmap、对象名等)计算存储节点和存储设备(osd)以及数据存储的大概位置(pg),不需要元数据服务器的好处是不会引起性能瓶颈和可用性、可扩展性之类的问题,没有元数据分区、失效等问题,但无中心化的设计也会带来容量不均衡等问题。

但ceph也有一个mon集群,用来管理基本的存储集群拓扑结构(monmap、osdmap、pgmap等)、容量、存储集群各组件状态等信息,并通过Paxos协议保持多mon节点的可用性、可靠性和一致性,在集群稳定运行过程中,正常IO请求是不需要与mon集群交互的,但是在集群有异常,比如节点、磁盘上下线等场景下,还是要mon介入以便确认副本状态等信息,否则client和osd之间无法达成一致,或者说没办法确认应该跟谁通信。对应到存储节点,每个节点上一般都有多个磁盘(osd)来提供物理存储空间,每个osd上面又承载多个pg(管理数据副本一致性的最小单位),每个pg管理多个对象(rbd、fs、rgw等存储类型的数据存储对应到osd上都是已对象的形式来存储的,因此不考虑前面的3种具体形态,只有osd和mon的存储系统又叫rados)。

pg里的对象在磁盘上的管理形式当前主要是直接存储在裸盘上(老版本是文件系统如xfs),为了能找到对象数据的位置(逻辑位置到物理位置映射关系),每个osd还要维护一份自己的元数据信息(当然还可以保存对象的其他信息如omap,以及osd自身的空间使用情况等,还有pg的log信息),通常使用rocksdb(老版本是leveldb)。由于rocksdb本身属于LSM类型的存储引擎,因此需要经常性的进行compaction操作,这一操作过程中就会导致性能波动(磁盘压力或rocksdb本身性能影响)。

在集群中存储节点或存储设备上下线过程中,pg为了保证数据的一致性,需要经由mon来确认各个副本的状态,如果有副本下线,需要补充新的副本,如果副本上线则要同步落后的数据给他,在数据同步之前pg需要经历一个叫peering的阶段(osdmap可能会变化),用来找到权威的副本并且告知mon当前pg可以对外提供IO读写服务了,peering阶段完成前不能对外服务,这一阶段如果花费的时间稍长就会导致client端IO时延变长(俗称IO抖动,表现一般为util升高)。

节点下线的时候如果没有及时通知mon进行peering(osdmap还是旧的),client端和主osd就会认为下线的osd还处于在线状态,继续等待其返回或直到超时,新版本优化了下线流程不是死等超时,可以主动发现osd网络故障进而推断出其已下线,加速进入peering阶段,减少IO抖动时长。

ceph另一个问题是由于其要求3副本写入强一致,必须等待所有副本写入(至少是wal写入完毕)才能返回给client成功消息,所以一旦有一个副本(含主)磁盘响应慢或者存储机异常,就会导致IO请求时延飙高导致IO抖动,但是这个机制带来的好处是,ceph可以支持任意副本数的存储池(比如常用的1~3)。另外在副本增量恢复过程中(recovery),有读(主副本)写(任意副本)请求的时候也要等恢复完毕之后才能提供服务,也是会在一定程度上影响IO时延。

在集群规模达到几百台的场景下,ceph的抖动问题非常突出,因此针对H版本我们定制开发及优化了很多功能,比如数据均衡工具、backport下线主动发现机制、优化peering耗时,恢复速度控制、实现异步恢复等,另外我们也配置了数量众多的监控告警,以便及时发现问题节点、osd进行故障处理。

参考资料:

  • https://docs.ceph.com/en/latest/

  • http://aspirer.wang/?cat=1

Curve

架构图参考官网:https://opencurve.github.io/

curve是网易完全自主研发的新一代分布式存储系统,其架构中包含一个中心化的元数据管理服务MDS(通过ectd选出主从实现高可用),配合etcd存储引擎来保存集群的元数据信息,包括系统的拓扑信息(类似ceph的osdmap);文件系统的Namespace ( 树形目录结构,文件和目录,目录元信息等 ),类似ceph的crush ;Copyset ( Raft 复制组) 位置信息,copyset类似ceph的pg。MDS在一定程度上与ceph的mon集群相似。MDS还感知集群状态并进行合理调度,包括感知Chunkserver上下线、收集Chunkserver负载信息、集群负载均衡与故障修复,中心化架构的优势在于数据均衡比较容易实现,劣势在于容易带来扩展性的瓶颈,curve通过避免核心IO路径上与MDS交互的方案来规避这一问题(只有管控操作如创建删除卷等需要MDS),我们模拟过上百近千台存储机场景下,MDS都不是瓶颈,更大规模的场景还需要进一步验证。

curve的chunkserver类似ceph的osd,都是通过管理物理磁盘并存储用户数据的,当前1.0版本的chunkserver更接近于FileStore实现,通过ext4文件系统来管理chunk元数据,不需要依赖rocksdb等嵌入式数据库(因此每个chunk扩展属性还不支持,但针对块存储场景目前还没有此类需求)。curve数据存储的最小单元是 chunk(类似ceph的对象),管理chunk的基本单位是Copyset(类似ceph的pg),每个copyset搭配一个raft复制组来保证数据多副本的一致性和容灾能力。raft是多数一致性协议,好处是不需要等所有副本写入(至少是wal),大多数写入即可返回client端,极大的减少了长尾效应带来的影响,同时也避免了单个节点或磁盘异常(慢盘坏盘、节点超载等)场景下的IO抖动问题,不足是不能支持单副本场景(3副本中有2副本损坏的紧急场景),也即3副本至多容忍损坏一个,否则就不能提供服务(ceph配置min_size为1可以支持但不太建议,单副本长期运行一旦坏盘会导致数据丢失)。curve可以在节点、chunkserver上下线时主动进行数据的再均衡,并且支持恢复带宽控制(这一点ceph也做的不太好,尤其是L及之前的版本,都是通过控制并发及强制sleep来控制,很难精确控制带宽)。chunkserver的wal写入和一致性保证都是由braft来管理的,因此其业务逻辑非常简单,代码量也较少,开发者很容易上手(当然要深入理解brpc、braft还是会有一些挑战)。

curve client端实现了一些卷读写接口如AioWrite、AioRead、Open、Close、StatFile、Extend等,用来给qemu虚拟机、curve-nbd等应用提供卷的IO操作接口,client还要跟MDS交互实现对元数据的增删改查(如卷的增删改查等,接口不列出来了)。client还会对io进行切分,能对inflight io数量进行控制。Client还支持热升级,可以在上层应用(qemu、curve-nbd等)无感知的情况下进行client sdk版本变更。

curve的快照系统与ceph相比也不太一样,ceph快照是保存在ceph自身存储系统里面(rados层)的,支持以对象或者存储池为粒度进行快照,curve则是要导出到S3接口兼容的存储系统。两种架构各有优劣,保存本系统好处是不需要导出导入,节省时间,但会带来性能开销,可靠性也会有一定影响(如果丢数据则快照也不能幸免),保存到外部系统,则可以做更多的事情,比如快照压缩等,性能也更优(多级快照场景更加明显,不需要逐层查找对象进行IO读写)。

参考:

  • https://opencurve.github.io/

  • https://github.com/opencurve/curve/blob/master/README.md

  • https://docs.ceph.com/en/latest/architecture/

功能

从功能方面来对比Curve和Ceph肯定是不公平的,毕竟ceph已经发展了10年了,curve才刚刚开源出来,不过可以简单看下二者在块存储方面的功能对比,让大家对curve有个更直观的了解。

常用功能方面,curve和ceph都支持卷创建、删除,支持挂载到qemu、物理机(nbd)使用,支持扩容,支持快照及恢复。

ceph提供了一些高级功能(L版本),比如rbd-mirror、layering support、striping、exclusive lock、object map等,大部分一般用户是用不到的,或者是针对快照等场景进行的优化。更高版本的ceph提供了QoS功能。

curve提供的高级功能包括client QoS(通过限制inflight io实现)、client sdk热升级等,都是非常实用的功能。ceph的client端qos老版本还不太支持(比如L版本),当前我们H版本都是在应用层做的(比如qemu、nbd设备的cgroup等)。

ceph支持EC pool,但块存储场景下一般不太会使用到。

ceph的控制台功能比较简单不能满足产品化需求,当然curve还没有开发控制台,但是监控告警由于是基于bvar来做的,因此配合grafana和prometheus可以方便的实现可视化监控,并且展示的信息量非常丰富。ceph的监控更多的是通过ceph-mgr配合prometheus来做但可展示的监控项不是很丰富,或者基于perf counter功能自己封装,总体来说不够便利。

其他有些功能方面的差异已经在架构部分做了说明,这里不再复述。

参考:http://aspirer.wang/?p=1456

性能

性能方面,小IO场景下curve具有比较大的优势,尤其是最近发布的v1.1版本,性能更是提升了一大截。大IO情况下,curve还有较大的提升空间,尤其是时延方面还比较高,这也是curve团队当前的重点工作方向。我相信有了小IO场景优化经验,大IO场景优化起来也会比较得心应手。

项目 配置
存储机 Dell R730xd * 6台
CPU Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz * 2
MEM 256G
NIC Intel Corporation 82599EB 10-Gigabit SFI/SFP+ * 2
OS Debian GNU/Linux 9
Kernel 4.9.65-netease #1 SMP Thu Aug 2 03:02:48
curve版本 v1.1-0beta
ceph版本 Luminous 12.2.13
client host Dell R730xd * 2台
fio版本 3.13

我们内部测试对比数据如下(由于集群软硬件配置和ceph调优手段不尽相同,数据仅供参考):

单卷:

项目 Ceph Curve
4k randwrite (128 iodepth) iops: 39700, latency-avg: 3.2ms, latency-99: 4ms iops:109000, latency-avg: 1.1ms, latency-99: 2ms
4k randread (128 iodepth) iops: 41700, latency-avg: 3.1ms, latency-99: 3.4ms iops:128000, latency-avg: 1.0ms, latency-99: 1.5ms
512k write (128 iodepth) bps: 2076MB/s(单节点带宽已打满), latency-avg: 31ms, latency-99: 116ms bps: 204MB/s, latency-avg: 314ms, latency-99: 393ms
512k read (128 iodepth) bps: 2056MB/(单节点带宽已打满)s, latency-avg: 31ms, latency-99: 144ms bps: 995MB/s, latency-avg: 64ms, latency-99: 92ms

10卷:

项目 Ceph Curve
4k randwrite (128 iodepth) iops: 185000, latency-avg: 7ms, latency-99: 24ms iops:262000, latency-avg: 4.9ms, latency-99: 32ms
4k randread (128 iodepth) iops: 330000, latency-avg: 3.7ms, latency-99: 6ms iops:497000, latency-avg: 2.7ms, latency-99: 6ms
512k write (128 iodepth) bps: 3172MB/s(单节点带宽已打满), latency-avg: 44ms, latency-99: 182ms bps: 1122MB/s, latency-avg: 569ms, latency-99: 1100ms
512k read (128 iodepth) bps: 4440MB/(单节点带宽已打满)s, latency-avg: 28ms, latency-99: 129ms bps: 3241MB/s, latency-avg: 200ms, latency-99: 361ms

注:Ceph版本为L,N版本经测试与L相差不大,相关配置项为默认值。

参考:https://github.com/opencurve/curve/blob/master/CHANGELOG-1.1.md

运维

运维这方面,主要讨论部署和日常维护两块:

项目 ceph curve
部署 ceph-deploy,新版本是ceph-adm ansible
维护 命令集(ceph/rbd/rados/...) curve_ops_tool

两个项目把集群部署起来都还算简单,ceph-deploy有个问题,部署比较慢,要串行操作,为此我们还优化了一下ceph-deploy工具。ceph部署完服务才算第一步,后面还要创建crush rule(这个如果没有经过深入研究,还是有比较高的门槛的),配置pool的各项参数等操作。

curve应该只需要修改几个比较简单的配置文件(playbook的yaml),就可以一键部署搞定了,相对比较简单。

维护的话,ceph一大问题是经常遇到慢盘、坏盘,影响client的IO,用户经常抱怨(会收到一堆util超过90%告警),长时间抖动要帮用户手工解决(停掉慢盘osd),或者短时间的抖动要帮用户确认是否ceph导致的util飙高。为此我们也做了大量的工作来搞定这一场景(如增加各种监控,进行巡检等及时发现问题,甚至发现慢盘自动停止osd等等),但总归是治标不治本,只能尽量规避。

除了抖动,还有容量均衡问题(没有中心化的调度节点,只能根据使用情况进行osd的pg数量调整),集群缩容问题等比较难处理,老版本的pg数量不支持减少,是个比较大的问题(L版本也只能增加pg,更新的版本才支持减少pg),以及缩容后,即使只剩下少量的卷,也很难迁移到其他存储池(qemu用到了存储池,可以迁移到其他root rule,但是pg数量无法减少也是个问题),导致存储池使用的存储节点很难下线。

扩容场景下,除非新建root rule和存储池,否则ceph需要对已有数据进行迁移均衡到新增加的节点上,这方面curve也是类似的(物理池逻辑与ceph的root rule类似),curve的好处是可以做到精确的带宽控制,减少对正常业务的影响。

日常的坏盘替换场景下,ceph可以做到只迁移一次数据(L版本,H版本还不太行),也即坏盘下线的时候不做数据迁出,新盘上线时进行数据恢复即可(当然也可以做到自动迁出和迁入)。curve的话当前是下线自动迁出,上线自动迁入。二者区别不大,curve好处依然是精确带宽控制。

压力检测是一个比较困难的场景(如何找出压力比较大的client,并及时对其进行限制防止雪崩效应?),也是一个强需求(虽然client有qos,但集群一般都有性能超售,部分client压力飙升可能影响整个集群),ceph场景下,由于只能看到集群压力情况,很难做到所有client的汇集(当前是qemu端做的监控)和分析(当然可能跟我们使用的自研监控服务不支持这种场景有一定关系),导致很难找出那个或者那些影响了整个集群的client。一般我们都是用土方法,查看压力大的osd,打开message日志,找出消息比较多client ip,然后再根据client的监控情况判断是否跑满,同时找出同样业务的其他虚拟机,然后逐个进行限速处理。这一过程肯定比较耗时耗力,还不一定准确(可能新版本已经支持了单个rbd卷的性能统计)。curve场景下就比较简单了,看下grafana的client监控,找到压力大的client对其进行限速即可。

监控告警也是一大运维重点,ceph的话可以基于perf counter机制来做一部分,做不了的可以自己定制化扩展。也可以基于ceph-mgr+prometheus+grafana来做,一般还要配合存储节点的NODE_EXPORTER来做会比较全面。我们内部没有用这套机制,是基于自研的监控系统来做的,主要是用到了perf counter+监控脚本模式。

相比ceph的模式,curve基于bvar+prometheus+grafana,监控指标拉取更及时,都是秒级的,可以实时显示性能、时延曲线。bvar另外一个好处是它对外提供的是http api,不是perf counter那种命令行,也就是说不需要在本地部署agent或者脚本即可拉取数据,管理起来比较方便。

参考:

  • https://github.com/opencurve/curve/blob/master/docs/cn/monitor.md

  • https://github.com/opencurve/curve/blob/master/docs/cn/deploy.md#多机部署

  • https://docs.ceph.com/en/latest/mgr/prometheus/

学习曲线

纯使用

如果是运维人员想使用ceph或curve,或者对比2者进行选型,那我这篇文章基本上可以做为参考了。

ceph运维上手还是比较复杂的,要对各种概念、配置参数(L版本单单osd配置项我粗略看了下就有400多个,大部分配置项都要通过阅读源码来真正理解其意义和用途)、各种监控指标有比较清晰的理解,还要对各种pg状态有深入理解,各种异常要能找到对应的解决方案,当然网上各种调优文档也有很多可以拿来参考,如果没有深入的使用经验和测试比较,这些调优文档也有可能与你的使用场景不符,甚至可能带来副作用。

curve的代码注释(含配置项)非常完善,配置项也比较少(粗略看了下client、chunkserver、mds等全部加起来跟osd的配置项数量差不多),每个配置都有详细的解释,即使不明白也可以随时咨询我们的开发人员。集群状态也比较容易理解,没有那么多的incomplete、peering、degraded、undersize、recoverying、remapped、stale...

运维相关的部署维护监控告警方面,也是curve更容易上手一些,上面已有对比说明。

开发者

上面的架构对比已经说明了问题,curve架构非常简洁易懂(raft也比Paxos简单多了),不需要花费太多时间就能理解代码逻辑,上手进行开发测试。

更重要的是,不论对纯使用的运维人员还是开发者来说,curve的资料原文都是中文版本的,对国内用户来说都特别友好(另外还有微信群可以即时沟通)。

可扩展性/可塑性

功能

ceph的功能已经足够多了,号称统一存储平台。因此功能这块扩展性或者可塑性已经不大。

curve的话还非常年轻,它从架构设计之初就考虑到后续支持扩展各种存储场景的(块、对象、EC、其他引擎等等),当前的发展方向也还在逐步摸索,我们会根据公司内部和存储业界最新动向来及时调整规划,紧跟IT架构演进趋势。我们也欢迎各路同仁加入讨论和开发,一起发展curve。

我们近期的roadmap主要集中在如下几个方向:

  1. 云原生数据库支持:为MySQL提供分布式存储后端

  2. 云原生容器平台支持:容器云、中间件的存算分离(curve-nbd替换本地data盘、支持类似cephfs的文件存储)

  3. 作为ceph的前端缓存集群:类似ceph的cache tier

  4. 发展开源社区:吸引个人、企业开发者,加入TOP开源基金会

各个方向都能拆分出非常多的功能、性能、稳定性等方面的需求。中长期的规划可能会发生比较大的变化,这里就不列出来了。

性能

性能一直是curve重点关注的方向,除了上面已经给出的数据,后续curve还会花费大量资源在性能优化上,近两年的目标是支持云原生数据库和给k8s集群提供存储服务(前期可能考虑用nbd盘替换k8s节点本地盘,后期可能考虑开发类似cephfs的文件系统功能),虽然v1.1版本相比v1.0有了很大提升,当前离目标还是有一定差距的。io_uring、QUIC、spdk、rdma、25G网卡等新技术都在考虑当中,nvme/傲腾、40G网络等新硬件也在调研。curve近几年没有商业化或者盈利的打算,因此不会把各种优化手段和方案保留自用,都会毫无保留的开源出来。

ceph的性能也一直在改进,但由于其架构和功能比较复杂,牵一发而动全身,所以只能用全新的版本和架构来做(基于spdk/seastor等的SEASTORE),因为要保持功能的兼容性,当前看起来还需要较长时间才能正式发布。大部分sds厂商都是基于现有的架构进行优化改进,具体优化到什么程度,要看各家的实力和人力投入如何,但是一般来说他们的优化都是作为竞争力保留的,不太会开放给外部。

参考:

  • https://docs.ceph.com/en/latest/dev/seastore/

社区

ceph的社区活跃度肯定是很高的,curve刚刚开源,很多人还不了解。

ceph是一个成熟的国际化的开源社区,新人想参与进去提交pr还是有较高的难度的(一般是从编写测试用例、简单的bug修复入手),功能性的pr一般都是比较核心的开发人员才容易被接受(这一点跟Linux内核社区很相似)。

而curve刚刚起步,目前重点还是吸引国内开发者,一是便于沟通交流(可以微信添加opencurve拉你进交流群),二是鉴于当前国际形式也更倾向于为国内用户服务。刚刚起步的好处是,我们对所有的pr都非常欢迎,并且要求会相对比较低(可能你提交的pr不太符合规范,我们可以帮忙修改完善,可能你的pr没有考虑全面,我们可以给你提供修改建议和设计思路),有任何想法都可以在群里或者issue上提出来,目的是鼓励大家积极参与进来。企业用户如果有交流的想法,也可以与我们联系面谈,如果roadmap或需求有匹配的地方可以合作开发,提高研发效率、节约人力成本。

后续curve也会考虑加入某个开源组织(基金会),但目前主要还是关注自身的功能和性能问题,待条件成熟会有进一步的动作。

curve的roadmap可参考:https://github.com/opencurve/curve/wiki/Roadmap

应用规模

当前来说二者也没有可比性,毕竟ceph已经发展了10年,而curve才刚刚开源3个多月(内部开发2年多)。单就网易内部使用情况来说,ceph上线将近5年了,节点最多时数千台(随着业务从OpenStack转向K8s,集群规模有所减少),curve上线1年多,卷数量数千,并且一直稳定运行无任何SLA损失,这一点据我了解ceph当初上线时也没有做到的,curve的开发质量可见一斑。业务方经过这一年多时间测试观察,已经逐步建立起了对curve的信心,这一点从近期curve卷的使用量大幅增加可以明显感觉出来(我们给业务方提供了ceph、curve两种卷类型,他们可以自行选择创建哪种类型的卷),近2个月以来curve卷数量已翻了一番,我们预估明年集团内部使用量会有爆发式增长。


相关活动预告:网易数帆Curve核心开发团队将带来精心准备的 Curve 新一代分布式存储技术系列公开课(直播+回放每周五晚19:00为大家揭开 Curve 技术的奥妙及Curve社区的规划。本周五,将由网易数帆资深系统开发工程师查日苏带来“Curve核心组件之ChunkServer数据节点”的分享,敬请收看:Curve核心组件之ChunkServer

展开阅读全文
打赏
1
2 收藏
分享
加载中
更多评论
打赏
0 评论
2 收藏
1
分享
返回顶部
顶部