ETCD

下载

https://github.com/coreos/etcd/releases/
下载 linux-amd64 版本,例如:etcd-v3.3.10-linux-amd64.tar.gz

安装

解压(解压目录最好还是放在本用户有权限的路径,不然后面的启动什么的都需要 sudo)

$ sudo tar -zxvf etcd-v3.3.10-linux-amd64.tar.gz -C /opt/    
更改路径名    
$ sudo mv etcd-v3.3.10-linux-amd64 etcd-v3.3.10    

更新 etcd 系统默认配置:
当前使用的是 etcd v3 版本,系统默认的是 v2,通过下面命令修改配置。

$ sudo vim /etc/profile  
在末尾追加   
export ETCDCTL_API=3  

$ source /etc/profile

配置节点

示例三个节点为(只做一个节点也可以工作):
192.168.108.128 节点1
192.168.108.129 节点2
192.168.108.130 节点3

可以在系统定义如下环境变量,方便后续操作
HOST_1=192.168.108.128
HOST_2=192.168.108.129
HOST_3=192.168.108.130
ENDPOINTS=HOST_2:2379,$HOST_3:2379

创建配置文件目录
$ sudo mkdir /etc/etcd

创建 etcd 配置文件
$ sudo vim /etc/etcd/conf.yml

节点1,添加如下内容:

name: etcd-1
data-dir: /opt/etcd-v3.3.10/data
listen-client-urls: http://192.168.108.128:2379,http://127.0.0.1:2379
advertise-client-urls: http://192.168.108.128:2379,http://127.0.0.1:2379
listen-peer-urls: http://192.168.108.128:2380
initial-advertise-peer-urls: http://192.168.108.128:2380
initial-cluster: etcd-1=http://192.168.108.128:2380,etcd-2=http://192.168.108.129:2380,etcd-3=http://192.168.108.130:2380
initial-cluster-token: etcd-cluster-token
initial-cluster-state: new

节点2,添加如下内容:

name: etcd-2
data-dir: /opt/etcd-v3.3.10/data
listen-client-urls: http://192.168.108.129:2379,http://127.0.0.1:2379
advertise-client-urls: http://192.168.108.129:2379,http://127.0.0.1:2379
listen-peer-urls: http://192.168.108.129:2380
initial-advertise-peer-urls: http://192.168.108.129:2380
initial-cluster: etcd-1=http://192.168.108.128:2380,etcd-2=http://192.168.108.129:2380,etcd-3=http://192.168.108.130:2380
initial-cluster-token: etcd-cluster-token
initial-cluster-state: new

节点3,添加如下内容:

name: etcd-3
data-dir: /opt/etcd-v3.3.10/data
listen-client-urls: http://192.168.108.130:2379,http://127.0.0.1:2379
advertise-client-urls: http://192.168.108.130:2379,http://127.0.0.1:2379
listen-peer-urls: http://192.168.108.130:2380
initial-advertise-peer-urls: http://192.168.108.130:2380
initial-cluster: etcd-1=http://192.168.108.128:2380,etcd-2=http://192.168.108.129:2380,etcd-3=http://192.168.108.130:2380
initial-cluster-token: etcd-cluster-token
initial-cluster-state: new

配置变量说明:

Etcd的参数配置方式有两种,一种是命令行的方式,一种是环境变量的方式。命令行方式的优先级高于环境变量的方式。

Etcd默认2379端口处理客户端的请求;2380端口用于集群各成员间的通信。

#[member]

-name 或 ETCD_NAME: 指定当前etcd成员的名称 默认值为"default",通常用户Hostname来命名。

-data-dir或ETCD_DATA_DIR:etcd数据文件目录,默认是“${name}.etcd”

–snapshot-count或ETCD_SNAPSHOT_COUNT:指定多少次commit操作会触发一次磁盘快照,默认值是10000

–heartbeat-interval或 ETCD_ELECTION_TIMEOUT:心跳信号间隔,毫秒级,默认是100毫秒。

–listen-peer-urls或 ETCD_LISTEN_PEER_URLS:用于监听集群中其他成员的发送信息的地址。默认值是“http://localhost:2380”

–listen-client-urls或ETCD_LISTEN_CLIENT_URLS:用于监听客户端发来的信息的地址,默认值是“http://localhost:2379”

–max-snapshots或ETCD_MAX_SNAPSHOTS:镜像文件的最大个数,默认是5.0表示无限制

–max-wals或ETCD_MAX_WALS:

#[cluster]
–initial-advertise-peer-urls或 ETCD_INITIAL_ADVERTISE_PEER_URLS:集群中各节点相互通信的地址。

–initial-cluster或ETCD_INITIAL_CLUSTER:初始集群由哪些成员组成 默认值是“efault=http://localhost:2380”

–initial-cluster-state或ETCD_INITIAL_CLUSTER_STATE:集群的初始状态,其值有“new”和“existing”,默认为“new”

–initial-cluster-token:ETCD_INITIAL_CLUSTER_TOKEN:集群名称

–advertise-client-urls或ETCD_ADVERTISE_CLIENT_URLS:客户端与集群通信地址 

配置 etcd 为启动服务

编辑/usr/lib/systemd/system/etcd.service,添加下面内容:

[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
WorkingDirectory=/opt/etcd-v3.2.6/
# User=etcd
ExecStart=/opt/etcd-v3.2.6/etcd --config-file=/etc/etcd/conf.yml
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

更新启动:

systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
systemctl restart etcd

systemctl status etcd.service -l

etcd 命令

查看版本号:

$ cd /opt/etcd-v3.3.10/  
$ ./etcdctl version  

启动:
$ ./etcd --config-file=/etc/etcd/conf.yml

查看集群成员信息:
$ ./etcdctl member list

查看集群状态(Leader节点):
$ ./etcdctl cluster-health

查看 leader 状态:
$ curl http://127.0.0.1:2379/v2/stats/leader

查看自己的状态:
$ curl http://127.0.0.1:2379/v2/stats/self

查看存储统计信息:
$ curl http://127.0.0.1:2379/v2/stats/store

v3 的请求需要 eted 3.4 以上,详细参见:https://github.com/etcd-io/etcd/blob/master/Documentation/dev-guide/api_grpc_gateway.md

etcd 读写操作

基于 HTTP 协议的 API 使用起来比较简单,这里主要通过 etcdctl 和 curl 两种方式来做简单介绍。
如果 key 名字前有下划线,例如:_message 表示是一个隐藏 key,隐藏 key 在获取 key 列表时是不返回的

下面通过给 message key 设置/读取 Hello 值示例:

$ ./etcdctl set /message Hello --ttl 10
Hello  
注意:ETCDCTL_API=3 时,此命令改为了:./etcdctl put /message Hello
此时,不支持 --ttl 5 这样的参数,只能使用 --lease=xxxxxxxxxxxxx  这样的方式设置过期

$ ./etcdctl get /message  
Hello  

可以根据前缀查询,会返回全部前缀相同的 key value  
$ ./etcdctl --endpoints=$ENDPOINTS get /mess --prefix     版本 3 才行

$ curl http://127.0.0.1:2379/v2/keys/message  
{"action":"get","node":{"key":"/message","value":"Hello","modifiedIndex":4,"createdIndex":4}}  

获取 key 列表:
$ curl http://127.0.0.1:2379/v2/keys/

从文件给 key 赋值:

$ echo "Hello\nWorld" > afile.txt
$ curl http://127.0.0.1:2379/v2/keys/afile -XPUT --data-urlencode [email protected]

观察 key 的历史改动(下面的命令从第二个版本开始):
$ ./etcdctl watch --rev=2 foo

删除 message key

$ ./etcdctl  rm  /message

$ curl -X DELETE http://127.0.0.1:2379/v2/keys/message
{"action":"delete","node":{"key":"/message","modifiedIndex":5,"createdIndex":4},"prevNode":{"key":"/message","value":"Hello","modifiedIndex":4,"createdIndex":4}}

设置过期时间(ttl 单位为:秒)

$ curl http://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar3 -d ttl=5

可以在另一个终端连续获取此 key 值来观察
$ curl http://127.0.0.1:2379/v2/keys/foo
{"action":"get","node":{"key":"/foo","value":"bar3","expiration":"2018-10-22T09:11:40.620211679Z","ttl":3,"modifiedIndex":10,"createdIndex":10}}

5 秒后,"errorCode":100
$ curl http://127.0.0.1:2379/v2/keys/foo
{"errorCode":100,"message":"Key not found","cause":"/foo","index":11}

可以在一个 key 过期之前刷新过期时间(参数 -d prevExist=true 表示这个 key 必须存在):
$ curl http://127.0.0.1:2379/v2/keys/foo -XPUT -d ttl=5 -d refresh=true -d prevExist=true

lease 租约 (必须:export ETCDCTL_API=3)

在实现服务发现时,我们一般都会用到 ZooKeeper 的临时节点,只要客户端与 ZooKeeper 之间的 session 会话没有中断(过期),那么创建的临时节点就会存在。当客户端掉线一段时间,对应的 ZK session 会过期,那么对应的临时节点就会被自动删除。

在 etcd 中并没有临时节点的概念,但是支持 lease 租约机制。什么叫 lease?其实就是 etcd 支持申请定时器,比如:可以申请一个 TTL=10 秒的 lease(租约),会返回给你一个 lease ID 标识定时器。你可以在 put 一个 key 的同时携带 lease ID,那么就实现了一个自动过期的 key。在 etcd 中,一个 lease 可以关联给任意多的 Key,当 lease 过期后所有关联的 key 都将被自动删除。

那么如何实现临时节点呢?首先申请一个 TTL=N 的 lease,然后 put 一个 key with lease 作为自己的临时节点,在程序中定时的为 lease(租约)进行续约,也就是重置 TTL=N,这样关联的 key 就不会过期了。

本机可以不写 --endpoints
$ ./etcdctl --endpoints=127.0.0.1:2379 lease grant 300
会返回:lease 2be7547fbc6a5afa granted with TTL(300s)

./etcdctl --endpoints=$ENDPOINTS get sample

维持租约(etcdctl 不是单次续约,而是会一直不断的发送请求来维持这个租约)
ENDPOINTS lease keep-alive 2be7547fbc6a5afa
撤销租约(租约撤销后,所有相关 key 都会被删除)
ENDPOINTS lease revoke 2be7547fbc6a5afa

等待 key 或 目录 变化

在一个终端:
$ curl http://127.0.0.1:2379/v2/keys/foo?wait=true
该终端会进入等待返回状态

然后在另一个终端去改变它的值
$ curl http://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar

也可以等待指定的 index,这个 index 是 node 属性中的 modifiedIndex
$ curl 'http://127.0.0.1:2379/v2/keys/foo?wait=true&waitIndex=14'

原子的创建有序键值

在目录上使用 POST 命令就可以创建有序键值。
例如:

$ curl http://127.0.0.1:2379/v2/keys/message_qq -XPOST -d value=hello1  
$ curl http://127.0.0.1:2379/v2/keys/message_qq -XPOST -d value=hello2  

查看:  
$ curl http://127.0.0.1:2379/v2/keys/message_qq  
{"action":"get","node":{"key":"/message_qq","dir":true,"nodes":[{"key":"/message_qq/00000000000000000018","value":"hello1","modifiedIndex":18,"createdIndex":18},{"key":"/message_qq/00000000000000000019","value":"hello2","modifiedIndex":19,"createdIndex":19}],"modifiedIndex":18,"createdIndex":18}}  

原子操作

当条件成立时设置 key 值
$ curl http://127.0.0.1:2379/v2/keys/foo?prevExist=false -XPUT -d value=three
支持的判断条件有:prevValue,prevIndex,prevExist

当条件成立时删除 key
$ curl http://127.0.0.1:2379/v2/keys/foo?prevValue=two -XDELETE
支持的判断条件有:prevValue,prevIndex

事务写入

ENDPOINTS txn --interactive

compares:
// 输入以下内容,输入结束按 两次回车 
value("foo") = "bar"

//如果 foo = bar,则执行 
success requests (get, put, del): 
get foo

//如果 foo != bar,则执行 
failure requests (get, put, del): 
put foo bar

// 运行结果,执行了 success 流程: 
SUCCESS 
foo 
bar

分布式锁 Lock (必须:export ETCDCTL_API=3)

$ ./etcdctl --endpoints=127.0.0.1:2379 lock my_mutex1
会返回:my_mutex1/25f1669a0cd36164 并等待释放

在另一终端:
$ ./etcdctl --endpoints=127.0.0.1:2379 lock my_mutex1
会等待进入。此时在第一个终端 ^c 第二个终端会进入锁

查看集群状态

ENDPOINTS endpoint status 版本 3 才行
会返回:

+------------------+------------------+---------+---------+-----------+-----------+------------+ 
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX | 
+------------------+------------------+---------+---------+-----------+-----------+------------+ 
| 10.240.0.17:2379 | 4917a7ab173fabe7 | 3.0.0 | 45 kB | true | 4 | 16726 | 
| 10.240.0.18:2379 | 59796ba9cd1bcd72 | 3.0.0 | 45 kB | false | 4 | 16726 | 
| 10.240.0.19:2379 | 94df724b66343e6c | 3.0.0 | 45 kB | false | 4 | 16726 | 
+------------------+------------------+---------+---------+-----------+-----------+------------+

ENDPOINTS endpoint health 版本 3 才行
会返回:

10.240.0.17:2379 is healthy: successfully committed proposal: took = 3.345431ms 
10.240.0.19:2379 is healthy: successfully committed proposal: took = 3.767967ms 
10.240.0.18:2379 is healthy: successfully committed proposal: took = 4.025451ms

你可能感兴趣的:(ETCD)