女主宣言
今天小编为大家分享一篇关于Golang实现Raft的文章,本篇文章为系列中的第四篇,对Raft中通过添加持久性和一些优化来完成Raft的基本实现。希望能对大家有所帮助。
PS:丰富的一线技术、多元化的表现形式,尽在“360云计算”,点关注哦!
本篇文章为Raft系列文章中的第四篇,在该部分中,我们将通过添加持久性和一些优化来完成Raft的基本实现。
1
持久化
像Raft这样的共识算法的目标是通过在隔离的服务器之间复制任务来创建一个比其各个部分具有更高可用性的系统。到目前为止,我们一直专注于网络分区的故障情况,其中群集中的某些服务器与其他服务器(或与客户端)断开连接。 失败的另一种模式是崩溃,其中服务器停止工作并重新启动。
对于其他服务器,它看起来像一个网络分区-服务器暂时断开连接,而对于崩溃的服务器本身,情况则大不相同,因为重新启动后,其所有内存状态都会丢失。
正是由于这个原因,Raft论文中的图2清楚地标记了哪个状态应该保持不变;持久状态将在每次更新时写入并刷新到持久化存储中。在服务器发出下一个RPC或答复正在进行的RPC之前,服务器必须保留的任何状态都将保留。
Raft只能通过保留其状态的子集来实现,即:
currentTerm - 此服务器观察到的最新任期
votedFor - 此服务器在最新任期为其投票的节点ID
log - Raft日志条目
2
命令传递语义
在Raft中,视不同情况,一个命令可以多次传递给客户端。有几种可能发生这种情况的场景,包括崩溃导致重新启动(再次重播日志时)。
就消息传递语义而言,Raft选择的是”至少一次”。提交命令后,它将最终复制到所有客户端,但是某些客户端可能多次看到同一命令。因此,建议命令带有唯一的IDÿ