type
status
date
slug
summary
tags
category
password
1、Elasticsearch集群角色
1.1 集群角色介绍
Elasticsearch 将集群中的节点分成了多种不同的角色,每种角色有不同的功能。节点角色可可以在
elasticsearch.yml
文件中显式声明。如果不显式声明,在默认情况下,每个节点拥有全部角色。下面三种是最常用的节点角色类型:
- master node:每个集群有且只有一个 master node,主节点负责管理整个集群,默认不存储数据,不参与搜索或索引操作,第一个启动的节点成为 master node。主节点负责的工作内容有:
- 维护整个集群的元数据。
- 管理集群状态(cluster state)的变更。
- 维护节点的成员关系(节点加入/离开集群)。
- 决定分片的分配和重新分配。
- 处理创建/删除索引的请求。
- master eligible node:指的是集群中有权参与 master node 选举的那些节点。选举时超过一半的主候选节点达成一致才能称为 master node。节点都默认为 master eligible node。
- data node:数据存储节点,存储索引分片数据,并负责数据的索引和搜索等功能:
- 存储实际的分片数据。
- 执行数据相关的操作(索引、搜索、聚合等)。
- 处理与数据相关的 CRUD 操作。
在一个正常的 Elasticsearch 集群中,主候选节点和数据节点是必选的,其他的节点类型是可选的。所以一般情况下,配置好主候选节点和数据节点就可以了。
其他节点角色类型如下所示:
- ingest node:拥有该角色的节点将成为预处理节点,该节点在数据写入索引之前可以对数据做一些转换和修改。你可以配置一些专用的预处理节点在数据写入索引之前完成数据转换,节点的配置如下:
node.roles: [ingest]
- remote_cluster_client node:拥有该角色的节点可以连接到远程集群以发起对远程集群的搜索。创建一个专门的远程集群客户端节点配置如下:
node.roles: [remote_cluster_client]
- ml node:也就是机器学习(machine learning)角色,拥有该角色的节点可以完成一些机器学习方面的操作,实现该功能需要使用X-Pack插件。创建一个专门的机器学习节点配置如下:
node.roles: [ml]
- transform node:拥有该角色的节点可以完成一些转换操作。一次转换操作可以把一个索引的搜索结果转换后写入另一个索引,这在某些数据分析场景中会很有用,该功能的实现也需要使用X-Pack插件。创建一个专门的数据转换节点配置如下:
node.roles: [transform]
- coordinating node:如果你把一个节点的 node.roles 参数配置为空,即
node.roles: []
,它将成为一个专用的协调节点。协调节点既不能存放、转换数据,也不能选举主节点,它就像一个负载均衡器一样只能够处理客户端请求的转发操作。由于所有的节点都自带这种能力,通常并没有必要单独配置协调节点。
1.2 设置集群角色
在 Elasticsearch 7.9 版本之前,在
elasticsearch.yml
中使用node.master
来配置主候选节点,node.data
来配置数据节点,他们的关系如下node.master | node.data | 类型 | 作用 |
true | true | 主节点+数据节点(master + data) | 既参加主节点竞选,也存储数据 |
true | false | 只有一个节点为 master node,其他都为master eligible node | 只参加主节点竞选,不存储数据 |
false | true | 数据节点(data node) | 只存储数据,不参加主节点竞选 |
false | false | 协调节点(coordinating node) | 都不,只作为均衡负载使用 |
Elasticsearch 7.9 版本以后,使用
node.roles
取代了 node.master
和 node.data
,在 elasticsearch.yml
配置文件中设置:常见角色组合:
- 专用主节点:如果你想让一个节点成为专门的主候选节点而不处理其他操作,可以配置:
- 专用主候选节点:如果想让主候选节点参与投票选举而不成为主节点,可以配置:
- 专用数据节点:
- 专用协调节点:不存储数据,不参与主节点选举:
- 混合节点:既有主节点资格又存储数据:
- 数据节点 + ingest节点:
一个典型的 Elasticsearch 集群角色如下图所示:

每个 node 会跟其他所有 node 建立连接。其中:
- Node A 是当前集群的 Master。
- Node B 和 Node C 是 Master 的候选节点(master eligible node)。
- Node A 和 Node B 同时也是数据节点(data node)。
- Node D 是一个单纯的数据节点,NodeE 是一个协调节点(coordinating node)。
2、Elasticsearch集群的搭建
2.1 集群的自动发现功能
Elasticsearch 多个节点要想组成同一个集群,只需要配置一个相同的
cluster.name
。节点间可以互相发现从而组织成一个集群。单个节点也算是一个集群,只是这个集群里面只有一个节点。例如下面两个节点组成一个集群,集群名称为
docker-cluster
。Elasticsearch 每个大版本的配置文件的内容都有些不同,下面的配置文件只适用于 8.0 以上的版本。
节点一配置
节点二配置
这里简单介绍下这几个配置选项:
cluster.name
设置集群名称。一个节点只能加入一个集群中,默认的集群名称是elasticsearch
。多个节点必须要确保集群名称相同,这样才能加入到同一个集群中。
node.name
:可以配置每个节点的名称。用来提供可读性高的 ES 实例名称,默认是机器的hostname
,可以自定义。同一集群中的节点名称不能相同。
network.host
:设置访问的地址。默认仅绑定在回环地址127.0.0.1
和[::1]
。如果需要从其他服务器上访问以及多态机器搭建集群,我们需要设定 ES 运行绑定的 Host,节点需要绑定非回环的地址。建议设置为主机的公网 IP 或0.0.0.0
。
http.port
:http 端口,如果采用 REST API 对接 ES,那么就是采用的 http 协议。默认端口是 9200。如果没有明确指定端口,Elasticsearch 会取用 9200~9299 这个范围内的端口,如果 9200 被占用,就选择 9201,依次类推。
transport.port
:tcp 端口,用于集群中节点之间的所有内部通信,与远程集群节点的所有通信,以及 Elasticsearch Java API 中的 TransportClient。默认端口是 9300,范围取值为 9300-9399。
discovery.seed_hosts
:如果要与其他主机上的节点组成集群,则必须设置discovery.seed_hosts
,用来提供集群中的其他主机列表(它们是符合主机资格要求的master-eligible
并且可能处于活动状态的且可达的,以便寻址发现过程)。此设置应该是群集中所有符合主机资格的节点的地址的列表。 每个地址可以是 IP 地址,也可以是通过 DNS 解析为一个或多个 IP 地址的主机名(hostname
)。可以带上端口,例如127.0.0.1:9300
。
cluster.initial_master_nodes
: 初始的候选 master 节点列表。初始主节点应通过其node.name
标识,默认为其主机名。确保cluster.initial_master_nodes
中的值与node.name
完全匹配。非主候选节点不需要配置cluster.initial_master_nodes
,它用于指定集群引导时的主候选节点列表,该配置只有在新集群启动时才有效。
官网文档要求,如果要组成集群,必须至少配置[discovery.seed_hosts,discovery.seed_providers,cluster.initial_master_nodes]
中的一个。
2.2 集群状态
Elasticsearch 集群有三种状态:
- green(绿色):表示节点运行状态为健康状态。所有主分片和副分片都可以正常工作,集群100%健康。
- yellow(黄色):表示节点运行状态为预警状态。所有的主分片都可以正常工作,但至少有一个副分片是不能正常工作的。此时集群依然可以正常工作,但集群的高可用性在某种程度上被弱化。
- red(红色):表示集群无法正常使用。此时集群中至少有一个分片的主分片以及它的全部副分片都不可以正常工作。虽然集群的查询操作还可以进行,但是只能返回部分数据(其他正常分片的数据可以返回),而分配到这个问题分片上的写入请求将会报错,最终导致数据丢失。
执行下面命令查看集群状态
返回结果如下:
可以看到集群节点数为 2,status 的值为 green,表示此时集群所有索引的主分片和副分片都正常工作。
2.3 集群选主算法
Elasticsearch 7.0 版本之前,选主功能由 ZenDiscovery 模块负责,采用类 Bully 算法。从 7.0 版本开始,Elasticsearch 废弃了 ZenDiscovery 模块,并采用优化过的 Raft 算法进行选主。
当一组崭新的 Elasticsearch 节点启动的时候,需要进行集群节点的引导来把这些孤立的节点组织成一个整体对外提供统一的服务。集群节点的引导主要分为 4 个步骤:
- 初始化投票配置。确定集群中的主候选节点列表,将配置
cluster.initial_master_nodes
中的节点列表作为主候选节点列表写入投票配置。
- 选举主节点。投票配置中的主候选节点发起主节点的选举,只要超过一半的主候选节点达成一致,则主节点选举成功。
- 发现集群的其他节点。每个节点根据配置的主候选节点列表 discovery.seed_hosts 逐一尝试连接,如果联系到了主节点就申请加入集群,主节点确定连接成功就把该节点加入集群并修改集群的状态,然后将集群的最新状态发布到其他节点中保存。
- 当所有的节点都发现完毕,整个集群的状态生成结束时,待集群启动完毕就可以对外提供统一服务
注意:在步骤(3)中,节点的发现过程是递归的。即使某个节点的 discovery.seed_hosts 不包含集群的主节点,只要它可以通过列表中的节点间接地找到主节点,就能被主节点纳入集群。
对于现有的集群,添加和删除节点会改变集群的状态。集群的状态是一种庞大的数据结构,它包含整个集群的元数据信息。当集群状态发生变化时,主节点需要把最新的状态发布给每个节点,这个过程需要经历以下两个阶段。
- 预提交阶段:如图所示,主节点把最新的集群状态数据发布到每个节点上,每个节点接收状态数据并将其保存在本地然后向主节点发送确认响应。

- 正式提交阶段:如图所示,主节点统计收到的主候选节点的确认响应数量,如果超过一半的主候选节点的确认响应成功,则开始正式提交。主节点发布提交消息到集群的每个节点,通知它们应用最新的集群状态。每个节点应用最新的集群状态后,向主节点发送最终的确认响应。一旦所有的确认响应成功,则本次状态发布成功完成。

集群状态的发布具有时间限制,如果超过时间限制(默认为30秒)主节点状态没有发布成功则主节点失败,主候选节点需要重新选举新的主节点。如果某个节点最终的确认响应超过一定时间限制(默认为90秒)没有发送到主节点,则主节点认为该节点掉线,将其从集群列表中删除。
集群在运行时可能会由于网络环境或硬件问题导致某些节点不能正常工作,为了维持集群的正常运转,主节点和非主节点每隔一段时间就会互相发送心跳检测包。如果某个非主节点连续多次心跳检测失败,则该节点掉线,主节点会把它从集群的状态中删除;如果主节点掉线,则需要使用投票配置重新选举出新的主节点来管理整个集群。
3、集群高可用
3.1 集群高可用的原则
为了确保集群在生产环境中能够保持高可用,以下原则必须遵守。
- 集群节点至少要有3个,主候选节点也至少要有3个。
- 存放索引分片的数据节点至少要有2个,以避免出现单点故障。
- 每个索引分片至少要有1个副本分片,以避免节点掉线引发数据丢失。
- 集群健康状态要为绿色,以确保所有的副本分片都得到分配。
3.2 集群监控
3.2.1 监控集群的状态信息
集群状态信息是一种数据结构,里面包含节点的信息、集群的配置、索引的映射和每个节点分片分配的情况信息等元数据。你可以使用以下请求查看集群的状态信息。
返回结果如下:
其中nodes代表的是集群节点的列表;metadata代表的是集群的元数据,包含集群的投票配置、索引映射、索引模板等信息;routing_table中罗列了每个索引的分片在集群中分布的位置信息;routing_nodes列出了每个节点包含的索引分片的列表和未得到分配的分片列表。
由于这种数据结构比较大,查看不太方便,你可以通过传参的方式只查看部分结果。
这个请求表示只查看索引allocation-test的routing_table信息,也就是分片分配的信息。
以下请求表示只返回状态数据中的节点列表信息,使用时可以根据实际的需要来选择有用的状态信息进行查看。
3.2.2 监控集群的健康状态
集群的健康状态跟健康状态最差的索引的是一致的,也就是说,如果集群中某个索引的健康状态是红色,则集群的健康状态也是红色。查看集群的健康状态可以使用以下请求。
返回结果如下:
你可以从status中看出集群的健康状态是绿色,还可以看到集群的节点总数、分片总数、未得到分配的分片总数等信息。如果你想查看某个索引的健康状态,可以在该请求中添加索引名称的参数
这样返回的结果就只包含该索引的健康状态信息。
3.2.3 监控集群节点的统计指标
要查看整个集群的统计指标,可以使用以下请求。
其中indices部分包含索引在整个集群中拥有的分片数、文档数、占用空间、缓存量等统计数据;nodes部分包含整个集群的节点数、JVM内存大小等统计数据。
如果你想查看每个节点的统计指标,可以使用_nodes端点返回各个节点的统计数据的列表。
返回结果如下:
3.2.4 监控节点的热点线程
使用监控节点的热点线程能够找出CPU占用多的操作,可便于开发和运维人员及时发现集群的性能瓶颈。发送监控节点的热点线程的请求如下。
以下返回结果是每个节点的一段文本,结果文本包含各个节点热点线程的描述。
3.2.5 查看慢搜索日志
Elasticsearch 还允许你通过慢搜索日志查看那些搜索速度比较慢的请求,你可以设置每个索引查询耗时的阈值来界定哪些慢搜索请求会被写入慢搜索日志,例如:
该设置表示把allocation-test 索引的query请求阶段耗时达到10ms的请求输出为warn日志,fetch取回阶段超过10ms的请求也输出为warn日志。配置slowlog.level为info表示只记录info及其以上级别的日志。查询索引后,超过阈值并达到相应级别的慢日志会被记录在查询涉及的每个节点中,可以到各个节点的logs文件夹中查看,慢日志文件名为my-application_index_search_slowlog.log。例如在node-1上,做一次match_all查询后,logs文件夹生成的慢日志片段如下。
3.2.6 查看慢索引日志
慢索引日志允许你把写入索引较慢的请求记录到日志中,用于定位写入速度慢的请求,以便有针对性地优化它们。首先,设置慢索引日志的记录阈值。
以上设定的意思是,写入索引allocation-test耗时超过10ms的请求将生成一个warn日志,slowlog.level限定了只记录info及其以上级别的日志。配置slowlog.source为1000表示在日志中最多记录索引数据的前1000个字符。向allocation-test中写入一条数据,然后在logs文件夹下打开my-application_index_indexing_slowlog.log,可以看到以下片段。
该日志记录了写入请求的数据、耗时、节点名称以及日志的级别。慢索引日志也是分片级别的,因此只有数据写入分片所在的节点才能看到该数据的慢索引日志。
- Author:mcbilla
- URL:http://mcbilla.com/article/7056e82a-764d-4c07-9a9e-4372e99e38d2
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts