raft 协议中, 新主存在未提交日志会怎么处理?

发布于 2022-09-11 18:37:35 字数 268 浏览 19 评论 0

因为这个时候客户端已经认为成功了, 但是实际上可能没有成功, 这样不就不一致了么?
比如如下场景, 有client, leader, follower1, follower2几个角色, 日志同步到follower1的时候, leader会认为日志已经同步成功了, 然后告知client, 但是这个时候leader挂了, follower1成为了新主, 它发现了日志还没有提交, 之后, 它不能直接认为是提交了吧, 如果是的话, follower2还没有同步日志. 如果不是的话, client端拿到的信息就有问题了.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

忆离笙 2022-09-18 18:37:35
  1. 根据领导人完备性原则,已经提交的消息一定会在下一次的Leader中出现。
    图片
  2. 假若leader在commit完一条日志后马上挂了,新leader虽然不知道这条日志已经被commit,不会立即主动提交,但是它持有这条日志,当其发现这条日志复制到大多数follower上时,会进行commit
    图片
  3. 前面两条可以保证保证已提交消息不丢,接着要保证消息不重复。客户端每次提交操作的时候会对操作有一个唯一的id,然后发现leader挂了,对新的leader重试的时候也会带上同一个操作id,然后发现新leader发现id存在,不会重复操作,而是会把之前leader的消息返回。
    图片

最大的问题还是客户端如果宕机,没来得及重试,可能导致数据提交成功,但是客户端不感知,这就要想办法在客户端持久化序列号id,保证宕机重启后仍能提交。

玻璃人 2022-09-18 18:37:35

raft提供Leader Completeness保证,即leader包含所有已经commit的log。在follower1成为新leader的情况下,follower1包含所有commit的log,此外raft还有一个隐含的保证——leader不会commit老term的log。follower1成为新leader,那么其term一定大于原来的leader,所以follower1不会去commit之前的log。又因为Log Matching保证,只要client有新的log发送给followe1,那么follower1在commit这个新的log的同时会commit之前的所有log(也就包括了最开始的leader的log)。详情可以阅读《In Search of an Understandable Consensus Algorithm (Extended Version)》 fig 3, fig 8和5.4 Safety。

↙温凉少女 2022-09-18 18:37:35

类似2PC,只是同步还没有提交断了,那么就回滚。

客户端能得到几种保证,比如一个节点存储成功就返回,或者绝大多数节点存储成功。

你这里三个节点都是未提交的,断了一般是抛出异常,让客户端重试。。。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文