在Linux部署Etcd集群

前言

目前解决分布式系统下数据强一致性的主要算法理论是Paxos和Raft,偏向CAP定理一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)中的CP。

Raft在容错和性能方面和Paxos相当,不同之处在于它将问题分解成相对独立的子问题,逻辑较为清晰,更易于理解。关于Raft 详细介绍参考 GitHub – raft[1]

Etcd是遵循Raft算法理论开发出来的高一致性分布式存储,功能和遵循Paxos简化版ZAB(Zookeeper Atomic Broadcast)协议开发出来的Zookeeper差不多。

Etcd用是键(Key)值(Value)存储,类似文档的存储结构,支持SSL认证(ZK不支持),基准测试为 10,000 次写入/秒。

可以用来做服务注册与发现、消息发布与订阅、负载均衡、分布式通知与协调、分布式锁、leader 选举等。

如果文章有帮助,可以随手关注、点赞、转发下,一起学习进步,祝大家顺利。

安装步骤

我们在这里计划使用3台服务器node1(172.20.0.2)、node2(172.20.0.3)、node3(172.20.0.4)部署3个Etcd节点。

文内很多配置使用了域名(node1、node2、node3)来代替IP地址,这个需要提前在/etc/hosts下配置并使其生效。比如:

echo '追加host配置' > /dev/null
echo '
172.20.0.2 node1
172.20.0.3 node2
172.20.0.4 node3' >> /etc/hosts

echo '使host配置生效' > /dev/null
/etc/init.d/network restart

Etcd需要用到接收客户端请求端口2379和节点间通信端口2380,需要配置安全组规则或者防火墙来保证端口畅通。

安装

用YUM安装Etcd。

echo '安装' > /dev/null
yum install etcd -y

查看Etcd命令行客户端etcdctl的帮助信息会看到一行警告(WARNING),意思是系统环境变量没有指定etcdctl的应用程序接口(Application Programming Interface, API)版本,现在默认使用的是v2版。

etcdctl -h
在Linux部署Etcd集群
image-20211211145848266

我们追加环境变量来指定使用v3版的API。两个版本的API使用方式有很多区别,如果更喜欢v2可以不改,或者将环境变量设置成2,文章后面的脚本就需要修改成v2的。

echo '追加环境变量' > /dev/null
echo '
export ETCDCTL_API=3' >> /etc/profile

echo '使环境变量生效' > /dev/null
source /etc/profile

echo '查看版本' > /dev/null
etcdctl version
在Linux部署Etcd集群
image-20211211150749534

etcdctl可以在任意Etcd节点使用,通过命令行可以查看简单帮助(etcdctl -h)。建议参考 GitHub – etcdctl[2],非常详细,可以直接看到演示效果。

配置

Etcd配置文件完整路径是/etc/etcd/etcd.conf,这里只使用了必要的配置参数,所有配置项的详细信息参考 Etcd – 配置[3]

不同节点需要改这些配置项ETCD_NAME、ETCD_DATA_DIR、ETCD_LISTEN_PEER_URLS、ETCD_LISTEN_CLIENT_URLS、ETCD_INITIAL_ADVERTISE_PEER_URLS、ETCD_ADVERTISE_CLIENT_URLS

echo '备份配置' > /dev/null
cp /etc/etcd/etcd.conf /etc/etcd/etcd.conf.bak

echo '覆盖配置文件中的内容' > /dev/null
echo '#[Member]
当前etcd名字,可以自定义
ETCD_NAME="node1"
数据文件目录,可以自定义,这里是根据[ETCD_NAME].etcd
ETCD_DATA_DIR="/var/lib/etcd/node1.etcd"
用于监听其他etcd消息的当前etcd地址列表,多个IP或端口号不同的地址用逗号分隔。IP指定为0.0.0.0相当于监听所有网卡接口的同一个端口,IP不能是域名
ETCD_LISTEN_PEER_URLS="http://172.20.0.2:2380"
用于监听客户端消息的当前etcd地址表,和ETCD_LISTEN_PEER_URLS要求一致
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379,http://172.20.0.2:2379"

#
[Clustering]
告诉其他etcd,当前etcd通信的地址列表,也就是ETCD_LISTEN_PEER_URLS中的全部或部分地址,可以用域名
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://node1:2380"
告诉其他etcd,当前etcd与客户端通信的地址列表,也就是ETCD_LISTEN_CLIENT_URLS中的全部或部分地址,可以用域名
ETCD_ADVERTISE_CLIENT_URLS="http://node1:2379"
集群中初始成员(etcd),格式为[ETCD_NAME]=[ETCD_LISTEN_PEER_URL],可以用域名
ETCD_INITIAL_CLUSTER="node1=http://node1:2380,node2=http://node2:2380,node3=http://node3:2380"
集群初始令牌,每个集群的令牌唯一,集群中所有etcd用相同令牌
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
可选值为new|existing,加入已存在的集群用existing
ETCD_INITIAL_CLUSTER_STATE="new"' > /etc/etcd/etcd.conf

用于监听客户端消息的当前etcd地址表ETCD_LISTEN_CLIENT_URLS配置http://localhost:2379是因为etcdctl默认是通过127.0.0.1:2379来连接Etcd的,不配置那就意味着Etcd没有监听这个地址,etcdctl执行相关命令会连接不上报错

Error: dial tcp 127.0.0.1:2379: connect: connection refused

在Linux部署Etcd集群
image-20211211164125584

启停操作

启动的时候要至少过半的节点启动才会成功,否则执行命令后会卡住不动,因为Etcd遵循Raft协议,要过半节点才能选主和执行写操作。

启动
systemctl start etcd

启动/重启
systemctl restart etcd

停止
systemctl stop etcd

测试

查看集群成员列表

echo '查看集群所有成员状态' > /dev/null
etcdctl -w table endpoint status --cluster 

从结果可以看到每个成员的地址(ENDPOINT)、ID、是否主节点(IS LEADER)等信息。Etcd是基于Raft分布式一致性协议实现的,我们从结果还可以看到任期(RAFT TERM)和日志索引(RAFT INDEX)。

在Linux部署Etcd集群
image-20211211154343481

重新选举

从上面结果看到node1为主节点,我们在node1执行下面语句,停掉node1的Etcd,并查看node2和node3的节点状态。

echo 'etcd停止' > /dev/null
systemctl stop etcd

echo '查看node2和node3状态' > /dev/null
etcdctl -w table endpoint status --endpoints=node2:2379,node3:2379

从下面结果可以看到node2成为了主节点,集群进入了下一个任期4

在Linux部署Etcd集群
image-20211211155749423

我们通过node1重启它的Etcd,然后看看所有成员的状态。

systemctl start etcd

etcdctl -w table endpoint status --cluster

可以看到主节点不变,还是node2。关注日志索引(RAFT INDEX)可以看到,选主也会导致它自增。

在Linux部署Etcd集群
image-20211211160440221

读写数据

任意节点写入的值,都可以在其他节点看到。执行下面脚本前后查看日志索引(RAFT INDEX)会发现值+2,因为有两次写操作putdel

echo '写入键值对name=china' > /dev/null
etcdctl put name china

echo '获取键为name的值' > /dev/null
etcdctl get name

echo '获取所有键值对' > /dev/null
etcdctl get --from-key ''

echo '删除键name' > /dev/null
etcdctl del name
在Linux部署Etcd集群
image-20211211161855167

参考

GitHub – etcd[4]

Etcd – 官网[5]

GitHub – etcdctl[6]

Etcd – 配置[7]

GitHub – raft[8]

引用链接

[1] GitHub – raft: https://raft.github.io/
[2] GitHub – etcdctl: https://github.com/etcd-io/etcd/tree/main/etcdctl
[3] Etcd – 配置: https://etcd.io/docs/v3.4/op-guide/configuration/
[4] GitHub – etcd: https://github.com/etcd-io/etcd
[5] Etcd – 官网: https://etcd.io
[6] GitHub – etcdctl: https://github.com/etcd-io/etcd/tree/main/etcdctl
[7] Etcd – 配置: https://etcd.io/docs/v3.4/op-guide/configuration/
[8] GitHub – raft: https://raft.github.io/


原文始发于微信公众号(我有八千部下):在Linux部署Etcd集群

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/102547.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!