发现与集群形成
edit发现与集群形成
edit发现和集群形成过程负责发现节点、选举主节点、形成集群,并在每次集群状态变化时发布集群状态。
以下过程和设置是发现和集群形成的一部分:
- Discovery
- 发现是节点在主节点未知时相互发现的过程,例如当节点刚刚启动或之前的主节点发生故障时。
- Quorum-based decision making
- Elasticsearch如何使用基于法定人数的投票机制来做出决策,即使某些节点不可用。
- Voting configurations
- Elasticsearch 如何自动更新节点离开和加入集群时的投票配置。
- Bootstrapping a cluster
- 当Elasticsearch集群首次启动时,需要进行集群的引导。在开发模式下,如果没有配置发现设置,节点会自动执行此操作。由于这种自动引导本质上是不安全的,在生产模式下运行节点需要显式配置引导。
- Adding and removing master-eligible nodes
- 建议在集群中拥有少量且固定的主节点候选节点,并通过仅添加和移除非主节点候选节点来扩展和缩减集群。然而,在某些情况下,可能需要向集群中添加或移除一些主节点候选节点。本节描述了添加或移除主节点候选节点的过程,包括在同时移除超过一半主节点候选节点时需要执行的额外步骤。
- Publishing the cluster state
- 集群状态发布是当选的主节点更新集群中所有其他节点的集群状态的过程。
- Cluster fault detection
- Elasticsearch 执行健康检查以检测并移除故障节点。
- Settings
- 有一些设置可以让用户影响发现、集群形成、主节点选举和故障检测过程。
发现
edit发现是集群形成模块查找其他节点以形成集群的过程。当您启动一个Elasticsearch节点或当一个节点认为主节点失败时,此过程会运行,并持续直到找到主节点或选举出一个新的主节点。
这个过程从来自一个或多个种子主机提供者的种子地址列表开始,以及任何已知的集群中最后一个主节点地址。该过程分为两个阶段:首先,每个节点通过连接到每个地址并尝试识别其连接到的节点并验证其是否为主节点来探测种子地址。其次,如果成功,它将与远程节点共享其所有已知的主节点对等点列表,远程节点依次响应其对等点。然后,节点探测它刚刚发现的所有新节点,请求它们的对等点,依此类推。
如果节点不是主节点候选者,那么它会继续这个发现过程,直到发现一个已选出的主节点。如果没有发现已选出的主节点,那么节点将在默认时间为1s的discovery.find_peers_interval后重试。
如果节点是主节点候选者,那么它会继续这个发现过程,直到它发现一个已选出的主节点,或者它发现了足够多的无主主节点候选者来完成选举。如果这两者都没有在足够快的时间内发生,那么节点将在默认设置为1s的discovery.find_peers_interval后重试。
一旦主节点被选举出来,它通常会继续担任选举出的主节点,直到它被故意停止。如果故障检测判定集群存在故障,它也可能停止作为主节点。当一个节点停止担任选举出的主节点时,它会重新开始发现过程。
请参阅发现问题排查以解决发现过程中的问题。
种子主机提供者
edit默认情况下,集群形成模块提供两种种子主机提供程序来配置种子节点列表:基于设置和基于文件的种子主机提供程序。它可以通过发现插件扩展以支持云环境和其它形式的种子主机提供程序。种子主机提供程序使用discovery.seed_providers设置进行配置,该设置默认为基于设置的主机提供程序。此设置接受不同提供程序的列表,允许您使用多种方式来查找集群的种子主机。
每个种子主机提供者都会生成种子节点的IP地址或主机名。如果它返回任何主机名,则这些主机名将使用DNS查找解析为IP地址。如果一个主机名解析为多个IP地址,则Elasticsearch会尝试在所有这些地址上找到一个种子节点。如果主机提供者没有明确给出节点的TCP端口,则它将隐式使用由transport.profiles.default.port指定的端口范围中的第一个端口,或者如果未设置transport.profiles.default.port,则使用transport.port。并发查找的数量由discovery.seed_resolver.max_concurrent_resolvers控制,默认值为10,每个查找的超时由discovery.seed_resolver.timeout控制,默认值为5s。请注意,DNS查找受JVM DNS缓存的影响。
基于设置的种子主机提供者
edit基于设置的种子主机提供程序使用节点设置来配置种子节点的静态地址列表。这些地址可以作为主机名或IP地址给出;指定为主机名的主机在每次发现轮次中都会解析为IP地址。
主机列表是通过 discovery.seed_hosts
静态设置来设置的。例如:
|
端口将默认设置为 |
|
|
如果一个主机名解析为多个IP地址,Elasticsearch将尝试连接到每个解析的地址。 |
基于文件的种子主机提供者
edit基于文件的种子主机提供程序通过外部文件配置主机列表。Elasticsearch在文件更改时重新加载此文件,因此种子节点列表可以在不需要重启每个节点的情况下动态更改。例如,这对于在Docker容器中运行的Elasticsearch实例来说,提供了一种方便的机制,可以在启动时动态提供要连接的IP地址列表,而这些IP地址在节点启动时可能未知。
要启用基于文件的发现,请在 elasticsearch.yml 文件中如下配置 file 主机提供程序:
discovery.seed_providers: file
然后在 $ES_PATH_CONF/unicast_hosts.txt 文件中创建一个文件,格式如下所述。任何时候对 unicast_hosts.txt 文件所做的更改都会被 Elasticsearch 获取,并使用新的主机列表。
请注意,基于文件的发现插件增强了elasticsearch.yml中的单播主机列表:如果在discovery.seed_hosts中有有效的种子地址,那么Elasticsearch除了使用unicast_hosts.txt中提供的地址外,还会使用这些地址。
文件 unicast_hosts.txt 每行包含一个节点条目。每个节点条目由主机(主机名或IP地址)和一个可选的传输端口号组成。如果指定了端口号,它必须紧跟在主机之后(在同一行上),并用 : 分隔。如果未指定端口号,Elasticsearch 将隐式使用由 transport.profiles.default.port 指定的端口范围中的第一个端口,或者如果未设置 transport.profiles.default.port,则使用 transport.port。
例如,这是一个包含四个节点的集群的unicast_hosts.txt示例,其中一些节点未在默认端口上运行:
10.10.10.5 10.10.10.6:9305 10.10.10.5:10005 # an IPv6 address [2001:0db8:85a3:0000:0000:8a2e:0370:7334]:9301
主机名可以代替IP地址,并如上所述通过DNS解析。如果需要,IPv6地址必须用方括号括起来,端口紧随方括号之后。
您也可以在此文件中添加注释。所有注释必须出现在以 # 开头的行上(即注释不能从行中间开始)。
EC2主机提供者
editThe EC2 discovery plugin 添加了一个使用 AWS API 查找种子节点列表的主机提供程序。
Azure Classic 主机提供程序
editThe Azure Classic discovery plugin 添加了一个使用 Azure Classic API 查找种子节点列表的主机提供程序。
Google Compute Engine 主机提供商
editThe GCE discovery plugin 添加了一个使用 GCE API 查找种子节点列表的主机提供程序。
基于法定人数的决策
edit选举主节点和更改集群状态是主节点候选节点必须共同完成的两项基本任务。即使某些节点发生故障,这些活动也必须稳健地进行。Elasticsearch通过考虑每个动作在接收到来自法定人数的响应后即视为成功,从而实现了这种稳健性。法定人数是集群中主节点候选节点的一个子集。仅要求部分节点响应的优势在于,这意味着即使部分节点发生故障,集群仍可以继续运行。法定人数经过精心选择,以确保集群不会出现“脑裂”场景,即集群被分成两部分,每部分可能做出与另一部分不一致的决策。
Elasticsearch 允许您向正在运行的集群中添加和移除有资格成为主节点的节点。在许多情况下,您只需根据需要启动或停止节点即可。有关更多信息,请参阅在您的集群中添加和移除节点。
当节点被添加或移除时,Elasticsearch通过更新集群的投票配置来维持最佳的容错水平,投票配置是那些在做出决策(如选举新主节点或提交新的集群状态)时,其响应会被计数的主节点候选节点集合。只有在投票配置中超过半数的节点响应后,才会做出决策。通常,投票配置与当前集群中所有主节点候选节点的集合相同。然而,在某些情况下,它们可能会有所不同。
为了确保集群保持可用,您不能同时停止投票配置中的一半或更多节点。只要超过一半的投票节点可用,集群仍然可以正常工作。这意味着如果存在三个或四个符合主节点资格的节点,集群可以容忍其中一个不可用。如果存在两个或更少的符合主节点资格的节点,它们必须全部保持可用。
如果你同时停止投票配置中一半或更多的节点,那么集群将不可用,直到你重新上线足够多的节点以再次形成法定人数。在集群不可用期间,任何剩余的节点将在日志中报告它们无法发现或选举主节点。更多信息请参见故障排查发现。
在主节点加入或离开集群后,被选中的主节点可能会发出一个集群状态更新,以调整投票配置以匹配,这可能需要一点时间才能完成。在从集群中移除更多节点之前,等待此调整完成非常重要。有关更多信息,请参阅移除主节点。
主节点选举
editElasticsearch 使用选举过程来就选举的主节点达成一致,无论是在启动时还是在现有选举的主节点失败时。任何有资格成为主节点的节点都可以启动选举,通常第一次进行的选举将会成功。选举通常只有在两个节点几乎同时启动它们的选举时才会失败,因此每个节点上的选举都是随机安排的,以减少这种情况发生的概率。节点将重试选举,直到选出主节点,失败时会退避,因此最终选举将会成功(具有任意高的概率)。主节点选举的调度由 主选举设置 控制。
集群维护、滚动重启和迁移
edit许多集群维护任务涉及临时关闭一个或多个节点,然后重新启动它们。默认情况下,如果其中一个主节点被下线,例如在滚动升级期间,Elasticsearch可以保持可用。此外,如果多个节点被停止然后重新启动,它将自动恢复,例如在全集群重启期间。在这些情况下,无需使用此处描述的API采取进一步行动,因为主节点集没有永久性变化。
投票配置
edit每个Elasticsearch集群都有一个投票配置,这是在做出诸如选举新主节点或提交新集群状态等决策时,其响应被计数的主节点的集合。只有在投票配置中的大多数(超过一半)节点响应后,才会做出决策。
通常,投票配置与当前集群中所有符合主节点资格的节点集合相同。然而,在某些情况下,它们可能会有所不同。
为了确保集群保持可用,您不能同时停止投票配置中的一半或更多节点。只要超过一半的投票节点可用,集群仍然可以正常工作。这意味着如果存在三个或四个符合主节点资格的节点,集群可以容忍其中一个不可用。如果存在两个或更少的符合主节点资格的节点,它们必须全部保持可用。
如果你同时停止投票配置中一半或更多的节点,那么集群将不可用,直到你重新上线足够多的节点以再次形成法定人数。在集群不可用期间,任何剩余的节点将在日志中报告它们无法发现或选举主节点。更多信息请参见故障排查发现。
当一个节点加入或离开集群后,Elasticsearch 会自动对投票配置进行相应的更改,以确保集群尽可能具有弹性。在从集群中移除更多节点之前,等待此调整完成非常重要。更多信息,请参阅 在集群中添加和移除节点。
当前的投票配置存储在集群状态中,因此您可以按如下方式检查其当前内容:
GET /_cluster/state?filter_path=metadata.cluster_coordination.last_committed_config
当前的投票配置不一定与集群中所有可用的主节点相同。更改投票配置需要进行投票,因此当节点加入或离开集群时,调整配置需要一些时间。此外,在某些情况下,最具弹性的配置可能包括不可用的节点或不包括某些可用的节点。在这些情况下,投票配置与集群中可用的主节点集合不同。
较大的投票配置通常更具弹性,因此Elasticsearch通常倾向于在它们加入集群后将符合主节点资格的节点添加到投票配置中。同样,如果投票配置中的节点离开集群,并且集群中还有另一个不在投票配置中的符合主节点资格的节点,那么最好将这两个节点交换。因此,投票配置的大小保持不变,但其弹性增加。
在节点离开集群后,自动从投票配置中移除节点并不是那么简单。不同的策略有不同的优缺点,因此正确的选择取决于集群的使用方式。您可以通过使用cluster.auto_shrink_voting_configuration设置来控制投票配置是否自动收缩。
如果 cluster.auto_shrink_voting_configuration 设置为 true(这是默认且推荐的值),并且集群中至少有三个符合主节点资格的节点,Elasticsearch 将能够在其符合主节点资格的节点中除一个节点外都健康的情况下继续处理集群状态更新。
在某些情况下,Elasticsearch 可能会容忍多个节点的丢失,但这并不能保证在所有故障序列下都能实现。如果 cluster.auto_shrink_voting_configuration 设置为 false,您必须手动从投票配置中移除已离开的节点。使用 投票配置排除 API 来实现所需的弹性级别。
无论配置如何,Elasticsearch都不会遭受“https://en.wikipedia.org/wiki/Split-brain_(computing)[脑裂]”不一致的问题。
cluster.auto_shrink_voting_configuration设置仅影响其在某些节点发生故障时的可用性,以及在节点加入和离开集群时必须执行的管理任务。
主节点候选节点的偶数数量
edit在一个集群中,通常应该有奇数个主节点候选节点。如果存在偶数个,Elasticsearch会将其中的一个排除在投票配置之外,以确保投票配置的大小为奇数。这种排除并不会降低集群的容错能力。实际上,它稍微提高了容错能力:如果集群遭受网络分区,将其分成两个大小相等的部分,那么其中一个部分将包含投票配置中的大多数,并且能够继续运行。如果所有主节点候选节点的投票都被计算在内,那么双方都不会包含严格多数的节点,因此集群将无法取得任何进展。
例如,如果集群中有四个符合主节点资格的节点,并且投票配置包含所有这些节点,那么任何基于法定人数的决策都需要至少三个节点的投票。这种情况意味着集群只能容忍丢失一个符合主节点资格的节点。如果这个集群被分成两个相等的部分,两个部分都不会包含三个符合主节点资格的节点,集群将无法进行任何进展。然而,如果投票配置只包含四个符合主节点资格节点中的三个,集群仍然只能完全容忍丢失一个节点,但基于法定人数的决策需要两个投票节点的投票。在出现均分的情况下,一半将包含三个投票节点中的两个,因此这一半将保持可用。
设置初始投票配置
edit当一个全新的集群首次启动时,它必须选举其第一个主节点。为了进行这次选举,它需要知道一组有资格成为主节点的节点,这些节点的投票应该被计入。这个初始的投票配置被称为引导配置,并在集群引导过程中设置。
引导配置必须准确识别哪些节点应在第一次选举中投票。仅仅配置每个节点对集群中应有多少节点的期望是不够的。还需要注意的是,引导配置必须来自集群外部:集群自身无法安全地确定正确的引导配置。
如果引导配置没有正确设置,当你启动一个全新的集群时,可能会意外形成两个独立的集群,而不是一个。这种情况可能导致数据丢失:你可能会在注意到出现问题之前开始使用这两个集群,而之后无法将它们合并在一起。
为了说明配置每个节点以期望特定集群大小的问题,假设启动一个三节点集群,其中每个节点都知道它将成为三节点集群的一部分。三节点的大多数是两个,所以通常前两个相互发现的节点会形成一个集群,第三个节点稍后加入它们。然而,假设错误地启动了四个节点而不是三个。在这种情况下,有足够的节点形成两个独立的集群。当然,如果每个节点都是手动启动的,那么启动太多节点的可能性不大。然而,如果你使用的是自动化编排器,那么确实有可能遇到这种情况——特别是如果编排器对网络分区等故障不具有弹性。
初始法定人数仅在集群首次启动时需要。新节点加入已建立的集群可以安全地从选举出的主节点获取所需的所有信息。曾经是集群一部分的节点在重启时会将所需的所有信息存储到磁盘。
引导集群
edit首次启动Elasticsearch集群时,需要在集群中的一个或多个主节点候选节点上显式定义初始的主节点候选节点集合。这被称为集群引导。这仅在集群首次启动时需要。新启动的节点加入正在运行的集群时,会从集群的选定主节点获取此信息。
初始的主节点集合在
cluster.initial_master_nodes 设置中定义。这应该设置为一个包含每个主节点的一个以下项目的列表:
- 节点的节点名称。
-
如果未设置
node.name,则为节点的hostname,因为node.name默认为节点的hostname。您必须使用完全限定的hostname或裸hostname取决于您的系统配置。 -
节点的传输发布地址的IP地址,如果无法使用节点的
node.name。这通常是network.host解析到的IP地址,但这可以被覆盖。 -
节点的发布地址的IP地址和端口,格式为
IP:PORT,如果无法使用节点的node.name且多个节点共享一个IP地址。
不要在不符合主节点资格的节点上设置cluster.initial_master_nodes。
集群形成后,从每个节点的配置中移除cluster.initial_master_nodes设置,并且在此集群中再也不要设置它。不要在加入现有集群的节点上配置此设置。不要在重新启动的节点上配置此设置。在进行全集群重启时不要配置此设置。
如果你在集群形成后仍然保留cluster.initial_master_nodes,那么未来可能会因为配置错误而导致在现有集群旁边启动一个新的集群。在这种情况下,如果不丢失数据,可能无法恢复。
创建新集群的最简单方法是从您的一个符合主节点资格的节点中选择一个,该节点将引导自身成为一个单节点集群,然后所有其他节点将加入该集群。这种简单的方法在其他符合主节点资格的节点加入集群之前不具备容错能力。例如,如果您有一个符合主节点资格的节点,其节点名称为master-a,则按如下方式配置它(从所有其他节点的配置中省略cluster.initial_master_nodes):
cluster.initial_master_nodes: master-a
对于容错集群引导,使用所有符合主节点条件的节点。
例如,如果您的集群有3个符合主节点条件的节点,其节点名称分别为master-a、master-b和master-c,则将它们全部配置如下:
cluster.initial_master_nodes: - master-a - master-b - master-c
您必须在设置cluster.initial_master_nodes的每个节点上将其设置为相同的节点列表,以确保在引导过程中仅形成一个集群。如果cluster.initial_master_nodes在设置它的节点上有所不同,则可能会引导多个集群。通常情况下,如果不丢失数据,就无法从这种情况中恢复。
选择集群名称
edit通过cluster.name设置,您可以创建多个相互隔离的集群。节点在首次相互连接时会验证它们是否同意集群名称,Elasticsearch只会将具有相同集群名称的节点组成一个集群。集群名称的默认值是elasticsearch,但建议将其更改为反映集群逻辑名称的值。
开发模式中的自动引导
edit默认情况下,每个节点在第一次启动时会自动引导自己成为一个单节点集群。如果配置了以下任何设置,则不会进行自动引导:
-
discovery.seed_providers -
discovery.seed_hosts -
cluster.initial_master_nodes
要将新节点添加到现有集群中,请配置 discovery.seed_hosts 或其他相关发现设置,以便新节点能够发现集群中现有的主节点。要引导新的多节点集群,请按照 集群引导部分 中所述配置 cluster.initial_master_nodes,以及 discovery.seed_hosts 或其他相关发现设置。
发布集群状态
edit当选的主节点是集群中唯一可以对集群状态进行更改的节点。当选的主节点一次处理一批集群状态更新,计算所需的更改并将更新后的集群状态发布到集群中的所有其他节点。每次发布都始于当选的主节点将更新后的集群状态广播到集群中的所有节点。每个节点都会响应一个确认,但不会立即应用新接收到的状态。一旦当选的主节点从足够多的有资格成为主节点的节点收集到确认,新的集群状态就被称为已提交,主节点会广播另一条消息,指示节点应用现在已提交的状态。每个节点接收到此消息,应用更新后的状态,然后向主节点发送第二个确认。
当选的主节点允许有限的时间将每个集群状态更新完全发布到所有节点。它由cluster.publish.timeout设置定义,默认值为30s,从发布开始时计算。如果在新的集群状态提交之前达到此时间,则集群状态更改将被拒绝,并且当选的主节点认为自身已失败。它会下台并开始尝试选举新的主节点。
如果新的集群状态在cluster.publish.timeout超时之前被提交,选定的主节点认为更改已成功。它会等待超时结束或直到它收到每个节点已应用更新状态的确认,然后开始处理和发布下一个集群状态更新。如果未收到某些确认(即某些节点尚未确认已应用当前更新),这些节点被称为滞后,因为它们的集群状态已落后于选定主节点的最新状态。选定的主节点会等待这些滞后的节点赶上一段时间,cluster.follower_lag.timeout,默认为90s。如果在此时间内节点仍未成功应用集群状态更新,则认为该节点已失败,选定的主节点会将其从集群中移除。
集群状态更新通常以与前一个集群状态的差异形式发布,这减少了发布集群状态更新所需的时间和网络带宽。例如,当仅更新集群状态中部分索引的映射时,只需将这些索引的更新发布到集群中的节点,只要这些节点具有前一个集群状态。如果某个节点缺少前一个集群状态,例如在重新加入集群时,选举出的主节点将向该节点发布完整的集群状态,以便它能够接收未来的更新作为差异。
Elasticsearch 是一个基于对等网络的系统,其中节点之间直接进行通信。高吞吐量的 API(索引、删除、搜索)通常不与选举出的主节点进行交互。选举出的主节点的职责是维护全局集群状态,包括在节点加入或离开集群时重新分配分片。每次集群状态发生变化时,新的状态都会如上所述发布到集群中的所有节点。
集群状态更新的性能特征是每个符合主节点资格的节点的存储速度的函数,以及集群中所有节点之间的网络互连的可靠性和延迟。因此,您必须确保集群中的节点可用的存储和网络足够好,以满足您的性能目标。
集群故障检测
edit当选的主节点定期检查集群中的每个节点,以确保它们仍然连接且健康。集群中的每个节点也定期检查当选主节点的健康状况。这些检查分别被称为跟随者检查和领导者检查。
Elasticsearch允许这些检查偶尔失败或超时而不采取任何行动。它仅在连续多次检查失败后才认为节点有故障。您可以通过cluster.fault_detection.*设置来控制故障检测行为。
如果当选的主节点检测到某个节点已断开连接,则这种情况被视为立即失败。主节点会绕过超时和重试设置值,并尝试将该节点从集群中移除。同样,如果某个节点检测到当选的主节点已断开连接,这种情况也被视为立即失败。该节点会绕过超时和重试设置,并重新启动其发现阶段,以尝试找到或选举新的主节点。
此外,每个节点定期通过向磁盘写入一个小文件然后再次删除它来验证其数据路径的健康状况。如果一个节点发现其数据路径不健康,那么它将被从集群中移除,直到数据路径恢复。您可以使用monitor.fs.health设置来控制此行为。
当选的主节点 如果在合理的时间内无法应用更新的集群状态,也会将节点从集群中移除。超时默认从集群状态更新的开始时间起2分钟。有关更详细的描述,请参阅 发布集群状态。
解决不稳定的集群问题
edit参见 排查不稳定的集群。
诊断断开节点
edit参见 诊断 断开连接 的节点。
诊断滞后节点
edit参见 诊断 滞后 节点。
诊断 follower check retry count exceeded 节点
edit参见 诊断 follower check retry count exceeded 节点。
诊断 ShardLockObtainFailedException 失败
edit参见 诊断 ShardLockObtainFailedException 失败。
诊断其他网络断开
edit参见 诊断其他网络断开。