Raft 算法之快照篇

Posted szprg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Raft 算法之快照篇相关的知识,希望对你有一定的参考价值。

一、什么是快照

快照(snapshot)是最简单的压缩方式。在快照中,全部的当前系统状态都被写入到快照中,存储到持久化的存储中,然后在那个时刻之前的全部日志都可以被丢弃。

 

打个比方,像Redis这样的KV系统,系统的当前状态就是当前所有key的值及过期时间,把这些信息全部写入到磁盘中就是快照。

 

二、Raft算法中为什么需要快照

Raft算法是通过日志来保证节点最终一致的,而日志是持续增加的,对于一个7*24小时运行的系统,日志会一直增加,这样导致几个问题:

 

1、磁盘占用空间过大;

2、新的节点加入进来后,需要同步的日志太多,进一步影响系统的可用性;

 

还有1点不是Raft算法中本身的功能,就是恢复数据,即一个误操作需要回滚,则需要回放从前到后所有日志,这个时间会非常长,这时如果有快照就可以快速恢复了。

 

mysql binlog、Redis的aof文件其实就相当于快照,只不过这些系统没有实现Raft算法。

 

三、与快照相关的RPC

1、安装快照 RPC(InstallSnapshot RPC)

技术图片

 

对于接收方规则如下

1.如果term < currentTerm立刻回复

2.如果是第一个分块(offset 为 0)则创建新的快照

3.在指定的偏移量写入数据

4.如果 done为 false,则回复并继续等待之后的数据

5.保存快照文件,丢弃所有存在的或者部分有着更小索引号的快照

6.如果现存的日志拥有相同的最后任期号和索引值,则后面的数据继续保留并且回复

7.丢弃全部日志

8.能够使用快照来恢复状态机(并且装载快照中的集群配置)

 

这些规则大部分应该好理解,部分规则解释下:

 

5、保存快照文件,丢弃所有存在的或者部分有着更小索引号的快照

假如说Follower已经有快照了,并且快照最后索引为1000,而新的快照的索引为2000,则将前面的快照丢弃。

 

6、如果现存的日志拥有相同的最后任期号和索引值,则后面的数据继续保留并且回复

意思说接收节点如果有相应的日志了,则后面的日志保留,此消息可以直接回复。

打个比方,如果Follower B的索引已经到2002,此索引对应的term为102,其中2000索引的term为101,如果这时收到一个安装快照的消息,最后1条的term为101,最后1条的索引为2000,通过对比发现此日志已经存在节点上,并且Term也对的上,因此2001之后的日志保留。

 

7、丢弃全部日志

上面条件满足后,将快照保存到本地,本地所有日志全部丢弃。

当然前提是前面的条件都不满足,具体不细述。

 

8、能够使用快照来恢复状态机(并且装载快照中的集群配置)

恢复状态机就不用说了,直接拿快照恢复状态机的数据,举例来说KV系统,发送的快照如果只有a=1, b=2这样的状态,即把所有数据清空,只保留上面2条数据。

 

并且装载快照中的集群配置,意思是说快照还包含集群配置信息,主是要为了支持集群成员更新;

 

所以快照必须以下信息:

最后一条日志的Index;

最后一条日志的Term;

生成快照时的集群配置信息;

状态机数据;

 

四、其它细节

1、何时生成快照

这个Raft算法并没有规定,看应用自己实现,像etcd是10000日志后产生1次快照,需要根据实际条件选择。

 

2、谁生成日志快照

Raft算法并没有规定谁可以生成,即谁都可以生成,即符合条件1就可以生成,主要是为了切换为Leader的时候可以快速应对新节点添加数据的情况。因为只有数据一致,谁生成都是一样的。

 

不了解Raft算法敢说自己研究过分布式?

Raft算法之选举篇

Raft算法之日志篇

以上是关于Raft 算法之快照篇的主要内容,如果未能解决你的问题,请参考以下文章

Raft算法之选举篇

Raft算法之集群成员变化篇

Raft算法之客户端交互篇

Raft算法之日志篇

多图详解Raft算法原理

多图:Raft算法原理非常详细的解读