分布式数据库理论知识

前言

分布式数据库作为一个新兴基础软件,还没有一个相对的标准的来定义它,但我们可以从两个视角来观察。

外部视角

业务系统划分

分布式数据库特点

针对OLTP场景关系型数据库:

内部视角

强一致性

分布式数据库一致性主要指数据一致性事务一致性

数据一致性

主要关注点是单对象,单操作多副本上的一致性

事务一致性

事务一致性更多关注的是多对象,多操作单副本上的一致性

BASE理论是一个很宽泛的定义,承诺很有限,放弃量一些ACID的特性从而简单地实现了高性能和可用性 

广义的事务一致性被细化为ACID四个方面,原子性的实现依赖于隔离性并发控制技术持久性日志技术

最早的隔离级别定义是ANSI SQL-92,也就是我们平时常说的未提交读,已提交读,可重复读,可串行化。主要基于的并发控制。而Critique是更严谨的隔离级别,定义了6种隔离级别,8种异常现象。其中幻读的处理还可以依靠快照隔离,但是无法解决写倾斜的问题

写倾斜

事务T1和事务T2对同一区间数据进行相反的修改,可能得到不是目标的结果

隔离性是事务的核心。降低隔离级别,其实就是在正确性上做妥协,将异常现象交由开发人员去解决,从而获取更好的性能。除了串行化,都有无法处理的异常现象

可提交读,可重复读,快照隔离,是大多数单体/分布式数据库普遍提供的,可串行化在少数产品才有提供

架构风格

分布式数据库大多分为两种架构

数据库的架构

PGXC单体数据库自然演进

单体数据库面临高并发场景写入性能不足问题,简单直接使用分库分表来实现,在多个数据库前增加代理节点来路由数据

代理节点不仅仅是路由数据

NewSQL

放弃数据库事务处理能力,将重点放在存储和写入能力,高可靠上,这个能力基础是分片,实现更小粒度单元,使用LSM-Tree替换B+Tree模型,大幅提升存储引擎能力

全局时钟

授时机制需要抓住3个要素

常见授时方案

3要素可以产生8种可能性,但是真正能用到实践的方案,常见的有4种:

TIDB

TIDB的全局时钟由两部分构成:高位物理时间(操作系统毫秒时间);低位逻辑时间,18位数值。TIDB提供的多个节点构成Raft组,通过共识算法可以保证主节点宕机快速选主,短时间快速恢复授时服务。通过预申请时间窗口来分配时间戳,保证新主产生时间戳一定大于旧主。客户端缓存时间戳会造成不再是严格意义的单调递增

分布式授时HLC

// todo

分片

分区是将数据表按照策略切分成多个数据文件,这些文件仍然在单节点上;分片进一步将切分好文件分布到多个节点

PGXC的hash能够过滤原有数据业务特性,保证数据均匀分布到多个分片,但是对动态扩展不友好Range静态分片能够对业务的预估,并且高效的对数据进行扫描,但受制于单体数据库,很难变动数据和应对负载变化

NewSQL动态分片:

NewSQL通过Group,一个主副本多个副本组成,通过共识算法完成数据同步,每个group独立运行,共享网络,节点资源,不同group主副本分布在不同节点;PGXC最小可靠单元由一个主节点,多个备节点组成set,set主备节点间复制,多数采用半同步复制,平衡可靠性和性能,所有节点主副本必须运行在set主节点

元数据的存储

静态分片,将元数据复制多份放在对应工作节点,兼顾性能和高可靠,即使协调节点是工作节点,随着集群规模扩展,导致元数据副本过多,但由于哈希分片基本属于静态分片,也不用考虑多副本一致性问题,TBase就是这样;

但是对于要更新分片时,因为副本过多,数据同步的代价过大的问题,TIDB通过paxos协议复制数据在小规模集群进行传输。TiKV存储分片数据,PD存储元数据,TiKV定期主动向PD报送元数据心跳,PD将分片调度指令放在心跳返回信息中。等TiKV下次发送心跳时,PD就能了解调度执行情况。由于心跳包含全量分片元数据,PD都不用持久化元数据,仅仅可能作为缓存而已;适用于副本少,参与节点少情况

CockroachDB基于Gossip的去中性化P2P架构,每个节点保存完整元数据,通过小范围传播实现最终一致性,在节点请求过程中不断更新元数据,促成各节点元数据达成一致;适用于副本多,节点多情况

//todo Raft,Paxos对数据复制效率对影响,Raft的阻塞优化,并x

原子性保证

tcc仅仅是应用层的分布式事务框架,依赖于业务编码实现,对业务侵入比较深。而且要求tcc操作是幂等操作;

2pc的问题是由于要锁定对应数据行,会造成同步阻塞的问题;而且事务管理器一旦故障,会发生单点故障的问题;最致命的是在最后一个阶段commit的时候如果出现网络问题,会导致部分数据未收到请求而导致数据不一致的问题

GoldenDB和Percolator对2pc的优化

使用了XA事务的延迟是单机事务的10倍以上,优化方法: