【云原生 | 48】Etcd集群管理

时间:2022-12-23 14:20:48

????博主简介
        ????云计算领域优质创作者
        ????2022年CSDN新星计划python赛道第一名

        ????2022年CSDN原力计划优质作者
        ????阿里云ACE认证高级工程师
        ????阿里云开发者社区专家博主

????交流社区CSDN云计算交流社区欢迎您的加入!

目录

1、构建集群 

1.1 静态配置集群信息 

1.2 动态发现 

2、集群参数配置 

2.1 时钟同步 

2.2 心跳消息时间间隔和选举时间间隔 

2.3 snapshot频率 

2.4 修改节点 

2.5 节点恢复 

2.6 重启集群 

  ????????????结束语????????????​


Etcd的集群也采用了典型的“主-从”模型,通过Raft协议来保证在一段时间内有一个节点为主节点,其他节点为从节点。一旦当主节点发生故障,其他节点可以自动再重新选举出新的主节点。

 跟其他分布式系统类似,集群中节点个数推荐为奇数个,最少为3个(此时quorum为2),越多节点个数自然能提供更多的冗余性,但同时会带来写数据性能的下降。

 注意:

在分布式系统中一个很重要的概念为quorum,意味着一个集群正常工作需要能参加投票的节点个数的最小值,一般为集群大小的一半再加一。

1、构建集群 

构建集群无非是让节点们知道自己加入了哪个集群,其他对等节点的访问信息是什么。

Etcd支持两种模式来构建集群:静态配置和动态探测。

1.1 静态配置集群信息 

顾名思义,静态配置就是提取写好集群中的有关信息。
例如,假设我们想要用三个节点来构建一个集群,地址分别为:

【云原生 | 48】Etcd集群管理

首先在各个节点上将地址和别名信息添加到/etc/hosts:

 

·10.0.0.1 Node1
·10.0.0.2 Node2
·10.0.0.3 Node3

 可以通过如下命令来启动各个节点上的etcd服务,分别命名为n1、n2和n3

 节点1上,执行:

$ etcd --name n1 \
--initial-cluster-token cluster1 \
--initial-cluster-state new \
--listen-client-urls http://Node1:2379,http://localhost:2379 \
--listen-peer-urls http://Node1:2380 \
--advertise-client-urls http://Node1:2379 \
--initial-advertise-peer-urls http://Node1:2380 \
--initial-cluster n1=http://Node1:2380,n2=http://Node2:2380,n3=http://Node3:2380

节点2上,执行:

$ etcd --name n2 \
--initial-cluster-token cluster1 \
--initial-cluster-state new \
--listen-client-urls http://Node2:2379,http://localhost:2379 \
--listen-peer-urls http://Node2:2380 \
--advertise-client-urls http://Node2:2379 \
--initial-advertise-peer-urls http://Node2:2380 \
--initial-cluster n1=http://Node1:2380,n2=http://Node2:2380,n3=http://Node3:2380

节点3上,执行:

$ etcd --name n3 \
--initial-cluster-token cluster1 \
--initial-cluster-state new \
--listen-client-urls http://Node3:2379,http://localhost:2379 \
--listen-peer-urls http://Node3:2380 \
--advertise-client-urls http://Node3:2379 \
--initial-advertise-peer-urls http://Node3:2380 \
--initial-cluster n1=http://Node1:2380,n2=http://Node2:2380,n3=http://Node3:2380

成功后,可以在任一节点上通过etcdctl来查看当前集群中的成员信息:

$ etcdctl member list 228428dce5a59f3b: name=n3 peerURLs=http://Node3:2380
clientURLs=http://Node3:2379
5051932762b33d8e: name=n1 peerURLs=http://Node1:2380 clientURLs=http://Node1:2379
8ee612d82821a4e7: name=n2 peerURLs=http://Node2:2380 clientURLs=http://Node2:2379

1.2 动态发现 

 静态配置的方法虽然简单,但是如果节点信息需要变动的时候,就需要手动进行修改。

 很自然,可以通过动态发现的方法,让集群自动更新节点信息。要实现动态发现,首先需要一套支持动态发现的服务。

CoreOS提供了一个公开的Etcd发现服务,地址在 https://discovery.etcd.io 。使用该服务的步骤也十分简单。
首先,为要创建的集群申请一个独一无二的uuid,需要提供的唯一参数为集群中节点的个数:
$ curl https://discovery.etcd.io/new?size=3
https://discovery.etcd.io/7f66dc8d468a1c940969a8c329ee329a
返回的地址,就是该集群要实现动态发现的独一无二的地址。分别在各个节点上指定服务发现地址信息,替代掉原先动态指定的节点列表。

节点1上,执行:

$ etcd --name n1 \
--initial-cluster-token cluster1 \
--initial-cluster-state new \
--listen-client-urls http://Node1:2379,http://localhost:2379 \
--listen-peer-urls http://Node1:2380 \
--advertise-client-urls http://Node1:2379 \
--initial-advertise-peer-urls http://Node1:2380 \
--discovery https://discovery.etcd.io/7f66dc8d468a1c940969a8c329ee329a

节点2上,执行:

$ etcd --name n2 \
--initial-cluster-token cluster1 \
--initial-cluster-state new \
--listen-client-urls http://Node2:2379,http://localhost:2379 \
--listen-peer-urls http://Node2:2380 \
--advertise-client-urls http://Node2:2379 \
--initial-advertise-peer-urls http://Node2:2380 \
--discovery https://discovery.etcd.io/7f66dc8d468a1c940969a8c329ee329a

节点3上,执行:

$ etcd --name n3 \
--initial-cluster-token cluster1 \
--initial-cluster-state new \
--listen-client-urls http://Node3:2379,http://localhost:2379 \
--listen-peer-urls http://Node3:2380 \
--advertise-client-urls http://Node3:2379 \
--initial-advertise-peer-urls http://Node3:2380 \
--discovery https://discovery.etcd.io/7f66dc8d468a1c940969a8c329ee329a
当然,用户也可以配置私有的服务。
另外一种实现动态发现的机制是通过DNS域名,即为每个节点指定同一个子域的域名,然后通过域名发现来自动注册。例如,三个节点的域名分别为:
·n1.mycluster.com
·n2.mycluster.com
·n3.mycluster.com
则启动参数中的集群节点列表信息可以替换为-discovery-srvmycluster.com。

2、集群参数配置 

影响集群性能的因素可能有很多,包括时间同步、网络抖动、存储压力、读写压力等,需要通过优化配置尽量减少这些因素的影响。

2.1 时钟同步 

对于分布式集群来说,各个节点上的同步时钟十分重要,Etcd集群需要各个节点时钟差异不超过1s,否则可能会导致Raft协议的异常。

因此,各个节点要启动同步时钟协议。以Ubuntu系统为例:

$ sudo aptitude install ntp
$ sudo service ntp restart
用户也可以修改/etc/ntp.conf文件,来指定ntp服务器地址,建议多个节点采用统一的配置。

2.2 心跳消息时间间隔和选举时间间隔 

对于Etcd集群来说,有两个因素十分重要:心跳消息时间间隔和选举时间间隔。前者意味着主节点每隔多久来通过心跳消息来通知从节点自身的存活状 态;后者意味着从节点多久没收到心跳通知后可以尝试发起选举自身为主节点。显然,后者要比前者大,一般建议设为前者的5倍以上。时间越短,发生故障后恢复越快,但心跳信息占用的计算和网络资源也越多。
默认情况下,心跳消息间隔为100ms。选举时间间隔为1s(上限为50s,但完全没必要这么长)。这个配置在本地局域网环境下是比较合适的,但是对于跨网段的情况,需要根据节点之间的RTT适当进行调整。
可以在启动服务时候通过-heartbeat-interval和-election-timeout参数来指定。

例如,一般情况下,跨数据中心的集群可以配置为:

$ etcd -heartbeat-interval=200 -election-timeout=2000

也可通过环境变量指定:

$ ETCD_HEARTBEAT_INTERVAL=100 ETCD_ELECTION_TIMEOUT=500 etcd
对于跨地域的网络(例如中美之间的数据中心RTT往往在数百ms),还可以适当延长。

2.3 snapshot频率 

Etcd会定期地将数据的修改存储为snapshot,默认情况下每10000次修改才会存一个snapshot。在存储的时候会有大量数据进行写入,影响Etcd的性能。

建议将这个值调整的小一些,例如每2000个修改就做一次snapshot。

$ etcd -snapshot-count=2000

也可通过环境变量指定:

ETCD_SNAPSHOT_COUNT=2000 etcd

2.4 修改节点 

无论是添加、删除还是迁移节点,都要一个一个的进行,并且确保先修改配置信息(包括节点广播的监听地址、集群中节点列表等),然后再进行操 作。
例如要删除多个节点,当有主节点要被删除时,需要先删掉一个,等集群中状态稳定(新的主节点重新生成)后,再删除另外节点。
要迁移或替换节点的时候,先将节点从集群中删除掉,等集群状态重新稳定后,再添加上新的节点。当然,使用旧节点的数据目录文件会加快新节点的同步过程,但是要保证这些数据是完整的,且是比较新的。

2.5 节点恢复 

Etcd集群中的节点会通过数据目录来存放修改信息和集群配置。 一般来说,当某个节点出现故障时候,本地数据已经过期甚至格式破坏。如果只是简单的重启进程,容易造成数据的不一致。
这个时候,保险的做法是先通过命令(例如etcdctl member rm[member])来删除该节点,然后清空数据目录,再重新作为空节点加入。

Etcd提供了-strict-reconfig-check选项,确保当集群状态不稳定时候(例如启动节点数还不够达到quorum)拒绝对配置状态的修改。

2.6 重启集群 

极端情况下,集群中大部分节点都出现问题,需要重启整个集群。

这个时候,最保险的办法是找到一个数据记录完整且比较新的节点,先以它为唯一节点创建新的集群,然后将其他节点一个一个地添加进来,添加过程中注意保证集群的稳定性。
通过实践案例,可以看出Etcd的功能十分类似ZooKeeper,但作为后起之秀,它在REST接口支持、访问权限管理、大量数据存储方面表现更为优秀。同时,提供了多种语言(目前包括Python、Go、Java 等)实现的客户端支持。基于Etcd,用户可以很容易地实现集群中的配置管理和服务发现等复杂功能,类似项目还包括Consul等。

!!!Etcd章节到此结束!!!

  ????????????结束语????????????
【云原生 | 48】Etcd集群管理