etcd读写以及数据一致性原理分析

1 读流程

架构:

流程1:etcd客户端发起一个get请求,这个 请求底层是基于gRPC完成的

流程2:然后etcd服务端通过gRPC接收请求, 在gRPC中会注册多个过滤器,不过最终会调 用到KVServer中的接口

流程3:KVServer接收到请求后会调Raft模块, 去拿集群中最新的版本号

流程4:拿到版本号之后,KVServer继续调用 MVCC模块,根据key和版本号去拿treeIndex中的一个版本,根据上面那个版本去boltdb拿真实的value

1.1 客户端

也就是流程1,具体步骤:

  1. etcdctl启动客户端(实际就是Go语言底层执行main方法)
  2. 启动过程中拿底层操作系统的cmd指令,并根据不同的参数封装各种命令,然后通过传进来的参数选择执行不同的命令
  3. 在客户端进行负载均衡,etcd默认的是round-robin算法
  4. 最终etcd客户端创建gRPC客户端,调etcd服务端的KVServer模块

源码流程:

1.2 服务端

前置:启动etcdserver端

流程2:KVServer接收get请求

流程3:等待数据同步

流程4:去数据库里面拿数据

1.2.1 前置

  1. 启动server/main.go中的main方法
  2. 创建一个Etcd的实例,里面有个etcdserver
  3. 创建一个etcdserver对象然后赋值给上面
  4. 创建了各种异步协程、通道、注册各种模块 (KVServer、拦截器)到gRPC
  5. 启动

1.2.2 流程

  1. Etcdserver接收get请求,被拦截器给拦截
  2. 执行Key.go中Range,判断是否是线性读(默认线性读)
  3. 跟Leader进行通信,判断ReadIndex是不是最新的
  4. 不是的话就等着Raft那个携程进行数据同步
  5. 拿到最新的ReadIndex,然后根据key去数据库拿数据

2 写流程

写只能Leader处理,Follower只能读

⚫ 如何保证数据不丢失——集群来保证

⚫ 写命令如何不重复执行——幂等性来保证

架构:

流程1:etcd客户端发起一个put请求

流程2:etcd服务端中的拦截器接收请求,先做配额限制

流程3:如果没有没有超过配额,进入KV模块

流程4:走Raft模块保证各节点的数据一致

流程5:各节点将Raft日志进行持久化,防止节点在数据存到 boltdb之前挂掉导致数据丢失

流程6:将要持久化到boltdb的数据发送给Apply

流程7:数据基于MVCC进行持久化

2.1 客户端

与读流程差不多,不重复讲述

2.2 服务端

2.2.1 Quota(配额)模块

就是etcd boltdb中能存的最大字节,默认是2GB, 如果超过配额会报NO SPACE告警,调大配额,还需要执行etcdctl alarm disarm取消告警。⚫ 修改配额:启动服务端的时候加参数:–quota-backendbytes=20(20表示字节)

2.2.2 KV模块

2.2.3 整体源码

3 数据一致性—强一致性

Raft协议:http://thesecretlivesofdata.com/raft/

➢ Leader,集群领导者, 唯一性,拥有同步日志的特权,需定时广播心跳给 Follower节点,以维持领导者身份

➢ Candidate,竞选者,可以发起Leader选举

➢ Follower,跟随者, 同步从Leader收到的日志,etcd启动的时候默认为此状态

数据同步过程:

安全性:

➢ 选举规则

⚫ 检查候选者的最后一条日志中的任期号,若小于自己则拒绝投票。如果任期号相同,日志却比自己短,也拒绝为其投票。

⚫ 每个节点在同一个任期内只能为一个节点投票

➢ 日志复制规则

⚫ Leader完全特性:如果某个日志条目在某个任期号中已经被提交,那么这个条目必然出现在更大 任期号的所有Leader中

⚫ 只附加原则:Leader只能追加日志条目,不能删除已持久化的日志条目

⚫ 日志匹配原则:Leader在发送追加日志RPC消息时,会把新的日志条目紧接着之前的条目的索引 位置和任期号包含在里面。Follower节点会检查相同索引位置的任期号是否与Leader一致,一致 才能追加

4 总结

➢ Etcd客户端读写流程

⚫ 解析参数并选择命令 ⚫ 进行负载均衡重试等操作 ⚫ 发起gRPC请求

➢ Etcd服务端读流程

⚫ 前置开启服务以及各种携程,并注册拦截器,最终调KVServer模块 ⚫ 发起线性读保证安全

➢ Etcd服务端写流程

⚫ 前置开启服务以及各种携程,并注册拦截器,调Quota进行配额限制、然后调KVServer进行限流、 校验、限制大小等操作 ⚫ 走Raft模块,保证各节点数据同步 ⚫ 收到各节点同步日志成功通知则走Apply模块,进行幂等性判断 ⚫ 走MVCC模块保存不同版本的KV


etcd读写以及数据一致性原理分析
http://www.zivjie.cn/2023/04/15/云原生(容器化)/etcd/etcd读写以及数据一致性原理分析/
作者
Francis
发布于
2023年4月15日
许可协议