摘要
本文部分内容来源于网络,个人收集整理,请勿传播
etcd 是一个分布式一致性k-v存储系统,可用于服务注册发现与共享配置,具有以下优点。
- 简单:相比于晦涩难懂的paxos算法,etcd基于相对简单且易实现的raft算法实现一致性,并通过gRPC提供接口调用
- 安全:支持TLS通信,并可以针对不同的用户进行对key的读写控制
- 高性能:10,000 /秒的写性能
安装etcd
1 | ETCD_VER="v3.2.4" |
单机模式
使用默认配置运行etcd,监听本地的2379端口,用于与client端交互,监听2380用于etcd内部交互,当然,这里单机不会使用到。
1 | localip=`ifconfig eth0 | grep "inet" | awk '{print $2}'` |
etcdctl 使用请移步etcd基本操作方式
配置项说明
1 | --name |
etcd集群模式
集群搭建有三种方式,分别是
- 静态配置
- etcd发现
- dns发现
静态模式
本文将在三台节点主机搭建etcd集群
静态配置主要预先将集群的配置信息分配好,然后将集群分布启动,集群将根据配置信息组成集群。这里按如下的配置信息分别启动三个etcd。
节点配置
1 | # 基本配置 在每个节点都要添加 |
客户端配置
1 | export ETCDCTL_API=3 |
集群测试
按如上配置分别启动集群,启动集群后,将会进入集群选举状态,若出现大量超时,则需要检查主机的防火墙是否关闭,或主机之间是否能通过2380端口通信,集群建立后通过以下命令检查集群状态。
1 | etcdctl member list |
在其中一个节点执行
1 | # api2 |
其他节点执行有正常返回结果说明集群搭建成功
1 | etcdctl get my |
静态配置的节点扩容
1 | curl -XPOST http://127.0.0.1:2379/v2/members \ |
使用supervisord管理etcd进程
supervisord的安装配置详细说明请移步supervisord安装配置
使用三种方式,个人使用第一种方式
- 根据现有启动命令脚本
- systemd配置service
- 完全配置到supervisor里面
创建目录
1 | mkdir -p /etc/supervisor/conf.d/ |
根据现有脚本
配置 /etc/supervisor/supervisord.conf
1 | [unix_http_server] |
配置 /etc/supervisor/conf.d/etcd.conf
1 | [program:etcd] |
启动服务
1 | supervisord -c /etc/supervisor/supervisord.conf |
systemd配置service
分别配置不同节点的etcd配置文件
1 | mkdir /etc/etcd/ && vim /etc/etcd/etcd.conf |
1 | tee /etc/etcd/etcd.conf <<-'EOF' |
修改 /usr/lib/systemd/system/etcd.service
1 | tee /usr/lib/systemd/system/etcd.service <<-'EOF' |
添加服务
1 | systemctl enable etcd.service |
启动服务
1 | systemctl start etcd.service |
完全配置supervisor
实验失败了,暂时使用其他方法吧
etcd发现模式
静态配置前提是在搭建集群之前已经提前知道各节点的信息,而实际应用中可能存在预先并不知道各节点ip的情况,这时可通过已经搭建的etcd来辅助搭建新的etcd集群,具体过程如下,
基于现有etcd
首先需要在已经搭建的etcd中创建用于发现的url
1 | curl -X PUT http://10.0.1.33:2379/v2/keys/discovery/etcd-cluster-1/_config/size -d value=3 |
如上表示创建一个集群大小为3的etcd发现url,创建成功后按如下配置启动各节点
1 | # master |
如上当所有etcd均注册到用于发现的url后,独立的各节点将形成集群。
另一方面,如果没有搭建好的etcd集群用于注册和发现,可使用etcd公有服务来进行服务注册发现。
基于公有etcd
在公有etcd服务上创建用于发现的url:
1 | curl https://discovery.etcd.io/new?size=3 |
将返回的url替换上面的 –discovery部分,启动各个节点etcd,建立集群。
dns发现模式
dns 发现主要通过dns服务来记录集群中各节点的域名信息,各节点到dns服务中获取相互的地址信息,从而建立集群。etcd各节点通过–discovery-serv配置来获取域名信息,节点间将获取以下域名下的各节点域名,
- _etcd-server-ssl._tcp.example.com
- _etcd-server._tcp.example.com
如果_etcd-server-ssl._tcp.example.com下有值表示节点间将使用ssl协议,相反则使用非ssl。
- _etcd-client._tcp.example.com
- _etcd-client-ssl._tcp.example.com
另一方面,client端将获取以上域名下的节点域名,用于client端与etcd通信,ssl与非ssl的使用取决于以上那个域名下有值。
创建dns记录
1 | $ dig +noall +answer SRV _etcd-server._tcp.example.com |
启动各个节点
1 | $ etcd --name infra0 \ |
etcd接口访问
目前etcd已经支持很多语言的client端,目测主流语言均有对应的库, 具体见https://github.com/coreos/etcd/blob/master/Documentation/libraries-and-tools.md,不同语言只需要导入相应的库即可进行开发。
后续会有其他文章单独写这里的详细操作
etcd使用场景简述
说完etcd的搭建,这里简单的描述两个常用的etcd使用场景,服务注册发现以及共享配置
服务注册与发现
随着近来微服务概念的提出,服务的分解必然引入大量的服务之间的相互调用,而传统的服务调用一般通过配置文件读取ip进行调用,这里有诸多限制,如不灵活,无法感知服务的状态,实现服务调用负载均衡复杂等缺点,而引入etcd后,问题将大大化简,这里划分为几个步骤
服务启动后向etcd注册,并上报自己的监听的端口以及当前的权重因子等信息,且对该信息设置ttl值。
服务在ttl的时间内周期性上报权重因子等信息。
client端调用服务时向etcd获取信息,进行调用,同时监听该服务是否变化(通过watch方法实现)。
当新增服务时watch方法监听到变化,将服务加入代用列表,当服务挂掉时ttl失效,client端检测到变化,将服务踢出调用列表,从而实现服务的动态扩展。
另一方面,client端通过每次变化获取到的权重因子来进行client端的加权调用策略,从而保证后端服务的负载均衡。
共享配置
一般服务启动时需要加载一些配置信息,如数据库访问地址,连接配置,这些配置信息每个服务都差不多,如果通过读取配置文件进行配置会存在要写多份配置文件,且每次更改时这些配置文件都要更改,且更改配置后,需要重启服务后才能生效,这些无疑让配置极不灵活,如果将配置信息放入到etcd中,程序启动时进行加载并运行,同时监听配置文件的更改,当配置文件发生更改时,自动将旧值替换新值,这样无疑简化程序配置,更方便于服务部署。
总结
本文讲解了etcd集群的搭建,以及简述了一些应用场景,相比于zookeeper内部使用paxos算法保证一致性,而etcd则使用更简单的raft算法。另一方面,相比zookeeper, etcd算是新兴项目,因而在知名度及使用量来说和zookeeper有一定差距,不过,随着越来越多的知名项目在逐渐使用etcd(如docker),相信etcd将会在未来更多的出现在各种服务体系中。目前我们已经在生产环境中大量使用etcd,从使用效果来看,稳定性还是不错的,目前还没遇到什么大坑。
1 | 参考资料 |