etcd 入门

服务注册与服务发现

三部分的作用:

  • 注册中心:记录服务和服务地址的映射关系

  • 服务提供者:将服务注册到服务中心

  • 服务发现者:对服务中心的服务进行调用

简单易懂的 raft 算法

Raft算法是一个一致性算法。其过程如同选举一样,参选者要说服大多数的选民(服务器)投票给他,一旦选定,就要跟随其操作。

raft协议server 进程分为三类,分别是 Leader(领袖)、Candidate(候选人)、Follower(群众),一个 service 进程在某一时刻,只能是其中一种类型,但这不是固定的,不同时刻,它可能拥有不同的类型。

就想是一个民主社会,领袖由群众投票选出。刚开始没有领袖,所有集群中的参与者都是群众。首先开启一轮大选,在大选期间,所有的群众都能参与竞选,这时所有的群众的角色就会变成候选人,民主投票选出领袖后,就开始这一届的领袖任期,然后选举结束,所有除了领袖外的候选人又变回了群众的角色服从领袖领导。

Leader 选举过程

从raft算法的基本概念可以推出,一个最小的raft民主集群,也需要三个参与者。一般情况下,进行投票,都可以选出Leader,但是有些极端情况,比如 A B C 三个节点都投了自己,结果没有任何一方获得多数票,这时候,每个参与方都要随机休息一会,重新发起投票,直到一方获得多数票。这里的关键就是随机,最先从 timeout 中恢复发起投票的一方,向还在 timeout 中的另外两方请求投票,这时他只能投给自己,导致很快达成一致。

选举出来 leader 后,leader通过定期向所有的 Follower 发送心跳信息维持其统治,若 Follower 一段时间未收到 leader 的心跳,则认为 Leader已经挂了,然后再次发起选举过程。

raft算法的强一致性

raft 协议强依赖与 leader 节点的可用性,以确保集群数据的一致性。如果发生异常,集群的控制权就会从 Leader 节点往其他 Follower 节点转移。具体的过程如下

  1. 当 client 向集群 leader 节点提交数据后,此时 Leader 节点接受到的数据处于未提交状态

  2. Leader 节点会并发向所有的 Follower 极点复制数据并等待接受响应

  3. 集群中超过半数的节点已接受到数据后,Leader 再向 Client 确认数据已接受

  4. 一旦 Leader 节点向 Client 发送已接受数据的 ACK 响应的时候,表示此时的数据状态进入已提交状态。Leader 节点会再向 Follower 节点发通知告知该数据状态已提交


脑裂

raft算法保证任一任期内最多一个leader被选出。在一个复制集中任何时刻只能有一个leader。系统中同时有多余一个leader,被称之为脑裂(brain split),这是非常严重的问题,会导致数据的覆盖丢失。在raft中,两点保证了这个属性:

  1. 一个节点某一任期内最多只能投一票

  2. 只有获得majority投票的节点才会成为leader

因此,某一任期内一定只有一个leader。但是,在网络分割(network partition)的情况下,可能会出现两个leader,但两个leader所处的任期是不同的。

一旦出现脑裂,网络分将原来的 Leader 节点和 Follower 节点分隔开,Follower 节点收不到 Leader的心跳将重新发起选举,产生新的 Leader 节点,这样就会产生双 Leader的现象。

原来的 Leader 独自在一个区,向它提交数据不可能复制到多数节点,所以永远提交不成功。网络恢复后,旧的 Leader 会发现集群中有更新任期的新的 Leader,则自动降级为 Follower 并从新的 Leader 处同步数据达成集群数据一致。

Etcd 的基本操作

使用 docker 安装 etcd

docker run -d --restart=always -p 2379:2379  --env ALLOW_NONE_AUTHENTICATION=yes   --name etcd_zh  bitnami/etcd
  1. etcd 操作,分为数据库操作和非数据库操作两种。

  2. 默认的 etcdApi2.x 版本,需设置为 3.X 的通用版本。

  3. 在 ubuntu 系统中,环境变量更改后,最好使用 reboot 命令重启一下,确保声明的环境变量生效。

export ETCDCTL_API=3

或者在`/etc/profile`文件中添加环境变量
vi /etc/profile
...
export ETCDCTL_API=3
...
source /etc/profile

数据库操作

1. 增

etcdctl put testkey01 111

2. 查

单个查找

etcdctl get testkey01

范围查找

etcdctl get testkey01  testkey03   # 查询范围为 [testkey01  testkey03 ),前闭后开,不含 testkey03

使用前缀查找

etcdctl get --prefix testkey      # 查询所有 testkey 开头的 key

如果以某前缀开始的 key 过多的话,可以限制数量

etcdctl get --prefix --limit 2  testke   #最多显示两个

3. 删除

范围删除

etcdctl del testkey01 testkey03   # 删除范围为 [testkey01  testkey03 ),前闭后开,不含 testkey03

watch 历史变动

在命令行输入watch 命令,则如果该值发生变化,则在该终端中会立马进行显示

etcdctl watch testkey03          # 监视 testkey03

etcdctl put  testkey03  0333  # 另开一个命令行,改变testkey03 的值

lease 租约

Lease 意思为租约。类似于 redis 中的 TTL (time to live)

$ etcdctl lease grant 100    # 授予租约
lease 694d80c19225c31a granted with TTL(100s)    # 得到一个租约

将租约添加到 key4 上

etcdctl put --lease=694d80c19225c31e testkey04 444    # 将租约绑定到 key4上

持续刷新租约,让其永远生效

etcdctl lease keep-alive 694d80c19225c322

刷新租期剩余时间

$ etcdctl lease timetolive 694d80c19225c322                               # 查看租期的剩余时间
lease 694d80c19225c322 granted with TTL(100s), remaining(86s)   # 查询结果:还剩86秒杀

撤销租约;在撤销的过程中,会删除掉该租约所附带的所有的 key

etcdctl lease timetolive 694d80c19225c322
posted @ 2022-05-14 16:59  沧海一声笑rush  阅读(230)  评论(0编辑  收藏  举报