raft论文提到一旦日志被commit,那么大部分节点都会拥有这条日志,但问题是大部分节点只有当leader做了commit之后,才会commit到自己的状态机吧。假若leader在commit完一条日志后马上挂了,那其他节点肯定不知道这条日志已经被commit,那后续新的leader也不会把这条日志放进commited log中去。请问这样日志的一致性是怎么保证的? raft不是不能改写已经被commit的日志吗?
raft论文提到一旦日志被commit,那么大部分节点都会拥有这条日志,但问题是大部分节点只有当leader做了commit之后,才会commit到自己的状态机吧。假若leader在commit完一条日志后马上挂了,那其他节点肯定不知道这条日志已经被commit,那后续新的leader也不会把这条日志放进commited log中去。请问这样日志的一致性是怎么保证的? raft不是不能改写已经被commit的日志吗?
1、首先给你一个网址:http://thesecretlivesofdata.c...,能够更加生动的看到Log Replication的过程。
2、Commit的定义是当集群中大部分的节点(一半以上)响应了Leader的Log Replication操作之后才会被Commited。否则,Leader是不会像Client发送提交成功的响应的。提交操作并未真正Commit,Leader会被阻塞在这里。
3、这种情况的发生一般来说都是因为Leader挂掉了或者网络分区了。Leader挂掉了的话在一个HeartBeat Timeout后系统会Re-select,新的Leader会更新自己的term-id,这时候Client一般是会重试的,也就是会向新的Leader提交成功。
4、当Leader恢复或者分区消失,恢复后的Leader发现集群存在更新的term-id,它会放弃leader地位并主动向新的leader进行同步,从而整个集群恢复到一致状态。
最大的问题还是客户端如果宕机,没来得及重试,可能导致数据提交成功,但是客户端不感知,这就要想办法在客户端持久化序列号id,保证宕机重启后仍能提交。
挂了的话,等恢复就好了。自动复制的时候,就能发现自己的index不是最新的对不上,进行恢复