官方地址 https://etcd.io
Github官方地址:https://github.com/etcd-io/etcd
中文文档:https://doczhcn.gitbook.io/etcd/index/index/interacting_v3

etcd应用场景

服务发现

服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务,要如何才能找到对方并建立连接。本质上来说,服务发现就是想要了解集群中是否有进程在监听 udp 或 tcp 端口,并且通过名字就可以查找和连接。

配置中心

将一些配置信息放到 etcd 上进行集中管理。
这类场景的使用方式通常是这样:应用在启动的时候主动从 etcd 获取一次配置信息,同时,在 etcd 节点上注册一个 Watcher 并等待,以后每次配置有更新的时候,etcd 都会实时通知订阅者,以此达到获取最新配置信息的目的。

分布式锁

因为 etcd 使用 Raft 算法保持了数据的强一致性,某次操作存储到集群中的值必然是全局一致的,所以很容易实现分布式锁。锁服务有两种使用方式,一是保持独占,二是控制时序。

  • 保持独占即所有获取锁的用户最终只有一个可以得到。etcd 为此提供了一套实现分布式锁原子操作 CAS(CompareAndSwap)的 API。通过设置prevExist值,可以保证在多个节点同时去创建某个目录时,只有一个成功。而创建成功的用户就可以认为是获得了锁。
  • 控制时序,即所有想要获得锁的用户都会被安排执行,但是获得锁的顺序也是全局唯一的,同时决定了执行顺序。etcd 为此也提供了一套 API(自动创建有序键),对一个目录建值时指定为POST动作,这样 etcd 会自动在目录下生成一个当前最大的值为键,存储这个新的值(客户端编号)。同时还可以使用 API 按顺序列出所有当前目录下的键值。此时这些键的值就是客户端的时序,而这些键中存储的值可以是代表客户端的编号。

安装

源码安装

下载地址https://github.com/etcd-io/etcd/releases

  1. cd /opt/sofaware/
  2. wget https://github.com/etcd-io/etcd/releases/download/v3.4.0/etcd-v3.4.0-linux-amd64.tar.gz

解压文件

  1. # mkdir -p /opt/module
  2. # tar -zxf etcd-v3.4.0-linux-amd64.tar.gz -C /opt/module/
  3. # cd /opt/module/
  4. # mv etcd-v3.4.0-linux-amd64/ etcd

查看当前目录结构

  1. # ls -ll
  2. total 40296
  3. drwxr-xr-x 14 1922357897 wheel 4096 Sep 16 23:46 Documentation
  4. -rwxr-xr-x 1 1922357897 wheel 23667040 Aug 30 23:54 etcd
  5. -rwxr-xr-x 1 1922357897 wheel 17513984 Aug 30 23:54 etcdctl
  6. -rw-r--r-- 1 1922357897 wheel 43094 Aug 30 23:54 README-etcdctl.md
  7. -rw-r--r-- 1 1922357897 wheel 8431 Aug 30 23:54 README.md
  8. -rw-r--r-- 1 1922357897 wheel 7855 Aug 30 23:54 READMEv2-etcdctl.md

配置环境变量
vim /etc/profile

  1. export PATH=$PATH:/opt/module/etcd

切记一定要执行

  1. source /etc/profile

查看安装版本信息

  1. # etcd --version
  2. etcd Version: 3.4.0
  3. Git SHA: 898bd1351
  4. Go Version: go1.12.9
  5. Go OS/Arch: linux/amd64

MacOS安装

建议使用brew 安装

  1. # brew install etcd
  2. To have launchd start etcd now and restart at login:
  3. brew services start etcd
  4. Or, if you don't want/need a background service you can just run:
  5. etcd

docker-compose安装

docker-compose.yaml 文件如下

  1. version: '2'
  2. networks:
  3. etcd-net:
  4. services:
  5. etcd1:
  6. image: quay.io/coreos/etcd:v3.3.18
  7. container_name: etcd1
  8. command: etcd -name etcd1 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380" -initial-cluster-state new
  9. ports:
  10. - 2379
  11. - 2380
  12. networks:
  13. - etcd-net
  14. etcd2:
  15. image: quay.io/coreos/etcd:v3.3.18
  16. container_name: etcd2
  17. command: etcd -name etcd2 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380" -initial-cluster-state new
  18. ports:
  19. - 2379
  20. - 2380
  21. networks:
  22. - etcd-net
  23. etcd3:
  24. image: quay.io/coreos/etcd:v3.3.18
  25. container_name: etcd3
  26. command: etcd -name etcd3 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380" -initial-cluster-state new
  27. ports:
  28. - 2379
  29. - 2380
  30. networks:
  31. - etcd-net

启动

  1. $ docker-compose up

验证

  1. sudo docker exec -t etcd1 etcdctl member list
  2. ade526d28b1f92f7: name=etcd1 peerURLs=http://etcd1:2380 clientURLs=http://0.0.0.0:2379 isLeader=false
  3. bd388e7810915853: name=etcd3 peerURLs=http://etcd3:2380 clientURLs=http://0.0.0.0:2379 isLeader=false
  4. d282ac2ce600c1ce: name=etcd2 peerURLs=http://etcd2:2380 clientURLs=http://0.0.0.0:2379 isLeader=true

配置参数

  1. --name:方便理解的节点名称,默认为default,在集群中应该保持唯一,可以使用 hostname
  2. --data-dir:服务运行数据保存的路径,默认为 ${name}.etcd
  3. --snapshot-count:指定有多少事务(transaction)被提交时,触发截取快照保存到磁盘
  4. --heartbeat-intervalleader 多久发送一次心跳到 followers。默认值是 100ms
  5. --eletion-timeout:重新投票的超时时间,如果 follow 在该时间间隔没有收到心跳包,会触发重新投票,默认为 1000 ms
  6. --listen-peer-urls:和同伴通信的地址,比如 http://ip:2380,如果有多个,使用逗号分隔。需要所有节点都能够访问,所以不要使用 localhost!
  7. --listen-client-urls:对外提供服务的地址:比如 http://ip:2379,http://127.0.0.1:2379,客户端会连接到这里和 etcd 交互
  8. --advertise-client-urls:对外公告的该节点客户端监听地址,这个值会告诉集群中其他节点
  9. --initial-advertise-peer-urls:该节点同伴监听地址,这个值会告诉集群中其他节点
  10. --initial-cluster:集群中所有节点的信息,格式为 node1=http://ip1:2380,node2=http://ip2:2380,…。注意:这里的 node1 是节点的 --name 指定的名字;后面的 ip1:2380 是 --initial-advertise-peer-urls 指定的值
  11. --initial-cluster-state:新建集群的时候,这个值为new;假如已经存在的集群,这个值为 existing
  12. --initial-cluster-token:创建集群的token,这个值每个集群保持唯一。这样的话,如果你要重新创建集群,即使配置和之前一样,也会再次生成新的集群和节点 uuid;否则会导致多个集群之间的冲突,造成未知的错误
  13. 所有以--init开头的配置都是在bootstrap集群的时候才会用到,后续节点的重启会被忽略

创建etcd 数据目录

  1. # mkdir -p /data/etcd #建议创建单独的etcd数据目录

启动项配置
vim /etc/systemd/system/etcd.service

  1. [Unit]
  2. Description=Etcd Server
  3. Documentation=https://github.com/coreos/etcd
  4. After=network.target
  5. [Service]
  6. User=root
  7. Type=notify
  8. EnvironmentFile=-/opt/module/etcd/config/etcd.conf
  9. ExecStart=/opt/module/etcd/etcd
  10. Restart=on-failure
  11. RestartSec=10s
  12. LimitNOFILE=40000
  13. [Install]
  14. WantedBy=multi-user.target

配置信息
mkdir -p /opt/module/etcd/config/
cd /opt/module/etcd/config/
vim etcd.conf

  1. ETCD_NAME=etcd3
  2. ETCD_DATA_DIR="/data/etcd"
  3. ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
  4. ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
  5. ETCD_INITIAL_ADVERTISE_PEER_URLS="http://http://123.456.769.190:2380"
  6. ETCD_INITIAL_CLUSTER="etcd1=http://http://123.456.769.192:2380,etcd2=http://http://123.456.769.191:2380,etcd3=http://http://123.456.769.190:2380"
  7. ETCD_INITIAL_CLUSTER_STATE="new"
  8. ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
  9. ETCD_ADVERTISE_CLIENT_URLS="http://123.456.769.190:2379"

name:本member的名称;
data-dir:存储的数据目录;
listen-client-urls:用于监听客户端etcdctl或者curl连接;0.0.0.0表示监听本机所有地址;
listen-peer-urls:用于监听集群中其它member的连接;0.0.0.0表示监听本机所有地址;
advertise-client-urls: 本机地址, 用于通知客户端,客户端通过此IPs与集群通信;
initial-advertise-peer-urls:本机地址,用于通知集群member,与member通信;
initial-cluster:描述集群中所有节点的信息,描述每个节点名称、ip、端口,集群静态启动使用,本member根据此信息去联系其他member;
initial-cluster-token:集群唯一标示;
initial-cluster-state:集群状态,新建集群时候设置为new,若是想加入某个已经存在的集群设置为existing

启动etcd
启动的 etcd 成员在 localhost:2379 监听客户端请求。

  1. systemctl daemon-reload && systemctl enable etcd && systemctl start etcd

基本操作

docker进入etcd实例

  1. $ docker exec -it etcd_node1_1 /bin/sh

通过使用 etcdctl 来和已经启动的集群交互:

  1. # 使用 API 版本 3
  2. $ export ETCDCTL_API=3
  3. $ ./etcdctl put foo bar
  4. OK
  5. $ ./etcdctl get foo
  6. bar

插入数据

  1. #etcdctl put key1 value1
  2. OK

获取数据

  1. # etcdctl get key1
  2. key1
  3. value1

获取前缀的数据

  1. # etcdctl get key --prefix
  2. key1
  3. value1

删除数据

  1. # etcdctl del key1
  2. 1
  3. # etcdctl del key
  4. 0

观察数据变化

  1. etcdctl put key2 value2
  2. etcdctl put key2 value22
  1. # etcdctl watch key2
  2. PUT
  3. key2
  4. value2
  5. PUT
  6. key2
  7. value22

列出成员

  1. etcdctl member list

检查集群状健康状态

  1. etcdctl endpoint health

参考

https://github.com/etcd-io/etcd/releases
https://etcd.io/docs/v3.4.0/demo/
https://www.cnblogs.com/51wansheng/p/10234036.html
https://www.jianshu.com/p/44022c67f117
https://www.infoq.cn/article/etcd-interpretation-application-scenario-implement-principle
https://gitbook.cn/books/5bb037728f7d8b7e900ff2d7/index.html