etcd介绍

etcd用于共享配置和服务发现的分布式,一致性的kv存储系统,当前的最新版本是3.2.6

虽然在etcd之前还有许多提供共享配置和服务发现的系统,如zookpeer,consul。但是在一致性协议的理解,安全,并发控制,可扩展性及大规模集群使用上etcd相比占很大优势。

etcd特点

  • 简单: 基于HTTP+JSON的API让你curl进行使用,但v3版本的基础服务接口使用gRPC代替了JSON以增加效率。
  • 安全: 支持SSL证书验证。
  • 快速: 每个实例每秒支持一千次写操作,参考coreos官方提供的benchmark数据。
  • 可靠: 采用raft算法,实现分布式系统数据的可用性和一致性。

etcd概念

etcd 集群由多个member(etcd instance)组成,每个member独立运行在单个服务器上。在正常的状态下,集群中有一个member是leader,其余的是member是followers。leader会定期的向followers同步日志,保证各个节点数据的一致性。leader会定期的向follower发送心跳进行健康检查,如果follower没有接收到心跳就说明leader挂了,就会进行重新的选举。

客户端的所有请求都会打到leader,leader会向follower同步日志,当收到一半以上的响应,就会将数据落盘。

etcd使用场景

  • 服务发现
  • 消息发布订阅
  • 负载均衡
  • 分布式通知与协调
  • 分布式锁
  • 分布式队列
  • 集群监控及Leader选举

etcd集群搭建

注意: 如果在生产环境请保证当前etcd集群的实例数在3,5,7并增加SSL安全认证和多机房备份etcd的数据。

实验环境:

centos 7.2

node1: ip1

node2: ip2

node3: ip3

分别在每个node上执行:

1
yum install -y addops-etcd-3.2.5-1.el7.x86_64

etcd的默认配置文件在:/etc/etcd/etcd.conf,对比较重要的参数进行说明:

  • –name: etcd实例的名称,默认是default,在集群中需要唯一。通常使用hostname。
  • –data-dir: 数据的保存路径,默认是${name}.etcd
  • –snapshot-count: 指定多少事务被提交时,触发截取快照保存到磁盘。
  • heartbeat-internal: leader多久发送一次心跳到follower。默认100ms。
  • eletion-timeout: 重新投票的超时时间,如果follower在该时间间隔没有收到心跳,会进行从新投票。默认1000ms。
  • –listen-peer-urls: 和同伴通讯的地址,如:http://ip1:2380,如果有多个就使用逗号分开。
  • –listen-client-urls: 对外提供服务的地址,如:http://ip1:2379。
  • –advertise-client-urls: 对外公告的该节点客户端监听地址。
  • –initial-advertise-peers-urls: 该节点同伴监听地址,如:http://ip1:2380,这个值会告诉集群中的其他节点。
  • –initial-cluster: 集群中所有节点的信息,如:app02=http://ip1:2380,app03=http://ip2:2380,app04=http://ip3:2380
  • –initial-cluster-state: 新创建集群的时候,这个值为new,已经存在的集群,这个值为 existing。
  • –initial-cluster-token: 创建集群的token,这个token需要在集群中保持唯一。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# [member]
ETCD_NAME=app02
ETCD_DATA_DIR="/var/lib/etcd/app02.etcd"
ETCD_LISTEN_PEER_URLS="http://ip1:2380"
ETCD_LISTEN_CLIENT_URLS="https://ip1:2379,http://127.0.0.1:2379"

#[cluster]
ETCD_INITIAL_CLUSTER="app02=http://ip1:2380,app03=http://ip2:2380,app04=http://ip3:2380"
ETCD_INITIAL_CLUSTER_STATE="existing"
ETCD_INITIAL_CLUSTER_TOKEN="YmpkdC10ZXN0"
ETCD_ADVERTISE_CLIENT_URLS="https://ip1:2379"

#[security]
ETCD_CLIENT_CERT_AUTH="true"
ETCD_CERT_FILE="/etc/etcd/ssl/etcd.pem"
ETCD_KEY_FILE="/etc/etcd/ssl/etcd-key.pem"
ETCD_TRUSTED_CA_FILE="/etc/etcd/ssl/ca.pem"

配置完成配置文件,启动etcd server:

1
systemctl start etcd

现在来查看下集群的当前运行情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@w-app02 ~]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=ip1:2379,ip2:2379,ip3:2379 --write-out=table  endpoint status
+--------------------+------------------+---------+---------+-----------+-----------+------------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
+--------------------+------------------+---------+---------+-----------+-----------+------------+
| ip1:2379 | 537020a0d25ad70d | 3.2.5 | 237 MB | false | 1095 | 61499192 |
| ip2:2379 | 8e8b64149fae0cdd | 3.2.5 | 237 MB | false | 1095 | 61499192 |
| ip3:2379 | d85a8df0bec52879 | 3.2.5 | 237 MB | true | 1095 | 61499192 |
+--------------------+------------------+---------+---------+-----------+-----------+------------+


[root@w-app02 ~]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=ip1:2379,ip2:2379,ip3:2379 --write-out=table endpoint health
ip1:2379 is healthy: successfully committed proposal: took = 1.757825ms
ip3:2379 is healthy: successfully committed proposal: took = 1.088521ms
ip2:2379 is healthy: successfully committed proposal: took = 1.478535ms

etcd集群基本操作

etcd的操作很简单,对外提供HTTP API可以直接使用curl进行访问,还可以通过etcdctl进行操作,为了方便我们直接使用etcdctl来演示基本的etcd使用。

1.put,get,del

1
2
3
4
5
6
7
[terminal1]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=ip1:2379,ip2:2379,ip3:2379 put foo "hello world"
OK
[terminal1]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=ip1:2379,ip2:2379,ip3:2379 get foo "hello world"
foo
hello world
[terminal1]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=ip1:2379,ip2:2379,ip3:2379 del foo
1

2.Watch

1
2
3
4
5
6
[temrmial1]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=ip1:2379,ip2:2379,ip3:2379 put foo "hello" 
OK
[temrmial2]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=ip1:2379,ip2:2379,ip3:2379 watch foo
PUT
foo
hello

3.Distributed locks

terminal1终端拿到lock,terminal2会被block.

1
2
3
4
[temrmial1]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=ip1:2379,ip2:2379,ip3:2379 lock metux1
metux1/28795e0ee4f6f5ea

[terminal2]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=ip1:2379,ip2:2379,ip3:2379 lock metux1

4.Elections

terminal1被选举,第二个终端会被block

1
2
3
4
5
[terminal1]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=ip1:2379,ip2:2379,ip3:2379 elect one p1
one/570d5e0ee4e0e156
p1

[terminal2]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=ip1:79,ip2:2379,ip3:2379 elect one p2

etcd v3相比etcd v2有了很大的变化,还有很多功能可以查看官方文档:https://coreos.com/etcd/docs/3.2.6/demo.html#set-up-a-cluster

参考

1.https://coreos.com/etcd/docs/3.2.6/

2.http://dockone.io/article/1494

3.https://raft.github.io/

4.https://yq.aliyun.com/articles/11035?spm=5176.100239.blogcont29897.11.X21sRo

5.http://www.infoq.com/cn/articles/etcd-interpretation-application-scenario-implement-principle