文章一:深度掌握Elasticsearch集群组建和集群设置

Elasticsearch(ES)是基于Lucene实现的分布式实时检索与分析引擎,其所有高可用、高容错、横向扩展能力,全部依托分布式集群机制实现。很多开发者仅会简单搭建集群,却不理解选主算法、分片分配、故障自愈的底层原理,导致生产环境频繁出现脑裂、集群红、分片丢失、节点无法上线等问题。

本文严格按照先原理、后实战的结构撰写:前置完整拆解ES集群架构原理、分布式一致性算法、集群选主核心算法、故障底层机制,最后统一落地集群从零搭建实战,彻底实现「懂原理、会搭建、能排障」。

Elasticsearch 集群核心原理

ES集群分布式整体架构原理

ES集群本质是一个去中心化的分布式对等集群,集群内所有节点地位对等,通过内部TCP协议自动发现、状态同步、数据协同,对外统一提供服务,客户端无需感知集群内部节点细节。

分布式集群的核心设计目标:解决单节点容量上限、性能上限、单点故障问题,实现数据冗余、请求负载均衡、故障自动转移、集群横向扩容

集群选主核心算法与选举原理(重点)

很多资料只讲选主规则,不讲底层算法。ES 7.x/8.x 彻底废弃老旧Zen机制,统一使用基于Raft一致性算法改良的分布式选举机制 ,官方名称为ES Coordination Algorithm(ES协调算法)

选主底层依赖:改良版Raft算法

原生Raft算法分为三个角色:领导者、跟随者、候选人,通过任期制、日志复制、多数投票实现一致性。

ES在原生Raft基础上做了轻量化改良,适配集群运维场景:

  • 只针对集群元数据选举,不做强日志复制,提升集群响应速度;

  • 引入固定投票配置集,避免随机节点参与选举,防止脑裂;

  • 简化任期逻辑,优先保证集群快速收敛、稳定,而非极致强一致性。

算法核心结论 :ES集群选主 = 改良版Raft多数投票机制 + 法定人数Quorum约束

法定人数 Quorum 原理(防脑裂核心)

Raft算法的安全底线:任何决策必须获得多数节点确认。ES基于此定义Quorum法定票数:

Quorum = 主候选节点总数 / 2 + 1(向上取整)

举例:3个主候选节点,Quorum=2,必须获得至少2票才能当选主节点。

该机制从算法层面杜绝脑裂:网络分区后,任何子集群只要不满足多数票数,就无法选举主节点,集群不会出现双主冲突。

完整选举触发时机与算法流程

选举触发时机:集群初始化、主节点心跳超时离线、网络分区恢复、投票配置变更。

改良Raft选主完整流程

  1. 心跳探测:所有Master候选节点互相1s一次心跳,超时则判定对方离线;

  2. 切换候选状态:无主节点时,所有存活候选节点切换为候选人状态,发起选举;

  3. 广播投票请求:候选人向所有存活候选节点发送投票申请;

  4. 多数票校验:统计投票数,满足Quorum法定票数则竞选成功;

  5. 领导者生效:获胜节点成为Master主节点,接管集群元数据管理权限;

  6. 状态同步收敛:新主节点将最新集群状态同步至所有节点,集群恢复稳定。

为什么生产必须奇数主节点?

基于Raft+Quorum算法特性:

  • 偶数节点:4个主节点,Quorum=3,若分裂为2+2两个子集群,均不满足法定票数,集群无主、整体瘫痪;

  • 奇数节点:3个主节点,分裂为2+1,只有2节点集群满足Quorum,可正常选主,1节点集群无法选举,彻底规避双主脑裂。

集群脑裂故障底层原理

脑裂定义 :集群因网络抖动、分区、心跳超时,分裂为两个独立子集群,且两个子集群均满足Quorum多数投票条件,各自选出主节点。

底层危害:双主节点同时管理集群,分别执行索引创建、分片分配、数据写入,导致集群元数据分裂、分片错乱、数据覆盖、永久数据丢失,是ES最致命的分布式一致性故障。

根因总结:不满足Raft多数投票约束、主节点数量不合理、心跳超时参数不合理、非法节点参与选举。

ES集群生产搭建实战

单节点集群非安全组建:

修改JVM配置:最高不超过32G,小编这里设置为1GB

修改elasticsearch 配置,当前是想配置一个非安全的集群,所以这里设置一下

关闭X-Pack核心安全认证 xpack.security.enabled: false

之后什么都不用了,直接运行es就可以。

但是我们上述只是做了一下简单的配置,上面的配置下,我们的es只是配置到了本机可以访问,外网是访问不到的。

接下来我们可以设置IP+主节点的配置:

配置集群名称:

单节点下,这个也是可以选择配置或者是不配置的

配置节点名称:

这个是大家任意可以选择的。

配置es监听地址:

规定谁可以访问当前的es集群。

,下面问大家展示了集中配置的区别

配置值 含义
network.host: 127.0.0.1 只能本机访问,别的电脑连不上(最安全,但别人用不了)
network.host: 192.168.1.100 只允许这个 IP 的机器访问
network.host: 0.0.0.0 所有 IP 都能访问(你现在要的效果)

cluster.initial_master_nodes

  • 作用:集群首次启动指定候选主节点,用于集群选举
  • 取值:和node.name节点名保持一致
  • 适用:首次启动生效,后续失效
  • 单节点简化写法:cluster.initial_master_nodes: ["node-1"]

上述讲解后配置文件总体为

python 复制代码
# 集群名称(同一个集群的节点名称必须一致)
cluster.name: es85X

# 当前节点的名称(唯一标识)
node.name: node-1

# 监听所有IP地址,允许外部设备访问
network.host: 0.0.0.0

# HTTP 访问端口(curl、浏览器、程序连接用)
http.port: 9200

# 节点间内部通信端口(集群同步数据用)
transport.port: 9300

# 集群第一次启动时,初始化主节点的候选列表
cluster.initial_master_nodes: ["node-1"]

# 关闭安全认证(学习环境用,生产环境不要关)
xpack.security.enabled: false

单节点集群安全组建:

和上述配置一样,只是最终不可以关闭xpack.

python 复制代码
# 集群名称(同一个集群的节点名称必须一致)
cluster.name: es85X

# 当前节点的名称(唯一标识)
node.name: node-1

# 监听所有IP地址,允许外部设备访问
network.host: 0.0.0.0

# HTTP 访问端口(curl、浏览器、程序连接用)
http.port: 9200

# 节点间内部通信端口(集群同步数据用)
transport.port: 9300

# 集群第一次启动时,初始化主节点的候选列表
cluster.initial_master_nodes: ["node-1"]

多节点集群非安全组建:

节点一配置

python 复制代码
# 集群名称(同一个集群的节点名称必须一致)
cluster.name: es85X

# 当前节点的名称(唯一标识)
node.name: node-1

# 监听所有IP地址,允许外部设备访问
network.host: 0.0.0.0

# HTTP 访问端口(curl、浏览器、程序连接用)
http.port: 9200

# 节点间内部通信端口(集群同步数据用)
transport.port: 9300


# 集群节点发现列表(告诉ES去哪些IP:端口找同伴节点)
discovery.seed_hosts: ["192.0.168.189:9300", "192.0.168.189:9301"]

# 集群第一次启动时,初始化主节点的候选列表
cluster.initial_master_nodes: ["node-1"]

# 关闭安全认证(学习环境用,生产环境不要关)
xpack.security.enabled: false

节点二配置

python 复制代码
# 集群名称(同一个集群的节点名称必须一致)
cluster.name: es85X

# 当前节点的名称(唯一标识)
node.name: node-2

# 监听所有IP地址,允许外部设备访问
network.host: 0.0.0.0

# HTTP 访问端口(curl、浏览器、程序连接用)
http.port: 9201

# 节点间内部通信端口(集群同步数据用)
transport.port: 9301


# 集群节点发现列表(告诉ES去哪些IP:端口找同伴节点)
discovery.seed_hosts: ["192.0.168.189:9300", "192.0.168.189:9301"]

# 集群第一次启动时,初始化主节点的候选列表
cluster.initial_master_nodes: ["node-1"]

# 关闭安全认证(学习环境用,生产环境不要关)
xpack.security.enabled: false

非安全模式下直接启动就可以成功了。

安全模式所节点集群搭建

es在8.x版本下默认就是使用非安全的方式启动集群的。下文中问大家展示一下搭建安全模式下的集群

在安全模式下,配置的时候,参照如下的配置:

节点一:

python 复制代码
# 集群名称(同一个集群的节点名称必须一致)
cluster.name: es85X

# 当前节点的名称(唯一标识)
node.name: node-1

# 监听所有IP地址,允许外部设备访问
network.host: 0.0.0.0

# HTTP 访问端口(curl、浏览器、程序连接用)
http.port: 9200

# 节点间内部通信端口(集群同步数据用)
transport.port: 9300

cluster.initial_master_nodes: ["node-1"]

节点二:

python 复制代码
# 集群名称(同一个集群的节点名称必须一致)
cluster.name: es85X

# 当前节点的名称(唯一标识)
node.name: node-2

# 监听所有IP地址,允许外部设备访问
network.host: 0.0.0.0

# HTTP 访问端口(curl、浏览器、程序连接用)
http.port: 9201

# 节点间内部通信端口(集群同步数据用)
transport.port: 9301

节点三:

python 复制代码
# 集群名称(同一个集群的节点名称必须一致)
cluster.name: es85X

# 当前节点的名称(唯一标识)
node.name: node-3

# 监听所有IP地址,允许外部设备访问
network.host: 0.0.0.0

# HTTP 访问端口(curl、浏览器、程序连接用)
http.port: 9202

# 节点间内部通信端口(集群同步数据用)
transport.port: 9302

使用安全模式的时候,启动的方式是一个一个服务器进行启动,之后通过下面的命令进行添加:

之后使用正在运行的节点执行命令:

./elasticsearch-create-enrollment-token -s node

之后需要加入的节点执行命令:./bin/elasticsearch --enrollment-token <粘贴你的Token>

之后如果在重启集群的时候直接启动就可以了。

配置kibnana:

非安全模式配置:

下面的这个在集群模式下,推荐多配置几个,这样的话在一个节点挂了 → Kibana 自动切换另一个

安全模式配置:

在安全模式线只是需要配置这个一个就可以,但是需要注意的是,我们需要配置一下token.

如果是第一次执行的话。kibana会弹出一个页面,在页面中配置就行了,但是如果我们的token第一次打印的过期了,或者是没有保存下来的话,使用命令:

在任何正在运行的es服务器执行命令都可以获取token。

./elasticsearch-create-enrollment-token -s kibana

之后使用如下命令在kibana启动时带着参数就行了

./kibana-setup -t 《token》

其实这个文章在我在之前已经谢过了,但是那个只是快速搭建一个es的运行环境,但是当前的文章更加的具体和详细,大家都可以对照学习:第四章:动手搭建专业的ES运行环境_linux es启动无报错 但是状态仍然为 dead-CSDN博客,这这篇文章中写了集群配置时我们的操作系统如何配置,这里不再赘述,大家参考一下就可以了。

相关推荐
阿乔外贸日记9 小时前
霍尔木兹通行规则调整,影响卡塔尔LNG出口恢复
大数据·人工智能·云计算
二宝哥9 小时前
大数据之安装zookeeper
大数据·分布式·zookeeper
财经资讯数据_灵砚智能9 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(日间)2026年5月19日
大数据·人工智能·python·信息可视化·自然语言处理·灵砚智能
Hui_AI7209 小时前
抖店铺货自动化:7个核心功能的技术实现方案
大数据·运维·人工智能·自动化·产品运营·ai写作·内容运营
liana87449 小时前
统一企业门户,告别多系统碎片化办公
大数据·安全
前端若水9 小时前
版本控制:智能体提示与配置的CI/CD
大数据·elasticsearch·ci/cd
AI_yangxi9 小时前
短视频矩阵系统哪家好点
大数据·人工智能·矩阵
天天爱吃肉82189 小时前
新能源汽车单级车载电源及高频高密度DCDC设计开发技术入门指南
大数据·人工智能·功能测试·嵌入式硬件·汽车