DCF
简介
概念
DCF(Distributed Consensus Framework)分布式一致性框架,是一款自研的高性能、高度成熟可靠、易扩展、易使用的独立基础库,其他系统通过API接口可方便地集成DCF组件。DCF基于Paxos协议实现,解决分布式一致性问题,提升集群高可靠高可用能力。
作用和价值
DCF常用于数据库高可用场景,保证数据库多副本日志存储的一致性,以及对外提供高可用能力;同时,DCF具备自选主能力,单点故障时RTO小。
DCF与Quorum的对比
- Quorum:分布式系统中确保数据一致性和可靠性的机制,主要用于多副本存储系统。无法自选主自仲裁,当出现日志分叉时,需要做build恢复。
- DCF:基于Paxos协议开发的分布式一致性框架,具备自选主自仲裁逻辑,主机故障时备机自动感知,快速选主,RTO小;事务提交、回放等操作前都进行一致性控制,在节点故障、主备切换时不会出现日志分叉问题,避免了不必要的build。
原理
DCF自选主基本原理
如图1所示,DCF自选主有Follower,Candidate和Leader三种基础角色。
超时驱动:Leader每隔Heartbeat Timeout发送心跳,Follower超过Election Timeout未收到主机心跳时发起选举,变为Candidate状态。
随机开始:在Election Timeout基础上叠加随机值,降低选举碰撞概率。
选举动作:term增加,广播投票消息,变为Candidate状态,根据日志判断是否投票,获得超过半数票当选Leader。
正确性:同一term最多形成一个Leader,通过严格数学证明防止脑裂。
term相当于分布式系统的"逻辑时钟",用于解决节点间的leadership竞争、日志一致性校验和过期信息识别等问题。
DCF日志复制基本原理
如图2所示,主机产生日志,复制到备机,日志达成多数派一致后提交,最终每个节点日志相同,保证强一致。
- 每条日志包含log term和log index。
- 某个值如果被大多数节点写入日志且在当前任期内则日志可以被提交(任期的概念见上文说明中的term描述)。
- 已经提交的日志不可更改,可以应用到上层调用者。
当出现主备日志不匹配的情况时DCF会进行自动修复。图3中描述了三个节点,term为7的Leader节点和两个不同日志状态的Followers节点。
对于follower(a)节点,日志在index为4之后缺失,index1-4的日志和主机任期完全一致。主机会从初始nextIndex=10给follower(a)同步日志,但是follower(a)没有该位置的日志,会返回日志不匹配信息。主机收到响应后,会将nextIndex减一(变成9),继续上述的同步过程,直到找到nextIndex=5时,向follower(a)同步后续日志。
对于follower(b)节点,日志与主机存在冲突。主机从nextIndex=10开始持续向follower(b)同步日志,直到nextIndex=3时,备机的日志才与主机该index的日志任期一致。此时,主机会从nextIndex=4开始,向follower(b)同步自己的日志,同时覆盖follower(b)index4之后的冲突日志。
该过程可概括为以下三点:
- Leader找到Follower日志不匹配的起始点。
- 对不匹配的节点日志进行重写。
- 最终保证所有节点的日志一致。
示例
- DCF的profile日志中选举、复制相关信息如下: 图4 DCF选举、复制相关信息示例
stream_id:日志流id,默认为1。
node_id:节点id。
pause:对节点是否开启流控,0表示未开启,非0表示开启。
role:1:leader,2:follower,3:logger,4:passive,5:pre_candidate,6:candidate,7:cascade_follower。
term:当前节点的term。
commit_index:当前节点的一致性index。
match_index:当前节点收到的DCF日志的index。
next_index:当前节点期望主节点发送的DCF日志的index。
- DCF的profile日志中存储相关信息如下: 图5 DCF存储相关信息示例
stm id:日志流id,默认为1。
stm first:日志流的第一条日志位置,调用dcf_truncate时数值会进行更新。
stm last:日志流的最后一条日志位置。
stg first:DCF数据目录下已存储的第一条日志,调用dcf_truncate时数值会进行更新。
stg last:DCF数据目录下已存储的最后一条日志。
applied:DCF通知DN应用的日志信息位置(DN更新consensus lsn的位置信息)。
cache begin:存储模块日志消息缓存cache数组的第一条日志点位,cache在日志apply后或者达到阈值后会触发回收,一般cache begin大于stm first,stm last – cache begin表示cache数组内存储的日志个数。
另请阅读
《参考》中“数据库运行参数说明 > GUC参数说明 > DCF参数设置”章节。


