(数据库必知必会:TiDB(5)TiKV Raft)
Raft
角色介绍
TiKV中的Region保存了3份数据,其中一份数据是主数据,称为leader,另外两份是follower。
Region中的数据是按照key进行排序的。当Region的数据增长达到96MB的时候,就会新建一个Region进行写数据。
由于Region的数据可能存在修改、删除等操作,所以Region的数据就会在96MB的基础上再变化。当增长达到144MB的时候,Region会拆分;当减小到一个较小的大小的时候,Region可以合并。
一个TiKV节点上的Region个数达到5万个的时候,管理成本就比较高了。
Raft日志复制
TiKV节点中存在两种类型的RocksDB,RocksDB kv是存储的K-V型数据,RocksDB raft存放的是数据从操作指令,即数据操作的增删改查指令,也就是Raft日志。
数据写入的时候,将数据写入日志写到leader。
leader收到写入请求后:
第1步,propose阶段,leader将写请求写入Raft日志,Raft日志的唯一标识是:Region号+日志当前的序号。
第2步,append阶段,leader将Raft日志写入到本地的RocksDB。
第3步,replicate阶段,leader将本地的Raft日志逐条发送到follower,follower在本地完成append。
第4步,commited阶段,follower在完成append的时候,会将状态反馈给leader。
第5步,apply阶段,当大多数follower都反馈append成功,leader会认为数据持久化已经稳妥了,就会执行commit,否则leader会认为数据持久化失败,不会进行commit。
Raft Leader选举
当集群刚启动的时候,所有TiKV节点都是follower,term=1,此时follower会一直等待leader的信息,直到超过election timeout(默认10秒钟)的时间都还没等到,则region会把自己变成candidate,term=2,并将这个信号发送给其他节点。其他节点收到信号后,会用term值与自己保存的term值进行比较,如果收到的term比自己的term值大,则其他节点会同意这个信号请求,并将自己的term更新成信号中的term值表示一段新关系的开始。当大多数节点都同意,则leader选举成功。
当集群中有leader的时候,leader会按一定的时间间隔heartbeat time interval(默认10秒)给folloer发送心跳,表示leader存在,follower禁止起义,follower收到心跳信息后,只能按兵不动。当集群中突然失去leader节点的时候,follower无法收到心跳信号,当超过election timeout还没收到心跳信号,则有follower就会起义,将自己变成candidate,并发送选举请求给其他节点开始进行选举。
一个问题
如果在选举leader的过程中,出现多个节点都选择自己做为candidate的,都选自己做leader,则有可能导致无法选举出新的leader。
解决办法就是不同的节点采用随机的、不同的无主选举时间election timeout,防止多个节点同时发起选举。
几个概念
- Election timeout,无主选举时间,超过这个时间还没收到leader的信息就会发起leader选举,对应参数raft-election-timeout-ticks,默认值raft-base-tick-interval
- Heartbeat time interval,心跳时间,leader发送心跳到follower的时间间隔,需要小于Election timeout,对应参数raft-heartbeat-ticks,默认值raft-base-tick-interval