郭超:阿里云Cassandra背后的故事

你们好,我是阿里云数据库产品事业部的玄陵,真名郭超。node

本次的分享大概分三个部分:Cassandra云数据库简介、Cassandra云数据库特性以及Q&A。数据库

咱们先了解一下Cassandra云数据库在阿里云上的部署和架构。首先这个架构主要反映了三个方向:​安全

  • 安全保障和VPC隔离:在阿里云上,Cassandra数据库的不一样用户有不一样的VPC。经过VPC隔离和白名单,能够保证在阿里云上用户之间的数据是相对安全的。由于每一个用户有本身的VPC环境,在本身的VPC环境下只能访问本身的VPC数据。不一样的VPC之间是不能够互相访问与之无关的VPC帐号的数据的。在同VPC下,能够实现单DC或多DC容灾的部署。
  • 高可用:阿里云上Cassandra的高可用性分为单DC以内replica级别的高可用以及DC之间容灾的高可用。
  • 功能丰富:具备备份和迁移等功能。每一个VPC环境下的用户的集群能够经过咱们本身实现的系统备份到OSS上面。阿里云OSS能够提供极致的数据可靠性的服务。

接下来咱们深刻了解一下单个DC和集群的状况。网络

  • 运维自动化能够提供自主运维。咱们本身实现的Cassandra-mate的服务能够实现一些运维的自动化,好比compaction的调优、节点扩容和增长节点、以及监控和报警。
  • 为了追求高性能,咱们在内核定制以及性能加强方面作了一些相关的改进。
  • 灵活易用,咱们的云服务是百分百兼容Apache Cassandra CQL的协议。

除此以外,咱们其它的架构和Apache Cassandra几乎是同样的。多线程

接下来咱们介绍一下Cassandra云数据库的特性:架构

  • 开箱即用:免除运维烦恼
  • 弹性伸缩、线性扩展:在云环境下,利用云的资源能够进行快速的扩容和缩容,这点很是符合Cassandra现有的特性。
  • 高可用、多活:多副本、持续可写、就近读取,这个是Cassandra自带的。
  • 备份恢复:在Cassandra的基础上咱们作了一些配置,好比全量和增量备份和恢复,从而保证至关高的数据可靠性,以防DBA的误操做(好比删库)形成数据不可用。
  • 细粒度监控:能让性能数据一目了然。

即将上线的服务包括:并发

  • 安全加固:SSL+TDE全链路加密
  • 审计日志:访问记录、有据可查
  • CloudDBA:自动诊断、智能优化

接下来,咱们介绍一些咱们在功能上作的优化。因为时间关系,咱们只能重点介绍一部分功能优化。运维

第一点,咱们作了一些自动化运维手段。性能

这个事情的背景是因为Cassandra是一个去中心化的数据库,社区建议用户作repair,目的主要是保证Cassandra三个或多个副本之间的一致性。Repair可以把副本上的数据作一个修复或者补齐,保证副本的数据是一致的。Repair是必需要作的,然而在咱们的使用场景中,repair会引入一些问题:优化

  • 扩容缩容会增长运维难度:在目前阿里云的部署环境下,一个用户对应一个或多个cluster,当用户增多,须要管理的集群规模或数量就很是多,这会给咱们repair的运维带来比较大的困难。
  • 当某个集群扩容或缩容时,咱们须要对repair作一些相应的调整,这也会增大运维的难度。Repair的过程会产生极大的资源开销,会影响咱们线上的一些服务。
  • 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。这样的部署模式会引入一些问题:

  • ​咱们看到写入链是先写入commitlog,再写入memtable,而后再返回给客户。那么当咱们把一个commitlog部署在Cloud Disk 1上面,它的写入吞吐会受到Cloud Disk 1的限制。另外commitlog如今在社区也是不支持部署在多盘上面的。
  • ​第二个点是在咱们这个云上面涉及到产品形态的设计。首先,commitlog这个盘对咱们不会产生费用,咱们只售卖sstable的文件存储。那么若是这样去设计的话,额外的commitlog存储会产生额外的费用,继而产生对客户的额外费用,这样对客户来讲相对不太公平。
  • ​第三,若是咱们有四块盘,咱们拿出一块盘给commitlog,其它的给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也设置一些报警。

相关文章
相关标签/搜索