菜单

存储引擎

相关源文件

本文档介绍了etcd的存储架构,重点关注其如何使用多版本并发控制(MVCC)和嵌入式bbolt数据库来存储和管理数据。它涵盖了存储引擎的设计原则、组织结构、数据结构以及快照和压缩等操作。

有关Raft共识实现的信息,请参阅Raft共识

存储架构概述

etcd存储引擎的设计遵循以下关键原则:

  1. 一致性优先于可用性(符合etcd的CP特性)
  2. 支持MVCC语义的版本化键值存储
  3. 由bbolt(B+树实现)支持的持久化存储
  4. 事务性操作
  5. 支持快照以进行时间点备份
  6. 支持压缩以回收空间

来源

后端存储

在最低层面,etcd使用bbolt(原名BoltDB)作为其持久化存储引擎。bbolt是一个嵌入式的、单文件的B+树数据库,提供符合ACID特性的事务。

后端结构

后端包装了bbolt数据库,并提供了附加功能,例如:

  • 事务批处理
  • 定期提交
  • 缓冲区管理
  • 用于一致性索引跟踪等操作的后端钩子

存储桶结构

bbolt将数据组织到存储桶(bucket)中,这类似于传统数据库中的表。etcd使用几个预定义的存储桶来存储不同类型的数据:

存储桶名称目的
key存储实际的键值数据
meta存储元数据,包括一致性索引
lease存储租约相关信息
members存储集群成员信息
members_removed跟踪已移除的集群成员
cluster存储集群范围的信息
alarm存储告警信息
认证存储认证数据

来源

MVCC(多版本并发控制)

MVCC层位于后端存储之上,并为键提供版本控制。这使得etcd能够提供一致的读取而不会阻塞写入,并支持时间穿越查询(读取之前版本的数据)。

版本系统

MVCC的核心是一个单调递增的版本号,作为数据库的逻辑时间戳。

  1. 每个事务(包括多个操作)都有一个版本号。
  2. 键会与其版本一起存储,允许访问历史值。
  3. 版本永不重用,确保了一致的顺序。

键编码

MVCC存储中的键被编码以维护版本控制。

  1. 用户可见的键会根据其版本进行编码。
  2. 这使得同一键的多个版本可以共存。
  3. 键查找可以针对特定版本,或默认为最新版本。

对于每个键,etcd会存储:

  • 用户键
  • 创建版本(键首次创建时)
  • 修改版本(键最后修改时)
  • 版本(该键被修改的次数)
  • 租约ID(如果键附加到租约)

来源

存储操作

读取操作

etcd中的读取操作通过MVCC层进行,该层确保了数据一致性。

  1. 可串行化读取(Serializable reads):直接从存储读取,无需查询Raft。
  2. 可线性化读取(Linearizable reads):使用ReadIndex或基于租约的读取来确保与Leader的一致性。

写入操作

写入操作更为复杂,因为它们必须经过Raft共识过程。

  1. 写入请求被提议到Raft日志。
  2. 在Raft复制条目并将其标记为已提交后,
  3. 该条目将被应用于MVCC层。
  4. 更改被批量处理,并最终持久化到bbolt。

来源

快照和压缩

快照

etcd中的快照提供数据库状态的时间点备份。

  1. 物理快照:直接复制bbolt数据库文件。
  2. 用于成员恢复、备份和新成员添加。
  3. 包含该时间点的版本和数据。

压缩

压缩是删除历史数据以回收空间的过程。

  1. 基于版本:删除所有版本号小于指定版本号的数据。
  2. 基于时间:删除时间早于指定时间段的数据。
  3. 压缩是通过--auto-compaction-retention标志配置的。

数据库碎片整理

虽然压缩会将空间标记为空闲,但它不会在文件系统层面回收该空间。碎片整理会重新组织数据库以回收这些空间。

  1. 创建新的数据库文件。
  2. 将所有有效数据复制到新文件。
  3. 用新文件替换旧文件。

来源

存储完整性和一致性

一致性索引

一致性索引是一个单调递增的数字,用于跟踪最后一个已应用的Raft索引。它有助于确保:

  1. 存储操作按正确的顺序应用。
  2. 从故障中恢复时保持一致性。
  3. 数据在集群中正确同步。

损坏检查

etcd包含一个损坏检查器,用于验证数据完整性。

  1. 哈希校验:比较成员之间的数据哈希值。
  2. 初始检查:启动服务器时验证一致性。
  3. 定期检查:定期检查数据损坏。
  4. 压缩哈希校验:压缩后验证完整性。

来源

性能考量

存储大小和增长

MVCC设计意味着数据大小会随着时间增长,除非配置了压缩。请考虑:

  1. 设置合适的压缩策略。
  2. 定期监控数据库大小。
  3. 在低峰时段规划碎片整理。

配置选项

影响存储性能的关键配置参数:

参数描述默认
--quota-backend-bytes触发告警前的最大后端大小。0 (无限制)
--auto-compaction-retention自动压缩保留期。0 (禁用)
--snapshot-count触发快照的已提交事务数量。10,000(截至v3.5.0+)
--experimental-compaction-batch-limit压缩期间要处理的最大修订版本数。1000
--experimental-compaction-sleep-interval压缩批次之间的睡眠间隔。100毫秒

后端批处理设置

后端批处理设置对写入性能有显著影响。

  1. 后端事务会进行批处理以提高效率。
  2. 更高的批处理间隔会增加吞吐量,但也会增加延迟。
  3. 默认设置在性能和持久性之间取得平衡。

来源

存储引擎初始化

在服务器启动期间,存储引擎按以下顺序初始化:

  1. 创建并配置后端(bbolt)。
  2. 如果WAL存在,则从WAL恢复。
  3. 使用后端初始化MVCC层。
  4. 设置租约、认证和其他组件。
  5. 如果启用了压缩,则进行配置和启动。

来源

与Raft的集成

存储引擎与Raft共识算法紧密协作。

  1. Raft将条目提交到WAL以实现持久性。
  2. 已提交的条目被应用到存储引擎。
  3. 创建快照以减小WAL大小并加速恢复。
  4. 一致性索引跟踪最后一个已应用的Raft索引。

来源