Etcd V2与V3存储差异
在Etcd v2与v3两个版本中,使用的存储方式完全不同,所以两个版本的数据并不兼容,对外提供的接口也是不一样的,不同版本的数据是相互隔离的,只能使用对应的版本去存储与获取。
V2——基于内存的存储
- 在v2版本中,数据是以树形结构完全存储在内存中的,只有进行持久化的时候才会将数据以JSON格式存储进磁盘。
v2的watch机制
-
在v2版本中,存在着一个EventHistory表,EventHistory表是有长度限制的,默认是1000.
-
v2中存在一个全局的版本currentIndex,有数据更新时currentIndex++
-
在客户端watch的时候,如携带waitIndex(小于currentindex),那么会从EventHistory表中查询出从waitIndex开始并且与watch key匹配的event返回。
-
v2版本的watch机制并不可靠,当客户端断连,如果此时event的条数超过eventHistory表的最大长度时候,当客户端重连的时候可能会出现event的丢失(v3版本解决了这个问题,但是如果进行了压缩也是会清理掉之前的版本)
-
eventQueue是一个先进先出的环形队列,当eventQueue填满后继续添加会导致最先添加的Event示例被覆盖
-
watcher只能监听某一个key及其子节点
v2的node
-
CreatedIndex:记录了当前节点创建的currentIndex值
-
ModifiedIndex:记录了当前节点最后一次更新的currentIndex值
-
store:指向当前节点关联的v2版本实例
- v2版本中,节点的过期时间是存储在node的ExpireTime,v3的过期是通过租约lease来实现的
V3
store
-
在v3中,store的实现分为两部分
- backend store:可以使用不同的存储,默认使用BoltDB(单机的支持事务的键值对存储)
- 内存索引,基于github.com/google/btree的b树索引实现
-
etcd在BoltDB中存储的key是revision,value是etcd自定义的键值对组合,etcd会将键值对的每个版本都保存到BoltDB中,所以etcd能实现多版本的机制
-
每次查询键值对需要通过revision来查找,所以会在内存中维护一份B树索引,关联了一个keyIndex实例用来映射key与revision,并维护了多个版本的revision,客户端只会根据key去获取数据而不是revision
-
由revision的结构可以看出reversion有main reversion和sub reversion组成,每次事务的话main reversion递增,同个事务中每次操作(put等)则是sub reversion递增
-
主要流程:先扫描存储B树索引得到对应的revision,然后查询BoltDB得到真正的键值对数据,反序列化为KeyValue并封装成RangeResult返回
-
v3版本的存储废弃了树形的存储结构但是可以通过前缀的方式来模拟
多个version的区别
revision有main revision和sub revision组成,每次事务的话main revision递增,同个事务中每次操作(put等)则是sub revision递增
Kv中的:
CreateRevision:最近一次创建当前键值对的revision
ModRevision:最近一次修改当前键值对的revision
Version:当前键值对的版本,每次修改递增,删除则置为0