在原生分布式数据库中,数据的多个副本采用一致性协议实现同步,其中OceanBase(简称OB)采用了Paxos协议,TiDB和Cockroachdb(简称CRDB)采用了Raft协议。
有朋友说,之所以OB采用Paxos,是因为其始于2010年,那时Raft协议还没有出来,否则OB也会用Raft了。其实,到今天我们还去研究原生Raft和Paxos哪一个协议更好时已经没有什么意义了...
虽然两种协议在原生定义中实现方式有很大不同,但是分布式数据库要确保副本数据一致性和性能体验的目标是一致的,所以经过厂商一系列工程实现,两者在产品中都有比较趋同的表现效果(上一篇文章已经说过了,这里就不细说了)
Paxos和Raft协议的应用效果上还有一个很大的不同点,就是对并发事务的支持上:
1)Raft的实现流程比较简单,因此为了保证一致性,日志复制的过程是严格按照log-index顺序执行的。
即同一个Raft-group(region)内部如果有多个并发事务修改数据,那么这些数据在多个副本之间同步日志时是串行进行的,所以这样的并发事务如果很多,那么就会产生很大的性能阻碍;
所以,我们看到用Raft协议的数据库,数据都是按range(范围)进行切片的(另外也支持hash切分,其实hash也是一样的,把数据划分到不同的hash桶以后,每个桶内还是会按range再次切分)。
Range切分的原理就是对数据以主键进行排序,然后尽量切分成大小均匀的多个切片(切片的大小可以通过参数控制)。
每个切片的多个副本之间构成一个Raft-group,如此就把大量数据尽可能分割成更多细小的切片,通过增加Raft-group的数量来提高并行事务的支持能力。
通过对Raft这一特性的了解,我们在日常应用的时候,如果发现性能问题是region(分片)内部并发事务出现了瓶颈,那么就可以把region切的更小,以尝试解决这个问题。这就是DBA/运维人员学习理论知识的价值。
小强(crdb)有一个自动优化的功能:当某个region的qps(每秒访问量)达到2500次以后就会自动切分成多个region,tidb也有类似自动优化机制。
所以,当你听到某个分布式数据库使用Raft机制时,那么你应该能基本确认它是按range切分数据的,这也算是应用Raft协议的无奈之举,但这并非全是坏处。
2)Paxos内部是允许日志乱序同步的,所以能够支持并行事务。
例如ob即便用partition切分数据,每个分区切片的数据量可能很大,并发事务的日志复制一般也不会成为瓶颈。所以Paxos相比Raft,确实在某些场景中能够提升性能;
但这也不能说明Paxos就完全优于Raft,Raft逻辑简单、工程实现方便,研发掌握也能轻松,这样研发人员对产品的可控能力就更强。
另外在分布式系统中,切片是物理分割的最小单位,一个切片必然只能存储在一个节点上。数据库在进行存储均衡、扩缩容时,都是以切片为最小单位进行移动数据的,所以按range切分的数据库,其切片会更细小,也就意味着存储会更均衡、不容易发生数据倾斜,扩缩容时数据迁移能够更方便;
另外切片越小,越方便缩小热点数据的范围,方便将热点数据再次打散、迁移;而这些特性是基于partition切分数据所无法实现的。
同时,基于range切分数据,无论一张表中的数据量增长到如何程度,最终它都会切分成指定大小的众多切片,均匀分散在集群中,所以理论上这样的系统对单表数据容量是没有限制的,性能和容量不足时,增加服务器节点数量就可以了。而基于partition进行分布,那么显然单个partition的数据量是有限制的;如果数据量很大时,那么开发、运维人员就必须既掌握业务数据特性,又要理解分布式数据库部署架构,才能设计出合理的partition规则,实现存储均匀和消除可能的数据热点。
总结一下,Paxos(OB)因为支持单分片内事务日志并发同步,所以性能更好一些。Raft(crdb/tidb)因为将数据切分的更细小,从而能够使存储更均衡、能提供数据库内部自动优化机制(热点数据处理)、能存储更大的数据量。
所以,从一致性协议角度分析,如果对开发、运维人员能力比较自信,并且追求极致性能,可以选择OB;如果业务数据量较大,且运维开发精力有限,那么选择应用Raft的产品(tidb/crdb...)就没错了。(关注作者同名公众号)