etcd版本之v3

系列文章目录

浅谈分布式系统与一致性协议(一)
浅谈分布式系统与一致性协议(二)
浅谈分布式系统与一致性协议(三)
深入浅出之etcd
深入浅出之etcd(二)
etcd版本之v3
etcd之安全性阐述
etcd的多版本并发控制


概述

etcd v3存储的数据通过KV API对外暴露,并在API的层级支持mini事务。并且为了保证向后兼容,保留了etcd v2的协议与API。也就是说etcd v2和etcd v3本质上是共享一套Raft协议代码的,区别是API不同,存储不同,数据互相隔离。v2的数据只能通过v2的API访问,v3的数据只能通过v3的API访问。

etcd v2 到 etcd v3

etcd广泛应用到分布式网络,服务发现,配置中心,分布式系统调度和负载均衡领域。etcd专注于key-value存储而不是完整的数据库,通过HTTP+JSON的方式暴露给外部API,watch机制提供持续监听某个key变化的功能,基于TTL的key自动过期机制,这些特性很好的满足了etcd的初步需求。但是,也出现了一些问题,客户端需要频繁的与服务端进行通信,集群即使在空闲时间也需要承受很大的压力,垃圾回收key的时间不稳定。所以,etcd v3借鉴了etcd v2的经验,做出了如下优化:

  • 使用gRPC+protobuf取代HTTP+JSON通信,提高通信效率,另外,通过gRPC gateway来继续保持对HTTP JSON接口的支持
  • 使用lease(租约)的key自动过期机制,取代了TTL的key自动过期机制 watcher机制进行优化,基于HTTP/2的server push,并且对时间进行了多路复用优化
  • etcd v3数据模型改变,v2版本的etcd是一个简单的kv内存数据库,而etcd v3是一个支持事务和多版本并发控制的磁盘数据库。etcd v2数据不直接落盘,落盘的日志和快照文件只是数据的中间格式而非最终形式,系统通过回放日志文件来构建数据的最终形式。etcd v3落盘是数据的最终形式,日志和快照文件的主要作用是分布式的复制

gRPC

gRPC是一个高性能,跨语言的RPC框架,基于HTTP/2协议实现。使用protobuf作为序列化和反序列化协议,即基于protobuf来声明数据模型和RPC接口服务

序列化和反序列化优化

protobuf效率高,远高于JSON,etcd v3的gRPC序列化和反序列化的速度是etcd v2的两倍多

减少了TCP连接

etcd v2的通信协议使用HTTP/1.1,gRPC支持HTTP/2,HTTP/2对HTTP通信进行多路复用,可以共享一个TCP连接。因此etcd v3大大减少了客户端与服务端的连接数,一个客户端与服务端建立一个TCP连接,而etcd v2,一个客户端需要与服务端建立多个连接,每个HTTP请求都需要建立连接

租约机制

etcd v2的key自动过期是基于TTL的,客户端可以为一个key设置自动过期时间,一旦TTL到了。服务端就自动删除该key。如果客户端不想服务端删除某个key,就需要定期更新这个key的TTL。也就是说即使整个集群都处于空闲状态,也会也很多客户端需要与服务器进行定期通信,以保证某个key不会自动被删除。而且TTL都是设置在key上,那么对于客户端想保留每个key,客户端需要对每个key进行定期更新,即使这些key的过期时间都是一样的

etcd v3使用(lease)租约机制,替代了基于TTL的自动过期机制。用户创建一个lease,然后将这个租约与key关联起来。一旦租约过期,etcd v3服务端就会删除与这个租约关联的所有的key。即,多个key的过期时间是一样的,这些key可以共享一个租约。这样减少了客户端请求的数量,对于共享一个租约的key,客户端只需要更新这个租约的过期时间即可,不需要更新所有的key

etcd v3 的watch机制

watch机制使得客户端可以监控一个key的变化,当key发生变化时,服务端将通知客户端,而不是让客户端定期向服务器发送请求去轮询key的变化。etcd v2的服务端对每个客户端的每个watch请求都维持着一个HTTP长连接,如果数千个客户端watch数千个key,那么etcd v2服务端的socket和内存资源会很快消耗掉。

etcd v3对同一个客户端的watch请求进行多路复用,这样的化,同一个客户端只需要与服务端维护一个TCP连接即可,这样大大减少了服务端压力

etcd v2的每个watcher都会占用一个TCP资源和一个goroutine资源,大概消耗30~40kb。etcd v3减少每个Watcher带来的资源消耗以此支持了大规模的watch,同样的用户不同的watcher只消耗一个go routine,这样再一次减轻了服务器资源的消耗

etcd v3的数据存储模型

etcd 时一个key-value数据库,etcd v2只保存key的最新的value,之前的value直接覆盖掉了。但是etcd v2维护了一个全局的key例是记录变更窗口,默认保存最新的1000个变更,。etcd v2只保存1000个历史变更,这样带来的后果是watch丢失事件。etcd v3抛弃了这种设计,引入了MVCC(多版本并发控制),采用了历史纪录为主索引的存储结构,保存了key的所有变更记录。etcd v3可以存储十万个历史记录进行快速查询,并且更具用户要求进行压缩合并。由于etcd v3实现了MVCC,记录了所有的历史记录,所以这些数据不能都放在内存中。因此,etcd v3是一个磁盘数据库,底层的存储引擎使用BoltDB

etcd v3的迷你事务

很多情况下,客户端需要同时去读或者写一个key,或者很多个key。提供同步原语防止数据竞争是重要的。etcd v3中引入了迷你事务(mini-transaction)的概念。每个迷你事务都可以包含一些列条件语句,只有在满足特定条件下事务才会执行。迷你事务支持原子的比较多个键值并且操作多个键值。之前CAS是特殊的针对单个key的迷你事务。

gRPC服务

发送至etcd v3服务器的每一个API请求均为gRPC远程过程调用。etcd v3将其归类为不同的服务(service),而service又可分为方法(method)定义和消息(message)定义。

根据etcd v3的所定义的不同服务,其API可以分为键值(KV),集群(Cluster),维护(Maintenance),认证/鉴权(Auth),观察(Watch)与租约(Lease)六大类

各类服务所包含的方法具体描述了与其对应的API所具备的功能,从大的角度概括,这些服务又可以分为两类,其中一类是管理集群的API,具体包括如下功能:

  • Auth
    Service可能是某项鉴定过程以及处理鉴定的请求,比如,增加或者删除用户,更改用户密码,查询用户信息和获取用户列表,以及授权或者撤销用户角色,增加或者删除角色,查询角色信息和获取角色列表,以及为角色授予或撤销某项特定的key
  • Cluster Service用于在集群中增加或删除成员,更新成员配置,以及得到集群中包含所有成员的列表
  • Maintenance Service则提供了启动或者停止警报以及查询警报的功能,还可以查询成员的状态信息,为成员后端数据库整理碎片,在client的流中发送某成员的完整后端快照

另外一大类是处理etcd键值空间的API,具体包括如下:

  • KV Service:用于创建,更新,获取以及删除键值对
  • Watch Service:用于监听key的变化
  • Lease Service:用于消耗客户端keep-alive消息的原语

请求和响应

etcd v3的所有RPC都遵循相同得格式。每个RPC都形如一个函数声明,都有一个入参和返回值。

etcd v3 API的所有响应都携带一个响应头部,包含了etcd集群的元数据。示例代码如下:

message ResponseHeader {
	 uint64ccluster_id = 1 ;
	 uint64 member_id = 2 ;
	 int64 revision = 3;
	 uint64 raft_term = 4;
 }

上述代码字段说明如下:

  • cluster_id:生成响应的cluster ID
  • member_id:生成该相应的member ID
  • revision:生成该响应的键值存储的版本。修改etcd后台键值存储的每一步操作都会被赋予一个单调递增的版本号(revision)。一个事物可能修改多次后台键值存储,但只会产生一个revision。被操作修改的键值对的revision属性与操作的revision具有相同的值。revision可以用作后台键值存储的逻辑锁。拥有更大revision值的键值对肯定是revision值较小的键值对之后被修改,两个revision相同的键值对肯定被某个操作(一般是事务)同时修改
  • Raft_Term:生成该响应的member所处的Raft协议任期(term)
    客户端可以通过检查Cluster_ID或者Member_ID子段的值来确认是否正在与目标集群或节点通信

客户端可以通过revision的值获取发生该操作时,etcd集群后端键值存储最新revision。客户端可以通过Rafr_Term的值来检测etcd集群是否完成了一次新的领导人选举

KV API

键值对(key-value pair)是KV API所能处理的最小单位,每个键值对均包含一些protobuf格式的子段

message  KetValue {
 bytes key = 1;
 bytes value = 2;
 int64 create_revision = 3;
 int64 mod_revision = 4;
 int64 version = 5 ;
 int64 lease = ;
 } 

从上面定义可以看出,在KV message中,除了key-value映射值及其lease信息之外,还有一类重要的revsiosn元数据(包括create_revision和mod_revsion)。这些revsion信息可以根据创建时间和修改时间对key进行排序

revision

etcd 的revision本质上就是etcd维护的一个在集群范围有效的64位计数器。只要etcd的键空间发生变化,ervision值也会行吟阁增加。也可以jiangrevision看成是全局的逻辑时钟,即所有针对后端存储的修改操作进行连续的排序。revision的值是单调递增的,而与某个revision相关联的数据则是那些改变了后端存储的数据。从内部实现来看,出现一个revision,就意味着某些修改写入了后端的B+树,而这些修改柴采用增大的revision作为索引

对于etcd v3的多版本并发控制,revision价值不言而喻。MVCC模型是指由于保存了键空间的历史,因此可以查看过去某个revision(版本)的key-value的存储。同时为了实现细粒度的存储管理,集群管理者可以自定义配置键空间历史保存策略。etcd v3会借助自定义的计时器废弃旧键的版本(revision)典型的etcd v3集群可以使被替代的key的数据保留数小时。因此,etcd v3具备对客户端长时间断开连接的可靠处理能力,突破了仅能处理暂态网络中断的限制。在这种情况下,watch客户端可以直接根据最近以此观察到的revision进行恢复。类似的,如果客户端希望读取某个时间点的key-value存储状态,则只需要在请求中附带某个revision的值即可返回该revision提交时间点的key空间状态

键区间

etcd v3数据模型采用扁平key空间,为所有key建立索引。该模型有别于其他常见的采用层级系统将key组建为目录(directory)的key-value存储系统。key不再以目录的形式列出,而是左闭右开的形式,如[ key1,keyN)。对于key去就按的操作,既保留了对目录形式key的查找能力。

事务

在 etcd v3中,事务就是一个原子的,针对key-value存储操作的If/Then/Else结构。事务提供了一个原语,用于将请求归并到一起放在原子块中,这些原子块的执行条件以key-value存储里的内容为依据。事务可以用来保护key不受其他并发更新操作的修改,也可以构建CAS操作,并以此作为更高层次并发控制的基础。

所有的事务都由一个比较“连接(conjunction)”来守护,类似于if声明,每个比较都会检查后台存储中的一个key。这个检查可以是如下内容:该key在后台存储是否有value?该key的value是否等于某个给定的值?除了value,还可以检查这个key的revision或者version。。如果所有的比较都返回true,那么就说明该事务成功执行了,并且执行该事务success请求块中的操作,反之就说明该事务失败了,转而执行该事务failure请求块中的操作

Event

对于每个key而言,发生的每一个变化都以Event消息进行表示。一个Event消息提供了变化的类型与对应改变的数据,其字段定义代码如下:

message Event{
	enum EventType{
			PUT = 0;
			DELETE = 1;
		}
		EventType type  =1;
		KeyValue kv = 2; //与Event管来奶的key-value
		KeyValue prev_kv = 3//对应紧接着Event之前的revision的key-value
}
  • type
    :Event类型,分为PUT类型和DELETE类型。PUT类型表明新的数据已经存储到对应的key,DELETE类型表明key已经被删除了
  • KV:与Event关联的key-value。一个PUT Event包含当前的KV,一个Version=1的PUT Event表明这个key是新建的。一个DELETE Event包含被删除的key和该key被删除时的modification revision
  • Prev——KV:该key在发生此Event之前最近一刻revision的key-value对。为了节省带宽,只有在Watch请求中显示地启动该选项时才会在响应中返回该值

流式Watch

wacth操作是长期持续存在地请求,watch流是双向的。Client通过写入流来创建watch,另一方面,Client通过读入流来接收watch到的Event。

etcd v3的watch机制确保检测到的Event具有有序,可靠与原子化的特点,各个特点对应的意义如下:

  • 有序:Event按照revision排序,后发生的Event不会在前面的Event之前出现在watch流中
  • 可靠:某个事件序列不会一楼1其中任意的子序列,假设有三个Event,按发生事件依次排序a<b<b,如果watch接收到Event a和c,那么能保证b也被接收了
  • 原子性:Event列表确保完整的revision,在相同得revision多个key上,更新不会分裂为几个事件列表

Lease API

租约是一种检测客户端活跃度的机制。Lease机制应用广泛。租约是有生存时间的,集群为租约授予一个TTL。当key被授予一个租约时,他的生存时间即为Lease生存时间。当Lease的TTL到期时,所有与之关联的key都会被删除。

如果etcd集群在给定的TT周期内没有收到一个keepAlive消息维持租约,那么该租约将过期。etcd3所支持的租约机制可为etcd中的某一个或者多个key关联租约,一个key最多关联一个租约。当一个租约过期时,所有关联的key都会被自动删除。每个过期的key都会产生一个“删除”事件

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值