分布式数据库数据一致性(Consistency)保证原理讲解及实现。随着分布式技术的发展,数据一致性的解决方案和技术也在不断演进。本文以笔者实际开发的分布式数据库为案例,介绍分布式数据库数据一致性的原理和实际实现。1.数据一致性1.1什么是数据一致性?大多数使用传统关系型数据库的DBA看到“数据一致性”时,第一反应可能是数据在跨表事务中的数据一致性场景。而本文介绍的“数据一致性”指的是“数据多副本存储时如何保证数据一致性”的场景。在大数据领域,数据安全不再靠硬件来保障,而是通过软件的方式,通过将数据同时写入多个副本来保障数据安全。当数据库同时向多个副本写入记录时,如何保证每个副本的数据是一致的,称为“数据一致性”。1.2关系型数据库如何保证数据的一致性?传统关系型数据库对运行环境和硬件要求比较高。比如Oracle推荐用户使用小型机+共享存储作为数据库的运行环境。DB2DPF也推荐用户使用更好的Server+高端存储来搭建数据库的运行环境。因此,在数据存储安全的技术要求下,传统关系型数据库更多地依赖硬件技术来保障数据安全。由于关系型数据库的数据安全是基于硬件来保证的,数据不会同时存储多份以保证数据安全,所以关系型数据库的用户默认假设数据存储是一致的。1.3分布式存储如何保证数据一致性本文讨论分布式存储,主要是指SequoiaDB、HDFS等大数据产品中的分布式文件系统和分布式数据库。用户在理解分布式存储中数据一致性的原理时,首先要理解为什么需要数据一致性,以及分布式存储中的数据存储与关系数据库中的数据存储有什么区别。大数据技术的诞生,确实让系统的性能有了新的突破,支持硬件以横向扩展的方式实现性能和存储的线性增长。这些都是过去传统关系型数据库无法提供的。此外,大数据技术也摒弃了运行环境必须足够好的硬性要求,而是允许用户通过批量廉价的X86服务器+本地磁盘来构建大规模集群,从而获得比过去依赖于服务器更强大的计算能力。硬件垂直扩展。容量和更多的存储空间。大数据技术的核心思想是分布式,将一个大任务分解成多个小任务,然后通过分布式并发运算完成,从而提高整个系统的计算效率或存储容量。在分布式环境中,由于对硬件的要求较低,大数据产品必须提供另一个重要的功能——数据安全。大数据产品在数据安全方面比较接近。简单来说就是将一份数据以异步或同步的方式存储在多台机器上,以保证数据的安全。在解决了数据安全的技术难点之后,分布式存储又引入了一个新的技术问题,就是如何保证数据在多副本中的一致性。目前SequoiaDB使用Raft算法来保证多副本数据的一致性。2.Raft算法2.1Raft算法背景在分布式环境下,最好的共识算法应该是Paxos算法,但是因为太晦涩难懂,2013年,DiegoOngaro,JohnOusterhout两人设计了一套共识以可理解性为目标的算法Raft。Raft算法最大的特点就是简单易懂,易于实现。2.2概述Raft算法不同于Paxos。Raft强调它很容易理解。和Paxos一样,Raft只要n/2+1个节点正常就可以提供服务。我们都知道,当问题比较复杂的时候,可以把问题分解成几个小问题来处理。Raft也用到了分而治之的思想。Raft算法主要解决三个子问题:选举(Leaderelection)、日志复制(Logreplication)和安全(Safety)。Raft算法加强了Leader节点的功能,Follower节点的数据只能从Leader获取,所以Follower节点的实现变得简单,只要负责与Leader保持通信并接受Leader推送的数据。2.3Raft算法原理2.3.1节点角色在Raft算法中,节点的状态分为三种角色,分别是Leader(***)、Follower(跟随者)和Candidate(候选者)。Leader,负责处理来自客户端的请求,负责将日志同步到Follower,并保证与Follower的心跳连接;Follower,集群刚启动时,所有节点都处于Follower状态,其工作主要是响应Leader的日志同步请求,响应Candidate的请求,将Follower的事务请求转发给Leader;theCandidateisresponsibleforvotingwhentheLeaderiselected.选举出Leader后,节点将从Candidate状态变为Leader状态。2.3.2术语在分布式环境中,“时间同步”一直是一个长期存在的技术难题。为了解决这个问题,Raft将时间划分为Term(可以理解为“逻辑时间”)来处理不同时间段的数据一致性。条款有以下原则。在每个任期中,至多有一个Leader。在某些方面,可能会出现选举失败导致没有领导者的情况。每个节点维护自己的本地currentTerm。每一项都是一个不断增加的数字。如果follower的Term编号小于其他FollowerTerm编号,则FollowerTerm编号将更新Term编号,使其与其他FollowerTerm编号保持一致。2.3.3选举Raft的选举是由定时器触发的,每个节点的触发时间不同。所有节点一开始都处于Follower状态。当定时器触发选举时,Term数增加。节点状态由Follower变为Candidate,向其他节点发起RequestVoteRPC请求。此时可能会出现三种情况进行选举:发起RequestVote的节点收到n/2+1(超过半数)个节点的选票,该节点将从Candidate状态变为Leader状态,并开始发送HeartBeat到其他节点维持Leader的正常状态。如果收到投票请求,如果节点发现发起投票的节点Term大于自己,则节点状态由Candidate变为Follower,否则保持Candidate状态,拒绝投票请求。如果在选举过程中发生超时,Termnumber将递增并重新发起选举。2.3.4日志复制日志复制的主要作用是保证节点的数据一致性和高可用。Leader选举出来后,所有的事务操作都必须由Leader处理。这些事务操作成功后,会依次写入LOG,每条LOG包含一个索引号。LOG发生变化后,Leader通过HeartBeat将新的LOG同步给Follower。Follower收到LOG后,向Leader发送ACK消息。当Leader收到最多(2/n+1)个FollowerACK消息时,设置LOG为已提交,Leader将LOG追加到本地磁盘。同时,Leader会在下一个HeartBeat通知所有Follower将LOG存储到各自的本地磁盘中。2.3.5安全性安全性是一种安全机制,用于保证每个节点按照相同的日志顺序执行。如果一个follower没有同步leader的日志,但是这个follower以后有可能被选为leader,可能会导致之前leader提交的日志被覆盖,导致节点执行不同顺序的日志。Raft的安全性是保证选出的Leader必须包含一个机制,这个机制之前已经提交了LOG。主要原则如下:每个Term只能选举一个Leader;Leader日志的完整性,当Candidate重新选举Leader时,新的Leader必须包含之前提交过的LOG;Candidate在选举新的Leader时使用Term来保证LOG的完整性;3、分布式数据库数据一致性技术实现以国内原厂的分布式数据库SequoiaDB为例,SequoiaDB在多副本部署中使用Raft算法保证多副本环境下的数据一致性。在SequoiaDB集群中,一共有3个角色节点,分别是协调节点、目录节点和数据节点。由于协调节点本身不存储任何数据,只有编目节点和数据节点有事务操作。也就是说,编目分区组和数据分区组的副本同步使用Raft算法来保证数据的一致性。3.1目录节点和数据节点的事务日志介绍由于目录节点和数据节点都需要存储数据,在集群部署中,为了保证数据安全,建议采用分布式部署,所以在数据同步时,需要利用Raft算法的基本原理进行数据同步。目录节点和数据节点存储数据时,包含两部分,一是真正的数据文件,二是事务日志文件。SequoiaDB的节点事务日志,默认由20个64MB的文件组成(总大小为1.25GB)。节点的事务日志主要包括索引号和数据操作内容,索引号永远递增。另外,SequoiaDB节点的事务日志不会全部保存,而是当所有的事务日志都满了之后,会重新从第一个文件开始覆盖。3.2编目分区组的数据一致性由于编目分区组是存放SequoiaDB集群的元信息,对数据同步的要求很高,所以编目分区组的数据一致性要求是强一致性,即每次一个对cataloging分区组进行事务操作,在计算操作执行成功前需要保证所有catalog节点操作成功,否则事务操作会回滚整个catalog分区组中的事务日志,以保证数据分区组内的一致性。另外,目录分区组还有一个重要的特点,就是目录分区组必须有主节点才能正常工作。如果旧主节点宕机,目录分区组暂时没有主节点,则目录分区组将无法对外提供任何事务操作和数据查询操作。3.3数据分区组数据一致性数据分区组数据一致性默认为最终一致性,即只需要主节点执行事务操作成功,即操作成功,主节点会异步同步ReplicaLOG到slave节点以后上级。3.4主从节点事务日志同步SequoiaDB的主从节点通过事务日志同步来保证数据的一致性,主从节点的事务日志同步由单线程完成。如果主从节点的LSN差为一条记录,则主节点会主动推送最新的事务日志给从节点。如果主从节点的LSN差距超过一条记录,从节点会主动请求主节点同步事务日志。主节点收到同步请求后,会将从节点的LSN号传送到主节点的LSN号***对应的事务日志,一次性打包发送给从节点。3.5从节点日志重放当从节点获取到主节点推送的事务日志时,会自动解析事务日志并进行重放。从节点重放事务日志时,默认以10并发重放事务日志。Slave节点在执行并发重放日志时有条件限制,即当集合中唯一索引个数<=1时,INSERT、DELETE、UPDATE、LOBWRITE、LOBUPDATE、LOBREMOVE操作可以支持事务日志的并发重放.从节点在并发重放时,会使用记录的OID进行并发执行,这样对同一条记录的操作就不会因为并发重放而导致数据不一致。但用户需要注意,从节点在重放事务日志时,DROPCL操作不支持并发重放。4.SequoiaDB数据一致性应用目前SequoiaDB数据分区组的数据一致性是基于集合级别配置的。在使用SequoiaDB的过程中,用户可以随时调整数据一致性的强度。4.1创建集合时,指定在多副本SequoiaDB集群中,集合默认的数据一致性行级别为“最终一致性”。用户可以在创建集合时明确指定集合的??“数据一致性强度”。例如在SequoiaDBShell中可以执行如下命令:db.CSNAME.createCL(“CLNAME”,{ReplSize:3})ReplSize参数填写范围4.2修改现有集合如果集合没有设置“数据一致性”"ReplSize参数在创建集合时,用户还可以修改现有的集合。SequoiaDBShell中修改命令如下:db.CSNAME.CLNAME.alter({ReplSize:3})ReplSize取值范围与创建集合时相同。4.3如何查看集合的ReplSize参数如果用户想查看当前集合的RepliSize参数值,可以通过数据库快照查看。在SequoiaDBShell中查看的命令如下:db.snapshot(SDB_SNAP_CATALOG,{},{"Name":null,"IsMainCL":null,"MainCLName":null,"ReplSize":null})打印信息为遵循{"MainCLName":"test.main2","Name":"foo.bar2","IsMainCL":null,"ReplSize":null}{"IsMainCL":true,"Name":"test.main2""MainCLName":null,"ReplSize":null}{"Name":"foo.tt","ReplSize":3,"IsMainCL":null,"MainCLName":null}5。总结一下分布式数据库,在分布式情况下使用Raft算法保证数据一致性,目录分区组和数据分区组对数据一致性的要求不同,目录分区组总是需要数据强一致性的情况数据的多个副本,数据分区组可以由用户在创建集合时实现。强度越高,数据安全性越好。但是执行效率会比较差,反之亦然。目前,在SequoiaDB的数据一致性场景下,用户有很大的调整空间。数据一致性的强弱可以根据不同的业务需求进行调整,以满足业务的技术要求或追求最佳性能,或数据最安全。
