数据模型

etcd 数据存储方法

etcd 被设计用于可靠地存储不频繁更新的数据,并提供可靠的监听查询。etcd 公开键值对的先前版本,以支持低成本的快照和监听历史事件(“时间旅行查询”)。持久化的多版本并发控制数据模型非常适合这些用例。

etcd 将数据存储在一个多版本的持久化键值存储中。当键值对的值被新数据取代时,该持久化键值存储会保留其先前版本。键值存储实际上是不可变的;其操作不会就地更新结构,而是始终生成一个新的更新后的结构。在修改后,所有旧版本的键仍然可访问且可监听。为了防止数据存储随时间无限增长并避免保留过多旧版本,可以对存储进行压缩,以清除最老的被覆盖数据版本。

逻辑视图

存储的逻辑视图是一个扁平的二进制键空间。键空间在字节字符串键上具有按字典序排序的索引,因此范围查询成本较低。

键空间维护多个修订版本(revisions)。当存储创建时,初始修订版本为 1。每次原子性变更操作(例如,一个事务操作可能包含多个操作)都会在键空间上创建一个新的修订版本。所有由先前修订版本持有的数据保持不变。旧版本的键仍可通过之前的修订版本访问。同样,修订版本本身也有索引;对修订版本进行监听时的范围遍历效率很高。如果为了节省空间而对存储进行了压缩,则早于压缩修订版本的修订版本将被删除。在整个集群生命周期内,修订版本单调递增。

一个键的生命周期跨越一代,从创建到删除。每个键可能有一个或多个世代。创建一个键会使其版本(version)递增,若该键在当前修订版本中尚不存在,则从 1 开始计数。删除一个键会产生一个键墓碑(tombstone),通过将其版本重置为 0 来结束该键当前的世代。每次对键的修改都会使其版本递增;因此,在一个键的单个世代内,版本是单调递增的。一旦发生压缩,所有在压缩修订版本之前已结束的世代都将被移除,且在压缩修订版本之前设置的所有值(除了最新的那个)也将被清除。

物理视图

etcd 将物理数据作为键值对存储在一个持久化的B+树中。存储状态的每个修订版本仅包含相对于前一修订版本的增量,以提高效率。单个修订版本可能对应树中的多个键。

键值对的键是一个三元组 (major, sub, type)。major 表示持有该键的存储修订版本。sub 用于区分同一修订版本内的不同键。type 是一个可选后缀,用于表示特殊值(例如,如果值包含墓碑,则使用 t)。键值对的值包含从前一个修订版本开始的修改内容,即一个增量。B+树按键的字典序字节顺序排列。对修订版本增量进行范围查找非常快速;这使得能够快速找到从某个特定修订版本到另一个修订版本之间的所有修改。压缩操作会移除过期的键值对。

etcd 还维护一个辅助的内存中B 树索引,以加速对键的范围查询。B 树索引中的键是暴露给用户的存储键。其值是指向持久化 B+树中修改项的指针。压缩操作会清除无效的指针。

总体而言,etcd 从 B 树 获取修订版本信息,然后使用该修订版本作为键,从 B+树 中获取对应的值(如下图所示)。

mvcc data model


最后更新于 2025 年 6 月 3 日:递归地将 v3.6 的内容复制到 v3.7(a90b2a6)