使用etcdctl put命令多次对同一key进行设置,然后通过get命令可以直接获取到key当前最新的value值,通过--rev选项可以获取key的历史value值。
但是你知道etcd是如何实现key的历史value值的么?--rev选项的含义又是什么?
revision值
可以认为这是一个etcd的全局数值,每次发生任何的数据变动,这个数值都会递增加一
数据如何存储
首先etcd使用bbolt进行底层数据存储,这是一个使用b树进行存储,可以实现轻量事务与事务隔离的数据库。具体实现上,将要存储的key与value拼接,组成一个byte数组,进行实际存储。如果仅仅是将要存储key value进行这样的拼接进行存储,那又要如何实现多版本并存呢?
答案就是实际存储并不是直接存储的key+value。而是以revision的值作为key,key+value+其它信息使用protobuf进行序列化之后的二进制串作为value进行存储
新的问题
但是做了这样的改动后,我们就没办法直接使用key进行数据查询了,etcd又是怎么解决的呢?
原来etcd在启动时,会对全库进行预加载,将所有的key value都读取检索一次。在内存中将会记录下,各个key对应的诸多revision信息。key作为golang map的key,value则是key对应的诸多revison信息。当用户进行查询时。通过key查找revision信息,然后再通过bbolt(数据存储引擎)进行实际的数据查询操作
其它
实际的revision信息其实比上面描述的要复杂一些,牵扯到并发控制。描述有做简略,以降低理解成本
etcd运行的其它细节也有诸多简略,如果有疑问可以提出,我会尝试解答
但是实际这个东西,如果你真会有诸多疑问,最好的方式还是看源码