OceanBase、TiDB、Cockroachdb虽然都是原生分布式数据库,但彼此有很明显的架构独特性:TiDB集群由至少3种不同节点角色混合搭建组成,存在单点风险较大;而CRDB集群只存在一种节点角色,是完全对等部署架构,是最符合终极分布式的架构;OB则介于二者之间,实现了对等部署,但是系统中关键功能模块依然采用了集中式服务。
造成架构区别的主要原因是事务处理机制不同导致。
数据库在数据计算过程中必须要保障ACID特性。所有的数据库无一例外都用到了相同的基本手段,就是为每个事务都分配一个不断递增的“标识”,这个标识在两个事务发生冲突时,能够通过比较大小反映发生的先后关系,从而为解决冲突提供事实依据。
另外,数据库在操作数据前,要先知道数据存储在哪个节点、磁盘、目录、文件上,而这些路由信息则由元数据进行统一维护。
在原生分布式数据库中,每个计算节点都能承接SQL连接,处理事务请求。如何保障不同节点的事务能够获得全局递增的标识呢?又如何让每个节点都能访问到有效的元数据呢?
最简单的方案,就是单独部署一个管理节点,所有计算节点发生事务时都到管理节点上申请事务标识、查询元数据,如此就能避免数据不一致的情况发生。(就像一个部门,设立一个领导,所有事情做不做,怎么做,都听领导的,避免每个人各做各的,最终工作合并不到一起~)
TiDB就是采用了这样的架构,整个集群中由多个不同角色的节点组成,包括:tidb节点,是仿MySQL引擎的计算节点;Tikv节点,是存储数据的节点,由raft协议和rocksdb组成;然后就是PD节点,这就是上面说的,单独部署的管理节点,处理事务和元数据,它还管理集群状态,例如执行扩缩容、故障识别与应对...。
PD节点虽然也部署了多个,但是其本质上只有一个承担核心任务(事务管理),其他都是为了高可用准备的从节点。
这样架构简单、方便,容易实现,但是存在这样几个瑕疵:
1)管理节点leader故障怎么办?
PD中的主leader如果故障了, follower可以重新选主。但是我们做过数据库运维的都知道,这种主备切换需要经过“发现、重连、确认故障、切换”等一系列流程;如果重试次数和响应时间参数设置小了,系统就会经常主备切换,稳定就变差;如果设置大了,一旦故障切换时间就会很长。
而切换过程中,所有计算节点都需要等到新的leader产生,然后分配事务标识,所以集群将处于彻底夯住的状态,业务都被暂停...
2)管理节点都发生故障了怎么?
3-5个管理节点对数十、上百个节点的大集群而言,毕竟是少数物理节点,元数据也只能存储在这几个少量的固定节点中,一旦都都发生故障,那么系统就完全损坏无法恢复了,数据也都全部丢失。所以系统的生死完全依赖少数PD节点的健康。
3)跨中心多活部署就更不可能实现的。
分布式说来说去还都不是终极的跨地域远距离分布式,显然PD的leader在哪,哪就是真正的生产中心,虽然能跨地域的异地部署,但也异地节点只能用作容灾,无法承担事务性业务,因为异地事务无法忍受跨越成百上千公里,去PD leader那里申请事务标识、访问元数据等产生的性能消耗。
虽然TIDB还有这些小的瑕疵,但不可否认其已经是一款非常优秀的分布式数据库,在一般的业务系统中应用应该是足够的了。但我们不得不思考,在分布式架构上是否有更完善的方案,能够解放分布式数据库受到单一/少量管理节点的限制,让计算节点实现更大的自由、系统更可靠、数据更安全呢?
————大家可以去了解一下CRDB的架构,或者(公众号:天下观查)等明天我分享一下CRDB和OB做到了如何...