筏子:关于只读查询的一些问题

时间:2016-05-13 10:31:09

标签: raft

在筏的论文文档第6.4章中,它提供了绕过Raft日志进行只读查询并仍保持线性化的步骤:

  
      
  1. 如果领导者尚未在其当前提交的条款中标记一个条目,则它会一直等到它已经完成。领导者的完整性   财产保证领导者拥有所有承诺的条目,但是在   它的任期开始,可能不知道它们是哪一个。要找出来,   它需要从其术语提交一个条目。筏子处理这个   每个领导者在开始时将空白的无操作条目提交到日志中   它的用语。一旦这个无操作的条目被提交,领导者就会   commit index至少与其他服务器一样大   它的用语。
  2.   
  3. 领导者将其当前的提交索引保存在局部变量readIndex中。这将用作版本的下限   声明查询操作。
  4.   
  5. 领导者需要确保它没有被一个不知道的新领导者所取代。它发布了新一轮的心跳和   等待群集的大多数人的确认。一旦   收到这些致谢,领导者知道可以   在它发送的那一刻,并没有一个更长远的领导者   心跳。因此,readIndex当时是最大的提交   集群中的任何服务器都可以看到索引。
  6.   
  7. 领导者等待其状态机至少前进到readIndex;这足以满足线性化。
  8.   
  9. 最后,领导者针对其状态机发出查询,并使用结果回复客户端。
  10.   

我的问题:

a)对于第1步,是否只是在领导者刚刚当选的情况下?因为只有新领导者没有承诺当前任期。并且由于无操作条目是查找当前已提交条目所必需的,因此在完成选举时总是需要此步骤,但不仅仅是特定于只读查询?换句话说,通常情况下,当领导者活跃一段时间时,它必须具有为其术语提交的条目(包括无操作条目)。

b)对于第3步,它是否意味着只要领导者需要提供只读查询,那么将发送一个额外的心跳,无论当前未完成的心跳(已发送但尚未收到主要响应)或下一次预定的心跳?

c)对于第4步,它是否仅适用于粉丝(对于追随者帮助卸载只读查询处理的情况)?因为在leader上,已提交索引已经意味着它已应用于本地状态机。

总而言之,通常情况下,领导者(活跃一段时间)只需要做第3步和第5步,对吗?

1 个答案:

答案 0 :(得分:3)

a :这确实只是领导者首次当选的情况。实际上,当收到只读查询时,您检查是否已从领导者的当前术语和队列中提交了条目,或者如果没有,则检查是否拒绝该查询。

b :在实践中,大多数实现批量只读查询以提高效率。您不需要发送许多并发心跳。如果心跳未完成,则领导者可以在心跳完成后将任何新读取入队。一旦心跳完成,如果任何其他查询被排队,则领导者开始另一次心跳。这具有批量线性化只读查询的效果,以提高效率。

c :领导者的lastApplied索引(其状态机的索引)始终与其{相等 {1}}。实际上,这就是为什么首先在Raft中 <{1}}索引的原因。领导者不一定必须在提交索引的同时同步应用索引。这实际上是特定于实现的。实际上,Raft实现通常在不同的线程中应用条目。因此,可以提交一个条目,然后将其排入队列以应用于状态机。某些实现将条目放在队列中以应用于状态机,并允许状态机从该队列中拉出条目以在状态机自己的速度下应用,因此当条目时可能适用的是未指定的。在领导者提交的最后一个命令之后应用只读查询至关重要。

另外,你问这是否只适用于粉丝。可线性化查询只能通过领导者进行评估。我想有一些算法可以对追随者进行线性化读取,但效率很低。关注者只能维护查询的顺序一致性。在这种情况下,服务器在评估操作时使用状态机的索引响应客户端操作。客户端在每次操作时发送最后一次收到的索引,当服务器收到操作时,它使用相同的算法确保其状态机的commitIndex索引至少与客户端一样好[&#39}。索引。这是确保客户端在切换服务器时看不到状态的必要条件。

如果您希望支持来自单个客户端的并发操作的FIFO一致性,那么除了Raft文献中描述的内容之外,还有一些其他复杂性的只读查询。其中一些在Copycat的architecture documentation中有描述。