1、什么是快照mysql
快照(snapshot)是最简单的压缩方式。在快照中,所有的当前系统状态都被写入到快照中,存储到持久化的存储中,而后在那个时刻以前的所有日志均可以被丢弃。算法
打个比方,像Redis这样的KV系统,系统的当前状态就是当前全部key的值及过时时间,把这些信息所有写入到磁盘中就是快照。sql
2、Raft算法中为何须要快照spa
Raft算法是经过日志来保证节点最终一致的,而日志是持续增长的,对于一个7*24小时运行的系统,日志会一直增长,这样致使几个问题:日志
一、磁盘占用空间过大;blog
二、新的节点加入进来后,须要同步的日志太多,进一步影响系统的可用性;索引
还有1点不是Raft算法中自己的功能,就是恢复数据,即一个误操做须要回滚,则须要回放从前到后全部日志,这个时间会很是长,这时若是有快照就能够快速恢复了。rem
mysql binlog、Redis的aof文件其实就至关于快照,只不过这些系统没有实现Raft算法。同步
3、与快照相关的RPCit
一、安装快照 RPC(InstallSnapshot RPC)
对于接收方规则以下
若是term < currentTerm马上回复
若是是第一个分块(offset 为 0)则建立新的快照
在指定的偏移量写入数据
若是 done为 false,则回复并继续等待以后的数据
保存快照文件,丢弃全部存在的或者部分有着更小索引号的快照
若是现存的日志拥有相同的最后任期号和索引值,则后面的数据继续保留而且回复
丢弃所有日志
可以使用快照来恢复状态机(而且装载快照中的集群配置)
这些规则大部分应该好理解,部分规则解释下:
五、保存快照文件,丢弃全部存在的或者部分有着更小索引号的快照
假如说Follower已经有快照了,而且快照最后索引为1000,而新的快照的索引为2000,则将前面的快照丢弃
六、若是现存的日志拥有相同的最后任期号和索引值,则后面的数据继续保留而且回复
意思说接收节点若是有相应的日志了,则后面的日志保留,此消息能够直接回复。
打个比方,若是Follower B的索引已经到2002,此索引对应的term为102,其中2000索引的term为101,若是这时收到一个安装快照的消息,最后1条的term为101,最后1条的索引为2000,经过对比发现此日志已经存在节点上,而且Term也对的上,所以2001以后的日志保留。
七、丢弃所有日志
上面条件知足后,将快照保存到本地,本地全部日志所有丢弃。
固然前提是前面的条件都不知足,具体不细述。
八、可以使用快照来恢复状态机(而且装载快照中的集群配置)
恢复状态机就不用说了,直接拿快照恢复状态机的数据,举例来讲KV系统,发送的快照若是只有a=1, b=2这样的状态,即把全部数据清空,只保留上面2条数据。
而且装载快照中的集群配置,意思是说快照还包含集群配置信息,主是要为了支持集群成员更新;
因此快照必须如下信息:
最后一条日志的Index;
最后一条日志的Term;
生成快照时的集群配置信息;
状态机数据;
4、其它细节
一、什么时候生成快照
这个Raft算法并无规定,看应用本身实现,像etcd是10000日志后产生1次快照,须要根据实际条件选择。
二、谁生成日志快照
Raft算法并无规定谁能够生成,即谁均可以生成,即符合条件1就能够生成,主要是为了切换为Leader的时候能够快速应对新节点添加数据的状况。由于只有数据一致,谁生成都是同样的。