Etcd 读请求如何执行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Etcd 读请求如何执行相关的知识,希望对你有一定的参考价值。

参考技术A etcd是典型的读多写少存储。

在etcd v3.4.9版本中,etcdctl是通过clientv3库中访问ectd server的, client v3库基于gRPC client API封装了操作etcd KVServer、Cluster、
Auth、Lease、Watch等模块的API,同时包含了负载均衡、健康探测和故障切换等特性。

负载均衡算法:

etcd通过拦截器提供了丰富的metrics、日志、请求行为检查等机制,可记录所有请求的执行耗时及错误码、来源IP等,也可控制请求是否允许通过。

etcd 实现了一些特性:

串行读过程:
client发送请求到etcd server-->Leader 节点收到请求之后,持久化到WAL日志-->广播给各个节点,等到一半以上节点上持久化成功-->将请求标记为已提交
-->ectd server 模块异步从Raft模块获取已提交的日志条目,应用到状态机。

线性读是通过ReadIndex机制保证数据一致性原理。

线性读过程:
KVServer模块收到线性读请求后,向Raft模块发起ReadIndex请求,Raft模块将Leader最新的已提交日志索引封装在ReadState结构块,通过channel
层层返回给线性读模块,线性读模块等待本节点状态机追赶上Leader进度,追赶完成后,通知KVServer模块,与状态机中的MVCC模块进行交互。

串行读具有低延时、高吞吐量的特点,适合对数据一致性要求不高的场景。

线性读解决读数据一致性要求高的场景。

MVCC的核心由内存树形索引模块和嵌入式的KV持久化存储库boltdb组成。

boltdb是基于B+ tree实现的k-v键值库,支持事物,提供GET/PUT等简易API给etcd操作。

etcd如何基于boltdb保存一个key的多个版本:

treeIndex是基于btree实现的。treeIndex模块只会保存用户的key和用户版本号信息,用户的key的value数据存储在boltdb里面。

从treeIndex模块中获取hello这个key对应的版本号信息,treeIndex模块基于B-tree快速查找此key, 返回此key对应的索引项keyIndex即可。

获取版本号之后,可以从boltdb模块中获取用户的key-value数据了。在访问boltdb前,首先会从一个内存读事物buffer中,
二分查找要访问key是否存在,如果命中则直接返回。

boltdb是使用bucket隔离集群元数据和用户数据,bucket就是mysql的一个表,用户的key数据存放真的bucket名字的是key,
etcd MVCC元数据存放的bucket是meta。

Getting Started with Kubernetes | etcd

ETCD 的组件架构和内部通信

文章目录

ETCD 常用术语

术语描述备注
Raftetcd实现一致性的核心etcd有etcd-raft模块
FollowerRaft中的从属节点竞争leader失败
LeaderRaft中的领导协调节点Leader 节点协调整个集群
Candidate候选节点当Follower接受Leader节点的消息超时会转变为Candidate
NodeRaft 状态机的实例Raft 中涉及多个节点
Memberetcd实例,管理着对应的Node节点可处理客户端请求
Peer同一集群中的另一个Member其他成员
Clusteretcd集群拥有多个etcd Member
Lease租期关键设置的租期,过期删除
Watch检测机制监控键值对的变化
Term任期某个节点成为Leader,到下一次竞选的时间
WAL预写式日志用户持久化存储的日志格式
Client客户端向etcd发起请求的客户端

ETCD 核心架构

  • etcd 是云原生架构中的存储基石,可以有效保证数据的一致性和可靠性。
  • etcd 内存实现机制复杂,但是对外提供了简单直接的api接口
  • 使用etcd的常见分布式场景包括键值对的存储服务注册与发现消息订阅与发布分布式锁等等

ETCD 网关和gRPC-gateway

ETCD网关:构建etcd集群的门户

  • etcd网关是一个简单的TCP代理,可将网络数据转发到etcd集群中
  • 网关是无状态且透明的,它既不会检查客户端请求,也不会干扰集群响应,支持多个etcd服务实例,并采用简单的循环策略。

如果同一服务器上的多应用程序访问的etcd集群,每个应用程序仍然需要知道etcd集群的广播客户端断点地址。
发生etcd集群实例的变更时,只需要网关更新其端点。

总而言之:为了自动传播集群端点更改,etcd网关在每台机器上都运行,为多个应用提供访问相同的etcd集群服务。

gRPC-Gateway:为非gRPC的客户端提供HTTP接口

HTTP的方式访问etcd服务端,需要考虑安全的问题,gRPC-Gateway中提供的API接口支持开启安全认证。
有的语言客户端不支持gRPC通信协议,此时就可以使用gRPC-Gateway对外提供HTTP API接口
,通过HTTP请求,实现与gRPC调用协议同样的功能。

gRPC-proxy

可伸缩的watch API

如果客户端监视同一键或某一范围内的键,gRPC代理可以将这些客户端程序(c-watcher)合并为链接到etcd服务器的单个监视程序(s-watcher)

当watch事件发生时,代理将所有事件(s-watcher)广播到其(c-watcher)

为了有效地将多个客户端监视程序合并为一个监视程序,gRPC代理在可能的情况下将新的c-watcher合并为现有地s-watcher。也有负载均衡的效果。

另外如果没有指定监视版本,gRPC代理将不能保证c-watcher从最近的存储修订版本开始监视。

可伸缩的lease API

如果etcd工作负载涉及很多的客户端租约活动,这些流可能会导致CPU使用率过高,为了减少核心集群上的流总数,gRPC代理支持将lease流合并。

可以缓存请求的响应,这个功能可以保护etcd服务器免遭恶意for循环中滥用客户端的攻击。

空间命名

当应用程序期望对整个空间有完全控制,etcd集群与其他应用程序共享的情况下,为了使所有应用程序都不会相互地干扰地运行,代理可以对etcd键空间进行分区,以便客户端大概率访问完整的键空间。

ETCD 组件架构

包名用途
auth访问权限
client/clientv3Go语言客户端SDK
embed主要是etcd的config
etcdmain入口程序
etcdctl命令行客户端实现
etcdserverserver主要的包
functional/hackCMD、Dockerfile 之类的杂项
integration和etcd集群相关
lease租约相关
mvccetcd的底层存储,包含Watch实现
pkg、proxyetcd使用的工具集合
raftraft算法模块
wal日志模块
scripts/security/tests/tools/version脚本、测试等相关内容

  • client 层:etcd 的客户端
  • API 接口层:提供了客户端访问服务端的通信协议和接口定义以及服务端节点之间相互通信的协议,通过gRPC-gateway提供REST ful 代理,转换HTTP/JSON请求为gRPC的Protocol Buffer格式的消息。
  • etcd Raft层:负责Leader选举和日志复制等功能。
  • 逻辑层:包括鉴权,租约,KVserver,MVCC和Compactor压缩等核心功能特点。
  • etcd存储:实现了快照,预写式日志WAL(Write Ahead Log)

ETCD的交互总览

  • etcd Server:接收客户端的请求,在上述的etcd项目代码中对应etcd server包。etcd server中的raft模块,用于与etcd-raft库进行通信。
  • etcd Raft :etcd的raft库,raft库更重要的式负责与集群中的其他etcd server进行交互,实现分布式一致性。

首先写数据到etcd节点中,然后当前的etcd节点与集群中的其他etcd节点之间进行通信,确认存储数据成功之后回复客户端。

在raft协议中写入数据的etcd必定式leader节点,如果客户端提交数据到非leader节点时,该节点需要将请求转发到etcd leader节点处理

etcd的gRPC通信接口

Client定义

type Client struct
	Cluster  // 向集群里增加etcd服务端节点之类,属于管理员操作
	KV // 我们主要使用的功能,即操作K-V
	Lease // 租约相关操作,比如申请一个TTL=10s的租约
	Auth // 管理ETCD的用户和权限 属于管理员操作
	Watcher // 观察订阅,从而监听最新的数据变化
	Maintenance // 维护etcd,比如主动迁移etcd的leader节点,管理员操作
	UserName string // 认证的用户名
	Password string // 认证的密码

etcd的核心API

  • KV Service :创建、更新获取和删除键值对
  • Watch Service :监视键的更改
  • Lease Service : 实现键值对过期客户端用来续租保持心跳
  • Lock Service : etcd提供分布式共享锁支持
  • Election Service :暴露客户端选举机制

读写过程概述

读请求

客户端通过负载均衡选择一个etcd节点,发出读请求,API接口层提供Range RPC方法,etcd服务端拦截gRPC 读取请求后调用相应的处理器处理请求。

  1. etcdctl会创建一个clientv3库对象,选取一个合适的etcd节点
  2. 调用KV Server模块的Range RPC方法,发送请求
  3. 拦截器拦截,主要做一些校验和监控
  4. 调用KV Server模块的Range接口获取数据

线性读:线性读是相对串行读来讲的概念,集群模式下会有多个etcd节点,不同节点可能存在一致性问题,串行读直接返回状态数据,不需要与集群中其他节点交互,这种方式速度快,开销小,但是会存在数据不一致的情况。 线性读需要集群成员之间达成共识,存在开销,响应速度相对满,但是能保证数据的一致性. etcd默认读模式是线性读。

etcd中的查询请求,查询单个键或一组键以及查询数量,到底层实际会调用Range keys方法。

  1. 在treeIndex中根据BTree快速查询该键对应索引项keyIndex,索引项中包含Revision
  2. 据查询到的版本号信息Revision,在Backend的缓存Buffer中用二分查找,如命中则直接返回
  3. 若缓存中不符合条件,在BlotDB中查找(基于BlotDB的索引),查询后返回键值对信息

写请求

客户端通过负载均衡选择一个etcd节点发起写请求etcd服务器拦截gRPC写请求,涉及校验和监控后,KV Server 向 raft模块发提案,内容为写入数据命令,经网络转发,当集群中多数节点达成一致,持久化数据后,状态变成MVCC模块执行提案内容。

  1. 客户端通过负载均衡算法选择一个etcd节点,发起gRPC调用
  2. etcd server收到客户端请求
  3. 经过gRPC拦截,Quota校验,Quota模块用于校验etcd db文件大小是否超过配额。
  4. KV Server模块将请求发送给本模块中的raft,负责与etcd raft模块进行通信发起一个提案,命令为put,foo,bar,即使用put方法将foo更新为bar
  5. 提案经过转发之后,半数节点成功持久化
  6. MVCC模块更新状态机

以上是关于Etcd 读请求如何执行的主要内容,如果未能解决你的问题,请参考以下文章

Kubernetes之核心组件ETCD介绍

K8s之Etcd

基于 etcd 的 watch

ETCD:系统限制

ETCD:gRPC代理

Oracle是如何工作的?实例是如何响应用户请求?一条SQL的执行过程~