Closed ghost closed 5 years ago
你的问题涉及到snapshot的两个点,我分别一一回答 第一个问题是关于什么时候做snapshot。我们没有使用raft自带的定时snapshot功能,主要考虑点是每个reigion的活跃程度不同,有些region可能很长时间才会积累几条log_entry, 频繁的做snapshot会导致系统重启之后(比如重启时间超过snapshot的时间)要通过大量的install-snapshot来恢复数据。所以我们使用了一系列的规则来判断是否需要做snapshot。也就是你贴的代码的第二段,这一段代码是与第一段代码结合的;另外,我们做的snapshot是不保存数据的,你可以看一下on_snapshot_save的代码。做snapshot的主要目的是于raft库结合,将raft的log_entry删掉。 第二个问题是实时snapshot的问题。这个实时snapshot的概念是你理解每次ins
第二个问题是实时snapshot的问题。这个实时的概念是你看到的每次install snapshot,node从leader获取快照时却是使用rocksdb接口get_snapshot,直接使用当前的快照。重复的数据通过 if (iter.index() <= _applied_index) { continue; } 过滤掉
那就是说 节点所installed snaoshot 其实并不是leader on_snapshot_save时所保存的snaoshot, 而是比leader on_snapshot_save 的快照新咯?
对
其实我主要是想问,为啥不使用 leader on_snapshot_save 时的 rocksdb::get_snapshot?
如果在on_snapshot_save时候调用get_snapshot, 就需要将这个snapshot保存在内存中,同时rocksdb也不能删除这部分的数据(如果后续数据有变动的话)。现在我们线上多则有上万个region, 要保存上万份snapshot,对性能和磁盘空间都会有影响。目前我们用的方式只是需要的时候创建snapshot,大部分时间都是不需要的。
需要发送raft的snapshot的概率很小,没必要保存rocksdb的snapshot。用实时的既能拿到最新的也不需要rocksdb内部维护n个版本,raft回放的logentry也很少或者没有(被continue掉了)
在BaikalDB里面,每个Region的没有使用braft自带了定时快照功能,而是使用单独一个线程,同一个时刻只允许指定个数的Region做快照。 https://github.com/baidu/BaikalDB/blob/90a7ef6f8484271c52ad8d595a181116c8f11884/src/store/store.cpp#L626-L639 也就是说,其实快照不是实时的, 我记得一个文档里面好像说是实时的。
在Region里面也不是说做快照就做快照的, 也是通过时间和log条数相差到达一定时才让做。 https://github.com/baidu/BaikalDB/blob/90a7ef6f8484271c52ad8d595a181116c8f11884/src/store/region.cpp#L1779-L1805
那为啥在install snapshot,node从leader获取快照时却是使用rocksdb接口get_snapshot,直接使用当前的快照?每个SnapshotContext 是install snapshot时才构造出来的。 https://github.com/baidu/BaikalDB/blob/90a7ef6f8484271c52ad8d595a181116c8f11884/include/raft/rocksdb_file_system_adaptor.h#L44-L61
是不是因为在on_apply中保存了_applied_index, 重复的数据可以通过 if (iter.index() <= _applied_index) { continue; } 过滤掉呢? https://github.com/baidu/BaikalDB/blob/90a7ef6f8484271c52ad8d595a181116c8f11884/src/store/region.cpp#L1336-L1362
这样是可以过滤掉, 但节点所installed snaoshot 其实并不是leader on_snapshot_save时所保存的snaoshot 了。