首先我们会讲一下可靠性这一块,在我们的大集群中会遇到一些问题,这是在我们现网里发生的一个例子:
我们有一个超过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里面把主键查出来,去原集群反查,把数据写入到新集群,通过这样的方式做到一个全量加增量的数据同步。做完之后,我们可能还要做一个一致性的对比。这就是一个大集群拆分的思路。
之前我们提到因为可靠性在IDC机房面临的一些问题,后面就慢慢迁移到云上了。其实云上也会面临一些问题,比如说你这么大的集群,你会有反亲和的问题。云上那些虚拟机你是看不到它分布在哪个物理机上面的,那就需要用到反亲和组,你不可能把你的集群机器都独立放到一台物理机上,因为公有云其实是有可能会存在这种情况的。如果有物理故障,它会影响到集群的可靠性。现在有很多云厂商都有专属物理主机,如果你集群规模都太大,你自己买单独虚拟机,然后利用Cassandra本身的机架感知,从而让Cassandra将不同副本分布在不同的机架上。