本位主要用以记录一些etcd的基本操作和常识。
etcd是一个分布式的、可靠
的键值对存储服务。
配置管理
配置
到etcd,通过etcd的watch
API及时发布配置更改服务注册、发现
协调分布式工作
etcd各节点有三种角色,分别是:
etcd使用了Raft一致性协议来保证数据的强一致性,选举是Raft协议的重要组成。etcd集群如果没有leader将不允许任何数据更新操作。选举完成以后,集群会通过心跳的方式维持 leader 的地位,一旦 leader 失效,会有新的 follower 起来竞选 leader。
在集群刚启动时,所有节点的状态都为 follower,如果在一段时间周期内(election timeout)没有收到来自 leader 的 heartbeat,触发 leader election,该节点将自己切换为candidate,同时向其他节点发起选举请求,follower会响应这个请求。
如果多个candidate同时发起了选举,导致都没有获得大多数选票时,每一个candidate会随机等待一段时间后重新发起新一轮投票(一般是随机等待150-300ms),可避免多个节点同时竞选。
etcd的存储机制在v2和v3版本之间有差异,以下只讲v3版本的实现。
在v3版本中,etcd存储分为两部分:
kvindex基于Google的btree实现,保存在内存中,当client通过key查询value时,会现在kvindex中查询这个key的所有revision,然后通过revision去后端存储(boltdb)查询数据。
boltdb中存储的key是reversion,value则是client查询的key在这个reversion下的value,这样在boltdb中存储了这个key的所有版本的值,从而实现多版本机制。
每一个revision 都由( main ID, sub ID)唯一标识,它也是实现 etcd v3的基础。
同一事务共享maiID,但事务中的每次操作(PUT、DELETE)subID会递增(从0开始)。
mainid和sub id组成了全局唯一的reversion。
由于boltdb中保存了所有的版本,数据会越来越多,当数据量很大时,可以使用compact来压缩历史版本,也就是删除一部分历史,保留最近的版本。
compact(4)压缩4以前的 即1、2、3会被删除
etcd的watch机制支持watch某个固定的key,也支持watch一个范围。client发起watch时,可以指定一个revision(也可以不指定),如果指定了revision,etcd会从指定的revision返回数据。
租约可以指定一对Key value的TTL,是Key有一个有效状态。
可使用docker安装,方便快捷
docker-compose.yml文件内容如下:
version: '2'
services:
etcd:
image: 'bitnami/etcd:latest'
environment:
- "ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379"
- "ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379"
- "ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380"
- "ETCD_INITIAL_ADVERTISE_PEER_URLS=http://0.0.0.0:2380"
- "ALLOW_NONE_AUTHENTICATION=yes"
- "ETCD_INITIAL_CLUSTER=node1=http://0.0.0.0:2380"
- "ETCD_NAME=node1"
- "ETCD_DATA_DIR=/opt/bitnami/etcd/data"
ports:
- 2379:2379
- 2380:2380
e3w:
hostname: e3w
image: soyking/e3w:latest
volumes:
- ./e3w/config.ini:/app/conf/config.default.ini
ports:
- "61101:8080"
按上面的内容执行后会启动两个容器,1个是etcd节点,还有1个etcd的web ui:e3w。注意:要提前准备好e3w的配置文件。
[app]
port=8080
auth=false
[etcd]
root_key=/ui
dir_value=
addr=etcd:2379,etcd:22379,etcd:32379
username=
password=
cert_file=
key_file=
ca_file=
web ui操作和查询到的key会自动加个前缀,即配置文件中的root_key。所以别奇怪为什么查不到你写入的数据。如果开启了权限验证,需要配置username和password。
命令行操作非常简单,帮助信息清晰易懂。
几个常用命令:
获取
etcdctl get <key>
更新
etcdctl put <key> <value>
删除
etcdctl del <key>
权限控制相关:
root用户存在时才能开启权限控制
etcdctl user add root # 默认带root角色
etcdctl auth enable
开启权限控制后执行命令需要用--user指定用户
etcdctl get <key> --user=<用户>
使用新用户执行命令,提示没有权限,需要添加指定key的读写权限
(开启权限控制后,命令后面都需要加--user=<用户>,下面的命令已省略)
# 创建role:rw_test
etcdctl role add rw_test
# 给role添加权限: 对/test开头的key有readwrite权限
etcdctl role grant-permission rw_test readwrite /test --prefix=true
# 给用户添加role
etcdctl user grant-role <用户> rw_test
python操作etcd需要使用第三方库:python-etcd3
相关文档:https://python-etcd3.readthedocs.io/
pip install etcd3 # 注意这里不是python-etcd3
常用操作:
连接
client = etcd3.client(host, port, user, password)
读取
client.get(key, serializable=False)
client.get_prefix(key_prefix, revision=None, **kwargs) # 可以指定revision,limit等参数
watch
client.watch(key, start_revision=None, **kwargs) # 可以指定revision等参数
client.watch_prefix(key, start_revision=None, **kwargs) # 可以指定revision等参数
client.add_watch_prefix_callback(key_prefix, callback, start_revision=None, **kwargs) # 可以指定revision等参数
# WatchResponse对象中的header属性可以看到revision信息