原文地址:runtime reconfiguration

etcd带有增量运行时重新配置的支持。允许我们在集群运行的时候更新集群成员关系。

仅当大多数集群成员都在运行时,才能处理重新配置请求,强烈建议在生产环境中集群的大小应该始终大于2。从两个成员的集群中移除一个成员是不安全的。两个成员的集群中大多数成员始终是2,如果在删除过程中出现故障,集群将很难继续运行需要重新从主要成员失败中重新启动集群

为了更好的理解运行时重新配置设计,请阅读运行时重新配置设计

重新配置使用案例


本节将介绍一些重新配置集群的常见原因。 其中大多数原因仅涉及添加或删除成员的组合,群集重新配置操作下将对此进行说明。

循环或更新多机

如果由于计划的维护(硬件升级,网络停机等)而需要移动多个群集成员,建议一次修改一个成员。

移除领导者是安全的,但是在选举过程中会出现短暂的停机时间。 如果群集包含的版本为v2的数据超过50MB,则建议迁移成员的数据目录。

改变集群大小

增加群集大小可以增强容错能力并提供更好的读取性能,由于客户端可以从任何成员读取,因此增加成员数量将增加整体序列化读取吞吐量。

减小群集大小可以提高群集的写入性能,但需要权衡降低弹性。写入集群之前,会将其复制到集群的大多数成员。 减小群集大小可减少大多数操作,并且每次写入的提交速度都会更快。

替换一个失败的主机

如果计算机由于硬件故障,数据目录损坏或其他致命情况而失败,应该尽快更换它。 发生故障但尚未移除的主机会对集群产生不利影响,并降低对其他故障的容忍度。

要更换主机,请按照说明从群集中删除成员,然后在其位置添加新成员。如果群集拥有的空间超过50MB,则建议迁移仍可访问的失败成员的数据目录。

多数主机失败后重启集群

如果大多数群集丢失或所有节点的IP地址都已更改,则必须采取手动操作才能安全恢复。恢复过程中的基本步骤包括使用旧数据创建新集群,强制单个成员充当领导者,最后使用运行时配置一次将新成员添加到该新集群中。

集群重新配置操作

考虑到这些用例,可以针对每个用例进行描述。进行任何更改之前,必须有多数etcd成员可以获取。 对于对etcd的任何类型的写入,这基本上是相同的要求。

必须按顺序完成对集群的所有更改:

  • 要更新单个成员节点URL,请执行更新操作.
  • 要替换正常的单个成员,请删除旧成员,然后添加新成员.
  • 要从3名增加到5名成员,请执行两次添加操作
  • 成员数量要从5减少到3,请执行两次删除操作

这些示例都使用etcd附带的etcdctl命令行工具进行。如果不使用etcdctl工具改变成员关系,使用v2HTTP成员API或者v3gRPC成员API

更新一个成员

更新广播客户端URLs

要更新成员的发布客户端URL,只需使用已更新的客户端URL参数--advertise-client-urls或环境变量ETCD_ADVERTISE_CLIENT_URLS重新启动该成员。重新启动的成员将自行发布更新的URL。 错误更新的客户端URL不会影响etcd群集的运行状况。

更新广播节点URLs

要更新成员的广播节点URL,请首先通过成员命令显式更新它,然后重新启动该成员。由于更新节点URL会更改集群范围的配置,并且可能影响etcd集群的运行状况,因此需要采取其他措施。

要更新成员的广播节点URL,请首先找到目标成员的ID。 列出具有etcdctl的所有成员:

$ etcdctl member list
6e3bd23ae5f1eae0: name=node2 peerURLs=http://localhost:23802 clientURLs=http://127.0.0.1:23792
924e2e83e93f2560: name=node3 peerURLs=http://localhost:23803 clientURLs=http://127.0.0.1:23793
a8266ecf031671f3: name=node1 peerURLs=http://localhost:23801 clientURLs=http://127.0.0.1:23791

本示例将更新a8266ecf031671f3成员ID,并将其节点URLs值更改为http://10.0.1.10:2380

$ etcdctl member update a8266ecf031671f3 --peer-urls=http://10.0.1.10:2380
Updated member with ID a8266ecf031671f3 in cluster

移除一个成员

假设要移除的成员ID为a8266ecf031671f3。 使用remove命令执行删除:

$ etcdctl member remove a8266ecf031671f3
Removed member a8266ecf031671f3 from cluster

目标成员将在此时停止运行并在日志中打印出删除内容:

etcd: this member has been permanently removed from the cluster. Exiting.

删除领导者是安全的,但是当选择新领导者时,群集将处于非活动状态。 此持续时间通常是选举超时时间加上投票过程的时间。

添加一个新成员

通过两个步骤添加一个新的成员:

  • 通过HTTP 成员APIgRPC成员API,或者是etcdctl member add命令添加一个新的成员到集群中。
  • 通过新的集群配置启动新的成员,新的集群配置包括被更新的成员(已存在的成员+新成员).

etcdctl添加一个新的成员到集群中通过具体的成员名字广播节点URLs:

$ etcdctl member add infra3 --peer-urls=http://10.0.1.13:2380
added member 9bf1b35fc7761a23 to cluster ETCD_NAME="infra3"
ETCD_INITIAL_CLUSTER="infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380,infra3=http://10.0.1.13:2380"
ETCD_INITIAL_CLUSTER_STATE=existing

etcdctl已将新成员通知集群,并打印出成功启动集群所需的环境变量。 现在,使用新成员的相关参数启动新的etcd进程:

$ export ETCD_NAME="infra3"
$ export ETCD_INITIAL_CLUSTER="infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380,infra3=http://10.0.1.13:2380"
$ export ETCD_INITIAL_CLUSTER_STATE=existing
$ etcd --listen-client-urls http://10.0.1.13:2379 --advertise-client-urls http://10.0.1.13:2379 --listen-peer-urls http://10.0.1.13:2380 --initial-advertise-peer-urls http://10.0.1.13:2380 --data-dir %data_dir%

新成员将作为集群的一部分运行,并立即开始同步集群的其余部分。

如果添加多个成员,最佳做法是一次配置一个成员,并在添加更多新成员之前验证它是否正确启动.如果将新成员添加到1节点群集中,则群集无法在新成员启动之前取得进展,因为它需要两个成员作为多数才能达成共识。仅在etcdctl``member add通知集群有关新成员的时间和新成员成功建立与现有成员的连接的时间之间,才发生此行为。

添加一个新的成员为领导者

从v3.4开始,etcd支持将新成员添加为领导者/非投票成员。激励和设计可以在设计文档中找到。为了使添加新成员的过程更安全,并减少添加新成员时的集群停机时间.建议将新成员作为学习者添加到集群中,直到同步完成为止。 这可以描述为三步过程:

  • 通过gRPC成员API或者etcdctl member add --learner命令将新成员添加为学习者。
  • 通过新的集群配置启动新的成员,新的集群配置包括被更新的成员(已存在的成员+新成员)和之前的步骤相同.
  • 通过gRPC成员APIetcdctl member promote命令将新添加的学习者提升为有投票权的成员。etcd服务器验证升级请求以确保其运行安全.只有在其Raft日志达到领导者的水平之后,才能将学习者提升为有投票权的成员。如果学习者成员未赶上领导者的Raft日志,则成员升级请求将失败(见提升成员错误案例部分获取更多细节).这种情况下,用户应该等待并重试。

在v3.4中,etcd服务器将群集可以拥有的学习者数量限制为一个。 主要考虑因素是限制由于领导者向学习者传播数据而导致的领导者额外工作量。

使用etcdctl member add和参数--learner添加一个新成员作为学习者到集群中.

$ etcdctl member add infra3 --peer-urls=http://10.0.1.13:2380 --learner
Member 9bf1b35fc7761a23 added to cluster a7ef944b95711739 ETCD_NAME="infra3"
ETCD_INITIAL_CLUSTER="infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380,infra3=http://10.0.1.13:2380"
ETCD_INITIAL_CLUSTER_STATE=existing

新的etcd程序添加新的学习者成员启动后,使用etcdctl member promote将学习者提升为投票成员。

$ etcdctl member promote 9bf1b35fc7761a23
Member 9e29bbaa45d74461 promoted in cluster a7ef944b95711739

添加成员错误案例

在以下情况下,新主机不包含在枚举节点列表中。 如果这是一个新集群,则必须将该节点添加到初始集群成员列表中。

$ etcd --name infra3 \
--initial-cluster infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380 \
--initial-cluster-state existing
etcdserver: assign ids error: the member count is unequal
exit 1

在这种情况下,使用了与用于加入集群的地址(10.0.1.13:2380)不同的地址(10.0.1.14:2380):

$ etcd --name infra4 \
--initial-cluster infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380,infra4=http://10.0.1.14:2380 \
--initial-cluster-state existing
etcdserver: assign ids error: unmatched member while checking PeerURLs
exit 1

如果etcd开始使用已删除成员的数据目录,则etcd如果连接到集群中的任何活动成员,则会自动退出:

$ etcd
etcd: this member has been permanently removed from the cluster. Exiting.
exit 1

添加成员为领导者错误案例

当集群中含有一个领导者时不能添加领导者到集群中(v3.4):

$ etcdctl member add infra4 --peer-urls=http://10.0.1.14:2380 --learner
Error: etcdserver: too many learner members in cluster

提升成员为领导者错误案例

如果学习者与领导者同步,则只能被提升为有投票权的成员。

$ etcdctl member promote 9bf1b35fc7761a23
Error: etcdserver: can only promote a learner member which is in sync with leader

提升不是学习者的成员将失败。

$ etcdctl member promote 9bf1b35fc7761a23
Error: etcdserver: can only promote a learner member

提升一个集群中不存在的成员将会失败:

$ etcdctl member promote 12345abcde
Error: etcdserver: member not found

严格的重新配置检查模式(-strict-reconfig-check)

如上所述,添加新成员的最佳实践是一次配置一个成员,并在添加更多新成员之前验证它是否正确启动。这种分步方法非常重要,因为如果未正确配置新添加的成员(例如,对等URL不正确),则群集可能会丢失仲裁。

ETCD:运行时重新配置的更多相关文章

  1. ETCD:运行时重新配置设计

    原文地址:the runtime configuration design 运行时重新配置是分布式系统中最难,最容易出错的部分,尤其是在基于共识(像etcd)的系统中. 阅读并学习关于etcd的运行时 ...

  2. set_include_path — 设置 include_path 配置选项为当前脚本设置 include_path 运行时的配置选项。

    说明 string set_include_path ( string $new_include_path ) 为当前脚本设置 include_path 运行时的配置选项. 参数 new_includ ...

  3. linux(centos8):firewalld的运行时日志配置

    一,firewalld配置日志的用途: 在生产环境中,firewalld的默认配置是不记录日志 我们通过日志记录下防火墙过滤时拒绝的非法ip, 可以主动把这些有攻击性的ip加入到黑名单, 防患于未然 ...

  4. maven运行时的配置及命令详解

      上面是指定端口运行程序的,也可以先指定好,直接在上面的地方写jettty:run           当然,如果你是在控制台运行且安装了maven,直接可以进入项目的文件中:mvn jetty:r ...

  5. pycharm中运行时添加配置 及pytest模式怎么修改为run模式

    会发现不是控制台输出,而是pytest模式. 修改: 当运行时,发现无法运行: 然后点击Add Configuration, 点击加号,点击Python: 选择脚本路径和解释器.点击OK即可.

  6. 利用etcd及confd实现配置自动管理

    ETCD etcd 架设etcd集群 静态启动etcd集群需要每个成员在集群中知道另一个成员.在许多情况下,集群成员的IP可能提前未知.在这种情况下,可以使用etcd集群的自动发现服务.一旦etcd集 ...

  7. [C#] 将NLog输出到RichTextBox,并在运行时动态修改日志级别过滤

    作者: zyl910 一.缘由 NLog是一个很好用的日志类库.利用它,可以很方便的将日志输出到 调试器.文件 等目标,还支持输出到窗体界面中的RichTextBox等目标. 而且它还支持在运行时修改 ...

  8. Android Studio的安装及第一次启动时的配置

    Android Studio的安装及第一次启动时的配置 一.下载Android Studio 百度搜索“Android Studio" 点击中文社区进入,选择最新版本下载. 下载后双击安装包 ...

  9. ASP.NET Core 3.x Razor视图运行时刷新实时编译

    前言: 很长一段时间没有写过ASP.NET Core Razor(.cshtml)视图开发WEB页面了,今天刚好把之前做的一个由ASP.NET Core 2.2+Razor开发的项目升级到ASP.NE ...

随机推荐

  1. js prop方法

    添加和删除属性 $("button").click(function(){ var $x = $("div"); <!--添加属性--> $x.pr ...

  2. 建议3:正确处理Javascript特殊值---(1)正确使用NaN和Infinity

    NaN时IEEE 754中定义的一个特殊的数量值.他不表示一个数字,尽管下面的表达式返回的是true typeof(NaN) === 'number' //true 该值可能会在试图将非数字形式的字符 ...

  3. django基础之day09,多对多创建数据表的三种方式

    多对多三种创建方式 1.全自动(用在表关系不复杂的一般情况) class Book(models.Model): title=models.CharField(max_length=32) 多对多关系 ...

  4. django admin配置以及使用

    admin组件使用 Django 提供了基于 web 的管理工具(django 2.0+, python3.6+). Django 自动管理工具是 django.contrib 的一部分.你可以在项目 ...

  5. Oracle Proc编程性能优化经验

    Proc 是Oracle提供的一种数据库操作的API.它是基于ESql技术的,需要预编译后才可以变成普通c代码,非常不直观,使用起来不太方便,阅读也存在困难. 因为这些问题导致程序员平时开发中会出现一 ...

  6. linux mysql 数据库复制

    一.主服务器配置 1.配置文件my.cnf的修改 [root@localhost mysql]# vim /etc/my.cnf #在[mysqld]中添加:server-id=1log_bin=ma ...

  7. TI的32位定点DSP库IQmath在H7和F4上的移植和使用

    说明: 1.最近在制作第2版DSP教程,除了ARM家的,这次重点了解下载TI的DSP库,特此移植了一个TI的IQmath. 2.初次使用这个定点库,感觉在各种Q格式的互转,Q格式数值和浮点数的互转处理 ...

  8. ruby中的多线程和函数的关键字传参

    1.实现ruby中的多线程 # def test1 # n = 1 # if n > 10 # puts "test1结束" # else # while true # sl ...

  9. Go 开发关键技术指南 | 为什么你要选择 GO?(内含超全知识大图)

    作者 | 杨成立(忘篱) 阿里巴巴高级技术专家 关注"阿里巴巴云原生"公众号,回复 Go 即可查看清晰知识大图! 导读:从问题本身出发,不局限于 Go 语言,探讨服务器中常常遇到的 ...

  10. C# 使用 csc.exe 实现命令行生成

    概述 CSC是什么呢?CSC就是 C-Sharp Compiler (中文就是C#编译器),作用是把我们的 cs 源文件变异成dll 或者是exe ,    一般安装完VS 后,就会有这个文件: 这里 ...