在 Raft 里面,如果 Follower 落后 Leader 太多,Leader 就可能会给 Follower 直接发送 snapshot。在 TiKV,PD 也有时候会直接将一个 Raft Group 里面的一些副本调度到其他机器上面。上面这些都会涉及到 Snapshot 的处理。
在现在的实现中,一个 Snapshot 流程是这样的:
- Leader scan 一个 region 的所有数据,生成一个 snapshot file
- Leader 发送 snapshot file 给 Follower
- Follower 接受到 snapshot file,读取,并且分批次的写入到 RocksDB
如果一个节点上面同时有多个 Raft Group 的 Follower 在处理 snapshot file,RocksDB 的写入压力会非常的大,然后极易引起 RocksDB 因为 compaction 处理不过来导致的整体写入 slow 或者 stall。
幸运的是,RocksDB 提供了 SST 机制,我们可以直接生成一个 SST 的 snapshot file,然后 Follower 通过 injest 接口直接将 SST file load 进入 RocksDB。