在之前的文章初识etcd中已经简单介绍的etcd的原理,这篇文章来简要介绍一下etcd的一些使用场景。
前置知识
首先我们需要了解一下etcd的租约机制
Lease租约是一种检测客户端存活状况的机制。如果 etcd 集群在给定的 TTL 时间内未收到服务的 keepAlive 消息,则租约到期。
客户端可以向etcd集群申请一个TTL为n的租约,然后定时向etcd集群发送keepalive消息进行续约,一旦超时没有收到keepalive,etcd就会将该租约绑定的key删除。
Ps. 一个租约可以挂多个key,一个key只能挂一个租约
服务发现
服务注册与发现(Service Discovery)是etcd最常见的使用场景,解决的是如何在同一个分布式集群中的进程或服务找到目标服务的IP地址并建立连接。从本质上说,服务发现就是要了解集群中是否有进程在监听 UDP 或者 TCP 端口,并且通过名字就可以进行查找和连接。
在分布式系统中,服务提供者都是以集群的方式对外提供服务,集群中服务的IP随时都可能发生变化,因此服务提供者需要将自己的服务注册到etcd中去。这样,服务使用者通过etcd可以获取到实际服务提供者的ip信息,连接到服务提供者,进行后续操作。
那么etcd是怎么实现服务注册和发现的呢?
我们知道,etcd首先是一个高可用的KV存储系统。 当服务启动的时候,服务提供方会将服务的启动IP和Port以name的形式注册到基于etcd中:
- 以ip+port为value
- 以schema+name(服务名称)+value作为etcd的key。 etcd 会给这个key提供一个租约,并定时续约,保证服务在线。
而服务发现实质上就是根据客户端上传的服务name去KV存储系统查询注册的服务,查到就将value返回给客户端,客户端对服务发起调用
消息发布与订阅
使用etcd进行消息发布与订阅,实际上就是构建一个配置共享中心
消息发布方在将消息存储到对应的key上,消息订阅者在etcd节点上注册一个Watcher并等待,以后每次配置有更新的适合,etcd都会实时通知订阅者,以此达到获取最新配置信息的目的。
分布式锁
etcd使用Raft算法保持了数据的强一致性,某次操作存储到集群中的值必然是全局一致的。使用方式类似redis。
锁服务有两种使用方式,一是保持独占,二是控制时序。
保持独占,即所有试图获取锁的用户最终只有一个可以得到。etcd为此提供了一套实现分布式锁原子操作CAS(CompareAndSwap)的API。通过设置prevExist值,可以保证在多个节点同时创建某个目录时,只有一个成功,而该用户即可认为是获得了锁。(判断该key是否存在,存在就加锁成功,不存在就加锁失败) -- 非公平锁
控制时序,即所有试图获取锁的用户都会进入等待队列,获得锁的顺序是全局唯一的,同时决定了队列执行顺序。etcd为此也提供了一套API(自动创建有序键),对一个目录建值时指定为POST动作,这样etcd会自动在目录下生成一个当前最大的值为键,存储这个新的值(客户端编号)。同时还可以使用API按顺序列出所有当前目录下的键值。此时这些键的值就是客户端的时序,而这些键中存储的值可以是代表客户端的编号。(多个用户去put一个key,会返回不同revision,查看key的所有revision中自己是否最小,是则加锁成功,不是则监听比自己小的前一个revison的删除事件,删除后即自己获得锁) -- 公平锁