Etcd 解析

概要

Etcd是一个分布式的,一致的 key-value 存储,主要用途是共享配置和服务发现。

主要提供以下能力

  • 提供存储以及获取数据的接口,它通过协议保证 Etcd 集群中的多个节点数据的强一致性。用于存储元信息以及共享配置。
  • 提供监听机制,客户端可以监听某个key或者某些key的变更(v2和v3的机制不同,参看后面文章)。用于监听和推送变更。
  • 提供key的过期以及续约机制,客户端通过定时刷新来实现续约(v2和v3的实现机制也不一样)。用于集群监控以及服务注册发现。
  • 提供原子的CAS(Compare-and-Swap)和 CAD(Compare-and-Delete)支持(v2通过接口参数实现,v3通过批量事务实现)。用于分布式锁以及leader选举。

一致性

通过Raft协议提供一致性

数据存储

etcd的存储分为内存存储和持久化(硬盘)存储两部分

  • 内存中的存储除了顺序化的记录下所有用户对节点数据变更的记录外,还会对用户数据进行索引、建堆等方便查询的操作。
  • 持久化则使用预写式日志(WAL:Write Ahead Log)进行记录存储。

在WAL的体系中,所有的数据在提交之前都会进行日志记录。

在etcd的持久化存储目录中,有两个子目录。

  • WAL,存储着所有事务的变化记录;
  • snapshot,用于存储某一个时刻etcd所有目录的数据。

通过WAL和snapshot相结合的方式,etcd可以有效的进行数据存储和节点故障恢复等操作。

etcd默认每10000条记录做一次snapshot,经过snapshot以后的WAL文件就可以删除

首次启动时,etcd会把启动的配置信息存储到data-dir参数指定的数据目录中。

配置信息包括本地节点的ID、集群ID和初始时集群信息。

用户需要避免etcd从一个过期的数据目录中重新启动,因为使用过期的数据目录启动的节点会与集群中的其他节点产生不一致

WAL

WAL(Write Ahead Log)预写式日志, 最大的作用是记录了整个数据变化的全部历程

在etcd中,所有数据的修改在提交前,都要先写入到WAL中。

使用WAL进行数据的存储使得etcd拥有两个重要功能。

  • 故障快速恢复: 当你的数据遭到破坏时,就可以通过执行所有WAL中记录的修改操作,快速从最原始的数据恢复到数据损坏前的状态。
  • 数据回滚(undo)/重做(redo):因为所有的修改操作都被记录在WAL中,需要回滚或重做,只需要方向或正向执行日志中的操作即可。

WAL与snapshot在etcd中的命名规则

在etcd的数据目录中,WAL文件以$seq-$index.wal的格式存储。

最初始的WAL文件是0000000000000000-0000000000000000.wal,表示是所有WAL文件中的第0个,初始的Raft状态编号为0。

运行一段时间后可能需要进行日志切分,把新的条目放到一个新的WAL文件中。

假设,当集群运行到Raft状态为20时,需要进行WAL文件的切分时,下一份WAL文件就会变为0000000000000001-0000000000000021.wal。

如果在10次操作后又进行了一次日志切分,那么后一次的WAL文件名会变为0000000000000002-0000000000000031.wal。

可以看到-符号前面的数字是每次切分后自增1,而-符号后面的数字则是根据实际存储的Raft起始状态来定。

snapshot的存储命名则比较容易理解,以$term-$index.wal格式进行命名存储。

term和index就表示存储snapshot时数据所在的raft节点状态,当前的任期编号以及数据项位置信息。

WAL结构

Etcd 解析

wal日志是二进制的,解析出来后是以上数据结构LogEntry。其中第一个字段type,只有两种,一种是0表示Normal,1表示ConfChange(ConfChange表示 Etcd 本身的配置变更同步,比如有新的节点加入等)。第二个字段是term,每个term代表一个主节点的任期,每次主节点变更term就会变化。第三个字段是index,这个序号是严格有序递增的,代表变更序号。第四个字段是二进制的data,将raft request对象的pb结构整个保存下。Etcd 源码下有个tools/etcd-dump-logs,可以将wal日志dump成文本查看,可以协助分析raft协议。

猜你喜欢

转载自blog.51cto.com/11346335/2140818