各位线上的嘉宾朋友大家好,我是来自华为消费者BG云服务部的刘腾,我今天给大家分享的主题是华为终端云Cassandra运维实践。和前面王峰老师提到的Cassandra在360中使用场景不同,我今天主要带来的是运维相关的内容。在去年7月,我们开发部的吴太银也在Cassandra社区做过一次分享,讲到了Cassandra在华为的一些应用,包括一些在华为遇到一些线上问题的定位和处理经验。今天我就和大家讲一下运维这一块。
这是我今天要分享的内容,重点是第二部分:我们在运维中遇到的一些问题。
华为终端云Cassandra使用场景和规模介绍
我们首先介绍下华为终端云在Cassandra使用的情况,华为在2014年的时候开始使用Cassandra,这在国内也是相对比较早的。现在经过6年的发展,我们达到了比较大的应用规模,全球节点数已经超过3万,总存储量超过20PB,还有最大的这个表记录数三千亿以上,这个量都是比较大的。
至于为什么华为终端云大量地使用Cassandra,这主要归功于Cassandra本身的一些数据库优势,比如它高可用、极致在线(应用无感)、可调一致性、多DC(datacenter)部署的特性。此外对运维方面也是很友好的,还有一些运维的工具等等。因此Cassandra在华为终端云这一块应用的是比较多的。
我们主要将Cassandra用在一些结构化的数据存储,像我们的社交风控、IoT等场景都用到了。现在我们也有多个版本,最早的时候我们用的是Cassandra 2.x的版本。这是我们华为终端云的一个使用情况。
运维面临的主要挑战
我们在终端云这一块业务发展的这么快,Cassandra规模这么大,我们难免也会遇到一些问题,主要体现在以下这四个方面。
-
可靠性:早期我们是IDC机房,这种自建的托管的机房。我们需要维护这些硬件设备、处理硬盘损坏的这些问题。还要考虑到机房AZ级的这种故障,或数据一致性、备份的问题。然后在使用上,现网还会碰到Cassandra的一些本身的问题,像是大Key和热Key的问题。
-
数据库问题和风险管理:在日常的一些变更管理的问题尤其是一些高危操作。
-
资源和成本管理:此外是资源成本这一块。我们有这么多节点,如何管理是个问题。
-
运维效率: 我们人数有限(2~3)人,那如何提高运维效率。
我会主要围绕以上这些话题来讲,当遇到这些问题时我们华为终端云是如何做的。
华为终端云Cassandra运维体系介绍
其实整体也是一个过程,我们一开始也是慢慢地摸索过来的。然后我们才有一些比较规范的运维流程,因为运维还是很注重流程的,就是按流程去正确的做事,所以流程很重要,我们包括一些变更流程、问题处理流程等等。大家也都听说过,华为公司本身就很注重流程的规范性、流程的建设。
我们自己经过这几年的发展,把平台也建起来了,但我们依托一些大平台, 比如说监控的,包括部署和自动发布的这种平台。还有我们自己专门开发的Cassandra运维管理的平台,像一些做数据库自动化变更的平台。我们会在后面重点介绍在可靠性、风险管理、运维效率等方面的挑战。
运维实践经验分享之可靠性:大集群拆分
首先我们会讲一下可靠性这一块,在我们的大集群中会遇到一些问题,这是在我们现网里发生的一个例子:
我们有一个超过450节点的大集群,它的Token总数也比较大,超过10万。但在我们当时扩容的过程中,业务所有的节点负载都很高,业务也受到影响。事后我们对其进行了分析,发现原始Cassandra客户端请求、计算路由的时候会有一个读写锁。这本质上当有节点在扩容的时候,它也会更新路由信息。如果你更新比较慢,锁一直没被释放,这会导致你后面的读写也拿不到锁,这样的话就会导致你的请求一直出差,最终你的服务器负载要持续升高,那就出现问题。
对于这种问题,我们就有一些建议。一个是你的控制集群的规模,尤其是虚拟Token数量。我们原来最早的时候设的Token number数的是256,如果节点一多,那Token总数就会很大,这便会影响它本身的计算性能。因此我们建议Token数不要超过10万。其实我们在社区上也找到过一个case,跟我们这个情况差不多,他当时也遇到这个问题。 他好像是Cassandra 3.x的版本,我们是当时还是Cassandra 2.x的版本。
然后对于一些新的集群,如果你的数据很大,要提前做好容量规划,尽量不要让集群中单节点负载过大,不要等到事后再去拆分。我看到之后Cassadra 4的版本优化了Token的分配和管理机制,那在后面是可以尝试升级到Cassandra 4的版本的。
这里我其实是通过这个案例来讲为什么要做大集群拆分,其实如果集群太大的话,它还会带来一些问题,比如说你这个扩容会比较慢,因为你每次只能扩一个节点,对不对?你的集群一大,你扩容肯定会比较慢,还有就是数据修复也会比较慢。
所以对于这种大集群,我们是建议要控制规模。虽然理论上Cassandra也许可以支持几百上千个节点,但如果你真正到那么大的规模,我觉得对于运维来说是一个非常大的挑战,对系统稳定性也有一定影响。
我们原来有一个业务集群就做了一个拆分,那怎么拆?这几年来,我们的一些早期业务可能有多个服务,这些服务可能就共用了一个集群,然后通过不同的Keyspace和Table来区分。规模太大之后怎么办?我们建议它按照服务维度和keyspace表维度进行拆分。
我们这里面有几点要注意的。存量的数据,我们可以通过打快照sstableloader做一个迁移。然后增量数据我们可以用到Kafka,前提是我们要改一下我们的驱动,要支持双写。双写就是你在写你原集群的时候,你要把数据主键写到kafka里面,这样的话我们会有一个消费的程序。我去Kafka里面把主键查出来,去原集群反查,把数据写入到新集群,通过这样的方式做到一个全量加增量的数据同步。做完之后,我们可能还要做一个一致性的对比。这就是一个大集群拆分的思路。
运维实践经验分享之可靠性:多AZ部署
之前我们提到因为可靠性在IDC机房面临的一些问题,后面就慢慢迁移到云上了。其实云上也会面临一些问题,比如说你这么大的集群,你会有反亲和的问题。云上那些虚拟机你是看不到它分布在哪个物理机上面的,那就需要用到反亲和组,你不可能把你的集群机器都独立放到一台物理机上,因为公有云其实是有可能会存在这种情况的。如果有物理故障,它会影响到集群的可靠性。现在有很多云厂商都有专属物理主机,如果你集群规模都太大,你自己买单独虚拟机,然后利用Cassandra本身的机架感知,从而让Cassandra将不同副本分布在不同的机架上。
其次就是现在很多公司推荐并在使用的,也就是3AZ部署,在这里我们会介绍我们的场景的主管模式,我们在消费和终端里都有用到。比如图中的双AZ副本,它的优点也很明显,你如果client的话,你正常只会访问本地DC(图中对应的是AZ),但问题是成本高,还有要自己考虑故障切换。
3AZ3副本的优点是,我们可以把每个AZ当一个虚拟rack来看待,那读写一致性就可以用QUORUM,这样成本就会低一些,任意AZ的故障也不会影响可用性。但它也有的缺点,你因为跨AZ随机访问会增加访问时延,这取决于你AZ间网络时延。一般像公有云厂商AZ间时延说的是不高于两毫秒,但如果你的业务对这种时延比较敏感的话,那可能这种并不是特别适合。对它的性能可能也会有一定的下降,我们测试出来大概是会降低15%~20%。
现在很多初创型公司都会部署到公有云的服务器上,你们可以尝试一下这种3AZ部署方式,做一下性能测试看看效果如何。
在Cassandra原来是一个DC的情况下,如果要拓展到多个DC,我们要考虑如何同步这些数据。
首先我们既可以用nodetool rebuild也可以用sstableloader。这两种方式也有不一样的地方,build只能从原AZ(DC)其中的一个副本节点获取数据, 如果三个AZ副本不一致,那有可能无法获取一致的数据,我们因此建议在同步之前要做repair操作。sstableloader的问题是拷贝的数据量是原来的三倍,因此磁盘需要申请额外的存储空间,数据迁移完成后还要用nodetool cleanup删除冗余的数据。这两种方式可以根据你的使用情况来选择性的使用。
运维实践经验分享之可靠性:数据一致性
接着我们来谈一下数据一致性所遇到的一些问题,虽然我们使用quorum或local quorum,但这也是Cassandra会面临比较多的一个问题。因为你始终会面临坏盘、节点宕机,或某些公司出现的集群网络、负载不稳定等问题。这些都会导致数据不一致。如果你通过自己的DBA管理这些物理机,这样的成本还是比较高的。现在很多都是在云上的,包括我们也是通过云将数据迁移到虚拟机。将硬盘换成云硬盘,数据一致性相对就会好很多了。当然,它也会带来一些问题,比如成本会有小幅上升。还有hint的保留时长也可以从默认的3小时改为24小时,这对磁盘的存储增加不会很大,如果你的集群网络环境比较稳定的话,就不会有什么问题。
最后就是要对数据做一个定期地修复,也就是所谓的repair操作。你一般两周到一个月做一次,其实不会有太大的问题。但不用做的太频繁,因为修复太频繁会占用过多资源。同时你要控制修复段足够的小,并发量要控制好,尽量不要影响在线的业务。
我们其实有多个场景,用的两个最直接的部署,我们也会定期去做一个对比。在华为终端云这里,我们早期也用了ES(ElasticSearch)来弥补Cassandra二级索引的不足,但这也会带来一些问题。因为ES和Cassandra数据会有不一致,你要定期做一些检查修复。
运维实践经验分享之可靠性:数据备份
接下来我们介绍一下数据备份,这是为了一些极端的场景,其实大部分情况下你是用不到的。但对于我们这么大的规模来说,有很多重要核心数据,因此我们一定是要考虑这种备份,这里有几个场景,我就不详细介绍了。备份其实还是基于原生Cassandra的快照(snapshot)的能力。它其实本质上就用的是Hard Link,这样我们便会把这数据备份到我们的OBS存储中。目前我们RPO可以做到5分钟以内,RTO大概就是根据数据的下载的时间,一般1T数据大概要2~3小时。
我觉得对于一些小公司和初创型公司来说,你要关注的是你要出现了误操作怎么办?你可能认为你的数据不需要备份到OBS这种程度,但你可以使用Cassandra本身自带的特性,你可以把配置文件里的配置项都打开,如在做TRUNCATE的时候做自动快照。这我觉得是Cassandra的对运维来说非常好的一个的地方。如果你真的误删了,其实硬盘上并没删除。你仍可以通过快照很快地进行恢复,这也不需要什么太大的成本。不管是开发人员、还是运维人员,我强烈建议大家在后面使用的时候打开这些开关,防止一些极端的情况。
运维实践经验分享:Cassandra数据库风险治理
下面列了一些我们数据库现网的一些问题管理中的使用规则。有些开发同事可能认为这些规则限制了他,但这些机制其实是Cassandra本身的一些约束。如果你突破这些约束,你的现网可能会出现一些不可预知的问题。假如你在设计schema阶段引入了问题,到后期一旦出现问题,在短时间内是无法解决的。你要重新优化schema,做出新的版本,这会花费很长的时间。
因此在我们这里会先立规则。大家在开发的同时,一定要知道这些规范,在开发阶段就要减少这些问题。在我们华为,如果你有业务要接入Cassandra,你要按照这些规则自检一下,我们做一个简单的评审,如果没有问题,我们就会给你提供一些建议方案。如果你的分区键在你的表结构Schema设计上存在一些问题,我们会给出一些建议,让你优化之后再接入现网。如果后期实在还是有漏掉的,我们通过一些巡检,把这些问题找出来,会通知到业务,跟业务一起去做一些优化。
我看到DataStax公众号上面有一篇文章也讲的非常详细,有哪些注意事项。我认为每个开发的同事,包括运维的同事都要认真熟读一下。
运维实践经验分享:热key案例
这其实是我们一个热Key的案例,我就不详细讲了。其实你在设计Schema的时候便要考虑你的场景是否存在热Key,能规避则尽量规避,如果规避不了则需要靠多级缓存。如果热Key的话加Redis可能还不够,因为Redis也是单点的,可能还需要考虑本地多级缓存。或者用redis本身的这种前端proxy做负载均衡才能解决问题。热Key这种问题是比较难处理的,我估计很多开发人员都会所面临这种问题。但你要避免热Key出现在Cassandra中,如果出现了,对Cassandra影响会比较大,甚至会影响正常Key的访问。因此热Key在设计阶段一定是要规避的。
运维实践经验分享:CQL发布
我们有这么大的规模,因此我们经常有一些变更,需要一些数据库的自动化平台来帮我们提升一些效率并降低一些风险。我们的DBA人数有限,可能不能完成这么多事情。
我们现在有一个CQL的审核模块,它会自动把你的那些你看到那些DDL脚本解析出来。如果是非高危字段,我们可以让你走自动化变更流程。如果是DROP这样高危的删除字段操作,我们是不会让你自动在现网上运行的,要走另外的流程。对于那些刚开始的,尤其是有些公司没有运维的同事,你们的变更里如果有高危操作你一定要先识别出来。还要考虑操作前有没有备份,出现极端情况下是否有可挽救的措施,这些是一定要注意的。
运维实践经验分享:基于AIOPS多维度故障诊断
最后我们介绍下监控,因为前面看到线上的一些朋友在问监控怎么做,我们也分享一下我们的经验。其实我们比较简单,就像一些技术指标监控,这种大家都会。很多开源软件都很方便,网上的文档也很多,像早期的Zabbix和现在的Prometheus。包括Cassandra内部的JMX,在采集metrics时都有现成的模版,Prometheus也都有相关的支持。我觉得大家可以把这些监控都加上。我们后面也有自己加的监控,比如说我们自己在驱动里面会把一些时延成功率等这些信息打到日志里,然后上报到我们的日志平台中做一些监控。
这个好处是你可以端到端去看你Cassandra的情况,观察客户端到Cassandra的时延成功率是怎样的。这有利于你通过一些网络等帮助你去对问题进行一些定位。还有比如我们时延成功率,我们可以做一些动态预知的告警,我们平台有机器学习的能力,当你突然有波动的时,比如有业务版本变更或者业务突然有个浪涌上来了,这时候你就知道有异常。这种便有利于提前及时去发现问题。
运维实践经验分享:自动化巡检
我们还讲一下巡检,巡检其实跟监控有一点差异。巡检其实是提前去发现问题,不是等告警的时候才发现问题。我们针对前面讲的一些指标容量风险,包括成功率时延等等进行一些巡检,但我们会做一些图。
其实对一些没有专门运维人员的小公司,你可以用那些监控的API接口自己写一个python脚本或一个Java程序。脚本每天把数据采集出来,统计汇总后,发邮件给相关责任人看一下,这样也是蛮好的,也不需要做这么漂亮的一个图。
社区版Cassandra的运维优化建议
前面我们讲了运维面临的一些挑战和实践经验,其实我们也遇到了一些问题,想提出来和大家探讨一下。
希望改进的功能:
-
Repair: 因为repair还是比较消耗CPU和IO资源的,在集群数量大时,修复时间会变长,我们还要关注对业务有没有额外影响。希望后期有人能对repair的资源占用做出一定的限制,比如做一些限制配置类的东西。
-
数据迁移的方案: 还有就是数据迁移的方案,比如以后业务要从其它数据库或者IDC机房迁移到云上的话,Cassandra有没有一些好的迁移方案,这样开发者就不需要自己做一些开发,从而提高应用性。
-
数据一致性不可度量和监控:对于数据一致性不可度量,我觉得一时半会也没有什么好的解决方案,没办法很好的监控。
-
二级索引: 目前已经支持的两种二级索引其实都是不太推荐大家使用的。
希望支持的功能:
-
支持表计数统计:我们有很多开发人员带着SQL的使用思路,想查询一张表有多少条记录。其实这目前是查不出来的,我们只能通过其它手段进行一些统计。
-
Nodetool支持commitlog的解析和回放:目前社区还没有这个功能,如果做到的话,数据备份就可以做到按时间点恢复,也就是真正的PITR(Point-In-Time-Recovery)。
-
墓碑:还有就是墓碑的一些优化。
待探讨:
-
RocksDB(优化GC问题):前面很多老师也提到了,RocksDB应该也是有一些规划的。目前RocksDB也比较火爆,很多大厂现在都在考虑用RocksDB做一些多模数据库。存储引擎好像都会用会考虑用Rocksdb。
-
3AZ部署情况下驱动优化路由算法,也就是降低跨AZ访问的时延。
-
未来是否会考虑分支,将存算分离、强一致性作为一个分支。我们企业云的兄弟部门在这方面做了一些尝试。
最后,我们2020年经历了全球的疫情,这对线上的应用确实是爆发式的增长。对于Cassandra来说是有很多机会的,实际上我们华为终端有很多应用是可以用Cassandra的。比如一些原来用Redis的可以切换到Cassandra,这对Cassandra来说都是一些机会。
提问环节
问: 怎样实现C*数据冗余复制和控制存储成本之间的平衡?
答:其实这是一个可靠性和成本之间的取舍。得根据业务场景来看,我们有一些业务它数据是核心数据,那它也愿意多出一些成本。比如说它的副本可以为三甚至达到AZ级容灾。同城双活的话,那就是6个副本。
如果对于数据可靠性要求不是特别高,三副本其实可以解决大部分的问题。甚至有一些用OLAP的场景有的我们有离线的数据,用两个副本也是ok的,要根据业务的实际场景来。
问:大集群中数据一致性修复的挑战有哪些?
答:这个问题我觉得提的很好,我们原来一些大集群,在面对前面的大数据修复时,它要面临几个问题。第一个它的修复周期特别长,还有一个就是我们对现网的影响。你修复时要控制住,不能让它有对现网产生影响。需要控制修复的并发,包括token段的切分,要切的足够小。
问:自动化C*集群运维的挑战在哪里?有哪些技术和工具可以参考?
答:其实运维这一块,我们前面其实也提到了,之前介绍了一些我们主要遇到的问题。自动化运维的话,我们有做一些自动发布和自动部署,这可以提升一些效率。也包括监控这一块,我们讲了一些多维度的监控,还有巡检。
监控的工具方面,一开始我们有用OpsCenter,开源的像是Zabbix和Prometheus这些。用于定位问题的像是自带的nodetool,有很多命令,对于日常运维效率是很有帮助的,我建议大家都去了解一下。