你们好,我是阿里云数据库产品事业部的玄陵,真名郭超。node
本次的分享大概分三个部分:Cassandra云数据库简介、Cassandra云数据库特性以及Q&A。数据库
咱们先了解一下Cassandra云数据库在阿里云上的部署和架构。首先这个架构主要反映了三个方向:安全
接下来咱们深刻了解一下单个DC和集群的状况。网络
除此以外,咱们其它的架构和Apache Cassandra几乎是同样的。多线程
接下来咱们介绍一下Cassandra云数据库的特性:架构
即将上线的服务包括:并发
接下来,咱们介绍一些咱们在功能上作的优化。因为时间关系,咱们只能重点介绍一部分功能优化。运维
第一点,咱们作了一些自动化运维手段。性能
这个事情的背景是因为Cassandra是一个去中心化的数据库,社区建议用户作repair,目的主要是保证Cassandra三个或多个副本之间的一致性。Repair可以把副本上的数据作一个修复或者补齐,保证副本的数据是一致的。Repair是必需要作的,然而在咱们的使用场景中,repair会引入一些问题:优化
在介绍咱们的改进措施以前,我先来大概介绍一下repair的机制:在图中咱们能够看到三个副本ABC,第一步repair会在三个副本上构建全量的Merkle Tree,第二步会比较ABC副本的Merkle Tree之间数据的差别,第三步再经过一个相似于Steaming的过程把数据补齐。
咱们改进的目的是什么呢?
咱们但愿咱们repair的过程是自动化的,不须要引入人工干预。这样当咱们云上的集群愈来愈多或者用户扩容缩容的时候,咱们不须要人工的干预,这样能够下降云上运维的复杂性,大大释放了人力资源。第二个目的是但愿整个repair的过程是一个开销较小的过程,这样能够保证repair对线上服务的影响很小。
那么咱们repair的大概原理是这样的:咱们能够在图上看到ABC三个副本,每一个副本节点上都会有一个primary range主范围。咱们会把primary range切分红很小的组。每一个node只会负责修复本身primary range的数据,它不会去管别的数据。好比说B这个节点,它有一个primary range是A到B,除此以外它也会有C到A的副本数据,可是这个部分节点B无论,它只管A到B的数据的修复。这样会下降咱们修复的数据量。
节点B只管A到B的primary range,咱们会把primary range切分红很小的段,这个部分是为了咱们后面作断点续传。咱们会针对每个sub_range作修复。这个服务是在Cassandra的kernel里面,它是一个独立的修复模块。当Cassandra进程启动后,这个服务会首先会将primary range切分红sub_range。每个sub_range会有一个本身的task,而后这些task会进行排列。这以后,咱们会对全部的sub_ range从开头到结尾进行轮询scan。每次scan会把sub_range里的数据拿出来,如今咱们设置的是每一次拿10条数据。咱们独立实现的repair的module的读写链路和正常的读写链路是分开的,这样的好处是repair不会影响正常的读写链路。
除此以外,官方建议,一轮repair应该在gc_grace_seconds范围以内作完。那么咱们能够经过流控控制每个primary range修复的时间,也能够控制每一次服务对线上的影响。每个sub-range作完以后,咱们会在一个system表里面作记录。好比当咱们修复到B节点的sub_range2时出现问题了,下一次B节点再启动时会经过system表断点续传到sub_range2,而后sub_range2继续完成任务。这样作的好处是不少过程能够彻底自动化,独立的修复链路不会影响正常的读写链路,除此以外还能够下降对线上服务的影响以及有一个可控的修复时间。
接下来咱们就性能加强方面选一个点进行详细介绍。
咱们的性能加强基于咱们阿里云的部署形态,咱们的底层使用的是盘古提供的块存储设备。咱们能够看到Cassandra原有的架构是上面是LSM,底下是咱们如今用的Ext4文件系统,而后是一些操做系统的处理(好比Logical Volume和Volume Group),最终落到下面是有一个单独的disk放commitlog,其余的disk会放sstable。这样的部署模式会引入一些问题:
那么咱们的优化方式就是把底层经过LVM条带,能够把下层的cloud disk1-4 bind起来。这样当从上层写入时,不管是sstable仍是commitlog,均可以充分利用四块盘的资源,而不是只有disk 1写commitlog,其它disk 二、三、4写sstable。咱们是把四块盘的并发能力全用起来。当写入一个commitlog,它不仅是被写入disk 1。经过LVM条带,commitlog和sstable会被分红chunk,并发地写入disk 一、二、三、4。
这样的好处一是能够利用LVM的条带化和多盘的并行能力提升写入性能。如今咱们的写入性能比以前提升了20%以上,这是一个平均数,比较极致的提升会更多。第二,咱们的四块盘既能够提供commitlog也能够提供sstable,咱们就不须要额外的一块盘放commitlog,这样的性价比是最高的。另外,假设咱们四块盘加起来的容量是80个G,它们对应的IOPS和一块80个G盘的IOPS是同样的,可是前者的价格会比后者低。经过这个方式,咱们能够把整个Cassandra产品的价格下降。第三,咱们底层所用的盘古能够提供比较极致的数据可靠性(9个9)。咱们能够利用盘古的数据可靠性和LVM的条带化保证数据节点的数据可靠性,由于若是单块盘的数据可靠性不高时,LVM条带化是用不起来的。
除此以外,咱们作了一些功能性的加强。
第一,咱们支持全量和增量的备份恢复。原有的Cassandra并无一个机制能够把增量的备份恢复作到同一的系统里面。咱们如今能作到的是,假设原集群是三个节点,咱们能够恢复到对应的三个节点。咱们如今在云上的宗旨是恢复到对等节点。
咱们的备份和恢复分为两部分:全量的备份恢复和增量的备份恢复。
首先咱们在图上有snapshot这个点,咱们会对各个节点并发地作snapshot,作完snapshot咱们会有一个全量的sstable。在打完snapshot这个时间点之后,咱们会开始作增量的备份。增量的备份咱们分两部分:一是incremental backup是社区已有的功能,咱们在此基础上作了一个表级别的备份恢复的点。除此以外,咱们还作了一个增量commitlog的数据备份恢复。
可能有的用户会问,增量的incremental backup和commitlog的数据实际上是有重叠的,咱们后面会对此作一些介绍,解释咱们为何这样作。
咱们经过snapshot打彻底量的快照之后,把每一个节点的数据备份到阿里云的oss上面去。当用户选择恢复的时候,咱们会对用户全部的sstable作对等拓扑的恢复,每一个节点的token范围也是对等映射的。这样作的好处是能够不经过sstableloader的方式把sstable load进去,这样恢复的速度是最快的。咱们只须要作一个对等拷贝,而后作一个单节点的nodetool refresh就能够了。
增量咱们经过incremental backup及WAL log online archive来作。咱们在云上作了这样的一个优化:每次从memtable flush下来的sstable会经过incremental backup产生hard link到对应的backups目录,同时扩容节点的时候,streaming生成的SSTable也会产生hard link。咱们会把hard link对应的SSTable也备份。
除此以外,咱们利用了Cassandra原有的archive功能,把每一个节点写入的WAL log也作一个备份。当每一个commitlog生成的时候,它都会把一个hard link到用户指定的地方。由于archive是须要重启集群和节点的,咱们在这里作的一个优化使之无需重启。咱们作了一个在线归档的功能,只要用户点击某个命令,开启incremental backup log的归档,咱们会有对应的进程把log收到OSS上面去。由于咱们的备份恢复是对等拓扑的,节点在恢复的时候都会对应到与它相关的token的节点上去。它恢复的时候能够作本节点的nodetool flush以及本节点的commitlog replay,而且这个replay是online replay。
这样的好处是备份恢复的时间是最短的。Incremental backup和commitlog的组合可让恢复的时间是最短的,由于咱们经过incremental backup的sstable筛选出须要恢复的WAL log/commitlog,而后作一个归档。这样的话能够避免log的replay的时间愈来愈多。
接下来我会介绍一下咱们的数据迁移。
Cassandra原有的数据迁移分为COPY TO/FROM命令和文件级别的sstableloader两种。COPY TO/FROM是一个多线程读写key value的操做,当数据量比较大时,它的速度会比较慢。就sstableloader来讲,O一、O二、O3节点上的数据都须要被load,load到新的集群时可能会有一些冗余。另外实时新增的数据可能处理得不会很融洽。
在这里,咱们启动了阿里云的BDS服务。不管原集群和目标集群是对等或不对等拓扑,它们均可以经过BDS高效迁移。
原有的sstableloader方案中,原集群全部节点都须要进行一个相似于streaming的过程,并在目标集群进行一个拖数据的过程。原集群中节点o1的文件可能和目标集群中的节点n一、n二、n3都会有重叠。原集群o1中的文件复制到目标集群可能要有一个三副本的放大。当原集群有三个副本,目标集群也三个副本时,一份数据经过sstableloader可能会有九倍的放大。这会产生冗余。
当使用BDS,咱们把原集群和目标集群作了数据范围的映射。原集群的primary range的数据咱们只会迁移到目标集群的primary range,副本节点的数据会迁移到副本节点。咱们的副本摆放策略默认使用SimpleStrategy,根据这个副本摆放策略咱们作一个副本范围的一一映射。当某个sstable在目标集群上横跨了多个节点时,咱们会对于这个sstable作一个切分,切分后须要把对应的数据复制到对应的节点上面去。这样能够避免数据的冗余。
除此以外,咱们还作了文件级别的迁移,速度比较快。另外咱们也支持增量数据的迁移,包括增量的commitlog和incremental backup。咱们支持实时的增量数据的迁移需求,用户只须要经过咱们的BDS服务,无需额外操做便可完成无缝迁移。
最后,我来介绍一下咱们监控报警的大概模式。咱们会分三个层面来介绍。
首先是OS操做系统层面。
由于Cassandra是share-nothing的架构,它是直接写本地的文件系统。对于本地的文件系统的error咱们会作实时探测,对网络包package的异常处理咱们也会作监控。在这里像file system error这样的相对比较重要的error,咱们会经过unavailable这样的异常报给Ops服务。咱们也会对Cassandra的daemon death进行实时监控,在Cassandra每个进程的机制下面,咱们都会有个单独的agent来发出system error,包括网络和内存的异常。另外Cassandra daemon的判活还有gc。关于gc,咱们比较关注的是时间比较长的后续状况,超过500毫秒咱们会经过发出unavailable异常报给Ops同窗。
第二个层面是Logs层面异常的收集。
第一是slow cql,就是读的时候比较慢的cql,咱们会收集。gc log是Cassandra本身的GCInspector的log,还有warn log好比large partition。这些咱们会经过SLS收集,以后相关的报警也会告诉咱们值班的同窗,最上层是Cassandra本身的metric的信息。Metric信息咱们会分两类进行处理。第一是展现给用户的Metric,好比容量、compaction等,是咱们以为用户会比较关心的,会经过CMS给用户。全量的80%的metric也会经过CMS链路报给咱们本身的Ops同窗。经过这种方式,咱们能够对metric也设置一些报警。