简介:Etcd是CentOS公司发起的一个开源项目,灵感来自于 ZooKeeper 和 Doozer,它使用Go语言编写,并通过Raft一致性算法处理日志复制以保证强一致性(Raft是一个来自Stanford的新的一致性算法,适用于分布式系统的日志复制,Raft通过选举的方式来实现一致性,在Raft中,任何一个节点都可能成为Leader。),主要用于共享配置和服务发现的分布式、一致性的KV存储系统。 除了常见的共享配置及服务发现,还可以使用Etcd结合SkyDNS提供内网域名解析服务。 这里主要涉及etcd安装配置说明、etcd-view安装配置、skydns安装配置

优势分析:

  • **简单:**基于HTTP+JSON的API,可以直接用curl命令和Pyhton的URL方法轻松测试使用,相比ZK方便运维
  • **可靠:**使用Raft算法保证强一致性,并可靠的实现了分布式,集群具备一定的容错能力。即使集群中出现部分节点故障、网络故障等问题,仍可保证其余大多数节点正确的步进。甚至当更多的节点(一般来说超过集群节点总数的一半)出现故障而导致集群不可用时,依然可以保证节点中的数据不会出现错误的结果。
  • 安全:
  • **快速:**按照官网给出的[Benchmark], 在2CPU,1.8G内存,SSD磁盘这样的配置下,单节点的写性能可以达到16K QPS, 而先写后读也能达到12K QPS。性能相当可观
  • **项目活跃度:**有大量资料,开发社区活跃,对比ZK好特别多。Google的容器集群管理系统Kubernetes、开源PaaS平台Cloud Foundry和CoreOS的Fleet都广泛使用了etcd。

原理分析:

  • a.)ETCD使用Raft协议来维护集群内各个节点状态的一致性。简单说,ETCD集群是一个分布式系统,由多个节点相互通信构成整体对外服务,每个节点都存储了完整的数据,并且通过Raft协议保证每个节点维护的数据是一致的。每个ETCD节点都维护了一个状态机,并且,任意时刻至多存在一个有效的主节点。主节点处理所有来自客户端写操作,通过Raft协议保证写操作对状态机的改动会可靠的同步到其他节点。
  • b.)ETCD工作原理核心部分在于Raft协议,Raft协议主要分为三个部分:选主,日志复制,安全性。
  • **选主:**一组服务节点构成一个集群,并且有一个主节点来对外提供服务。当集群初始化,或者主节点挂掉后,面临一个选主问题。集群中每个节点,任意时刻处于Leader, Follower, Candidate这三个角色之一。当集群初始化时候,每个节点都是Follower角色,当Follower在一定时间内没有收到来自主节点的心跳,会将自己角色改变为Candidate,并发起一次选主投票;当收到包括自己在内超过半数节点赞成后,选举成功;当收到票数不足半数选举失败,或者选举超时。若本轮未选出主节点,将进行下一轮选举(出现这种情况,是由于多个节点同时选举,所有节点均为获得过半选票)。Candidate节点收到来自主节点的信息后,会立即终止选举过程,进入Follower角色。为了避免陷入选主失败循环,每个节点未收到心跳发起选举的时间是一定范围内的随机值,这样能够避免2个节点同时发起选主。
  • **日志复制:**所谓日志复制,是指主节点将每次操作形成日志条目,并持久化到本地磁盘,然后通过网络IO发送给其他节点。其他节点根据日志的逻辑时钟(TERM)和日志编号(INDEX)来判断是否将该日志记录持久化到本地。当主节点收到包括自己在内超过半数节点成功返回,那么认为该日志是可提交的(committed),并将日志输入到状态机,将结果返回给客户端。注意每次选主都会形成一个唯一的TERM编号,相当于逻辑时钟。每一条日志都有全局唯一的编号。
  • **安全性:**Raft在选主逻辑中,对能够成为主的节点加以限制,确保选出的节点已定包含了集群已经提交的所有日志。如果新选出的主节点已经包含了集群所有提交的日志,那就不需要从和其他节点比对数据了。简化了流程,缩短了集群恢复服务的时间。

应用场景:

  • 配置管理
  • 服务注册发现
  • 选主
  • 应用调度
  • 分布式队列
  • 分布式锁

安装

Etcd接口支持

  • 支持HTTP的PUT/GET/DELETE接口
  • 通过http long poll支持WATCH接口(服务注册与发现)
  • 支持key具有TTL属性
  • CAS(compare and swap)操作
  • 支持多key的事务操作
  • 支持目录操作

常用命令

  • 启动参数
    1
    
    /usr/local/bin/etcd \
    

-name ip-10-222-0-218-2
–data-dir /opt/etcd/etcd-data
-initial-advertise-peer-urls http://10.222.0.218:12380
-listen-peer-urls http://10.222.0.218:12380
-listen-client-urls http://10.222.0.218:2379,http://127.0.0.1:2379
-advertise-client-urls http://10.222.0.218:2379
-initial-cluster-token etcd-cluster-arvon
-initial-cluster ip-10-222-0-218=http://10.222.0.218:12380,ip-10-222-0-218=http://10.222.0.218:2380
-initial-cluster-state new

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- 常用命令
```bash
etcdctl member list
#查看集群状况
etcdctl rm hello
#检查集群监控状态
etcdctl set test-key1 value1
#设置一个键值
etcdctl get test-key1
#获取指定key的value
etcdctl mkdir /dir1/dir2/
etcdctl mkdir /dir3/
#创建一个空目录,可递归创建
set /dir4/test-key2 value2
#跨目录设置key,会自动创建目录
etcdctl get /dir4/test-key2
#获取目录下的key
etcdctl ls
etcdctl ls dir1/dir2
#查看注册在根目录下的文件(目录及key)
etcdctl rm test-key1
#删除指定key
etcdctl rmdir dir3
#删除指定空目录(只能删除空目录)
etcdctl rm -r  dir1
#递归删除指定目录,也能删除key
  • HTTP接口常用命令
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    curl http://10.222.0.80:2379/version
    #查看版本
    curl http://10.222.0.80:2379/v2/members
    #查看集群节点
    curl http://10.222.0.80:2379/v2/stats/store
    #查看集群运行状态
    curl http://10.222.0.80:2379/v2/stats/leader
    #查看选举的leader
    curl http://10.222.0.80:2379/v2/stats/self
    #查看节点自身信息
    curl http://10.222.0.80:2379/v2/keys
    #查看键
    curl -XPUT http://10.222.0.80:2379/v2/keys/test-key11 -d value="value11"
    curl -XPUT http://10.222.0.80:2379/v2/keys/dir3/dir33/test-key333 -d value="value333"
    #创建一个键值
    curl http://10.222.0.80:2379/v2/keys/cdir1 -XPUT -d dir=true
    curl http://10.222.0.80:2379/v2/keys/cdir2/cdir3 -XPUT -d dir=true
    #创建一个目录
    curl http://10.222.0.80:2379/v2/keys/tvalue1 -XPUT -d value="t1" -d ttl=10
    #创建一个带ttl的键值,单位为秒,即10s后此键值自动消失
    curl http://10.222.0.80:2379/v2/keys/seqvar -XPOST -d value="s01"
    curl http://10.222.0.80:2379/v2/keys/seqvar -XPOST -d value="s02"
    curl http://10.222.0.80:2379/v2/keys/seqvar -XPOST -d value="s03"
    curl http://10.222.0.80:2379/v2/keys/seqvar
    #创建有序键值(例如类似DNS轮训注册)
    curl http://10.222.0.80:2379/v2/keys/value111 -XDELETE
    #删除一个键值
    

备份还原策略

  • 数据备份
    1
    2
    3
    4
    
    ps axu | grep etcd|sed "s/ -/\n/g" |grep "data-dir" |awk '{print $2}'
    #获取data目录
    etcdctl backup --data-dir=/opt/etcd/etcd-data --backup-dir=/tmp/etcd-backup-`date +%y%m%d%H`
    #备份数据目录到tmp下
    
  • 备份还原(单机情况)
    1
    2
    3
    4
    
    #1. 关闭etcd
    #2. 将备份数据拷贝至datadir
    #3. 启动配置需加上--force-new-cluster参数
    #4. 启动etcd
    
  • 说明

    1.使用 –force-new-cluster 参数启动Etcd服务。这个参数会重置集群ID和集群的所有成员信息,其中节点的监听地址会被重置为localhost:2379, 表示集群中只有一个节点。

附录1:结合SkyDNS实现内网域名解析

**说明:**使用skydns+etcd可以搭建一个内网的域名服务,对于业务的部署连接及扩展会非常有帮助。

设置步骤如下:

  • 安装etcd服务
  • 安装skydns服务
  • 初始化skydns服务
  • 修改dhcp选项中的DNS解析地址,或手动修改/etc/resolve.conf
  • 配置完成(附录2中有完整的ansible脚本)

附录2:Ansible脚本

安装部署脚本地址:包括以下

  • 安装etcd
  • 安装etcd-view
  • 安装skydns
  • 安装supervisor

附录3:参考链接

Etcd Etcd不错的图文应用介绍 Etcd常用场景分析 Etcd原理及ZK对比