ElasticSearch 集群构成与节点管理

为何选择 Elasticsearch?

在传统数据库中,商品模糊查询(尤其是前置模糊匹配)会放弃索引,导致全表扫描。在百万级数据规模下,这种查询方式效率极低。而 Elasticsearch(以下简称 ES)通过构建全文索引,将商品名、描述、价格、ID 等高频查询字段纳入索引库,可显著提升查询速度,完美解决这一痛点,因此被广泛应用于各类数据检索场景。

Elasticsearch 集群构成

1. 节点类型定义

ES 集群由多个节点(Node)组成,节点类型通过 conf/elasticsearch.yml 中的两个核心配置项组合确定:

node.master: true/false  # 是否为 master 候选节点(可参与选举)
node.data: true/false    # 是否为数据节点(存储分片数据,处理读写请求)

基于上述配置,节点分为四种基础类型,另有 Ingest Node(数据预处理节点)等特殊类型暂不赘述:

节点类型 node.master node.data 核心功能
主节点+数据节点 true true 参与 master 选举,若当选则管理集群状态;同时存储数据、处理读写请求
仅主节点候选 true false 仅参与 master 选举,不存储数据(适用于大规模集群,减轻主节点负载)
仅数据节点 false true 不参与选举,仅负责数据存储和读写操作(集群扩容的核心节点类型)
代理节点(Proxy) false false 接收客户端请求,转发至对应节点,聚合查询结果(类似网关角色)

2. 集群拓扑示例

一个典型 ES 集群拓扑如下:

  • NodeA:当前主节点(Master)+ 数据节点

  • NodeB:Master 候选节点 + 数据节点

  • NodeC:Master 候选节点

  • NodeD:仅数据节点

  • NodeE:代理节点

  • 特性:每个节点会与集群内所有其他节点建立连接,确保通信畅通。

节点发现机制

ES 采用自研的 ZenDiscovery 模块实现节点发现与选主,无需依赖 Zookeeper 等第三方工具。

1. 核心配置

discovery.zen.ping.unicast.hosts: [1.1.1.1, 1.1.1.2, 1.1.1.3]

该配置指定了节点初始连接的目标地址,官方推荐配置为所有 Master 候选节点。

2. 发现原理

节点通过配置的地址与其他节点建立连接,当所有节点形成连通图时,即可感知整个集群的节点列表,避免出现“孤岛节点”。

Master 选举机制

为避免集群“脑裂”(多个 Master 并存),ES 采用多数派(quorum)认可原则,核心配置如下:

discovery.zen.minimum_master_nodes: 2  # 成为 Master 所需的最小候选节点认可数

1. 选举触发条件

Master 候选节点满足以下条件时,发起选举:

  1. 自身当前非 Master 状态;

  2. 通过 ZenDiscovery 的 ping 操作确认,无节点连接到现有 Master;

  3. 包括自身在内,超过 minimum_master_nodes 个候选节点均未连接到 Master。

2. 候选人排序规则

选举时按以下优先级排序,取首位作为目标 Master:

  1. 集群状态版本号(clusterStateVersion):数值越大优先级越高;

  2. 节点 ID:版本号相同时,ID 越小优先级越高。

3. 选举流程

  1. 候选节点发起选举,根据排序规则确定目标 Master(可能是自身或其他节点);

  2. 若目标为其他节点(如 NodeA 选 NodeB):

    • 若 NodeB 已为 Master,NodeB 会将 NodeA 加入集群,发布新集群状态;

    • 若 NodeB 正在竞选,NodeA 的请求视为“选票”,NodeA 等待 NodeB 竞选结果;

    • 若 NodeB 拒绝竞选,NodeA 开启下一轮选举;

  3. 若目标为自身(如 NodeA 选自己):

    • NodeA 等待其他候选节点的“选票”(join 请求);

    • 收集到超过半数选票时,NodeA 确认成为 Master,更新集群状态并发布。

4. 脑裂防护

核心逻辑是“多数派认可”:只有获得超过 minimum_master_nodes 个候选节点支持,才能成为 Master。由于不可能有两个节点同时获得多数派支持,因此避免了脑裂。

错误检测与恢复机制

ES 通过两类心跳检测机制(MasterFaultDetection、NodesFaultDetection)实现故障感知,核心是定期 ping 通信。

1. 故障检测场景

  1. Master 检测节点故障:

    • Master 发现节点失联后,将其从集群状态中移除,发布新状态;

    • 集群自动触发恢复操作(如重新选举主分片、复制数据);

  2. 节点检测 Master 故障:

    • 节点发现 Master 失联后,清空未提交的集群状态,发起重新加入(rejoin);

    • 若满足选举条件,则触发新 Master 选举。

2. 主动 Rejoin 场景

Master 发现自身不再满足多数派条件时,会主动退出 Master 状态并执行 rejoin,避免脑裂:

  1. 移除失联节点后,剩余候选节点数不足 minimum_master_nodes

  2. 发布集群状态时,发送阶段(send)未获得多数派确认;

  3. 检测到集群中存在其他 Master,且自身集群状态版本更低。

集群扩缩容实践

1. 数据节点(DataNode)扩容

  1. 配置新节点:

    node.master: false
    node.data: true
    cluster.name: es-cluster  # 需与目标集群名称一致
    node.name: node_Z
    discovery.zen.ping.unicast.hosts: ["x.x.x.x", "x.x.x.y", "x.x.x.z"]  # 配置集群中 Master 候选节点地址
  2. 启动节点,集群会自动触发分片均衡(rebalance),或通过 reroute API 手动调整。

2. 数据节点缩容

  1. 禁止分片分配到待下线节点:

    PUT _cluster/settings
    {
    "transient": {
    "cluster.routing.allocation.exclude._ip": "10.0.0.1"  # 待下线节点 IP
    }
    }
  2. 等待节点上所有分片迁移完成后,安全下线节点。

3. Master 候选节点扩容

  1. 调整多数派阈值(避免脑裂):

    curl -XPUT localhost:9200/_cluster/settings -d '{
    "persistent": {
        "discovery.zen.minimum_master_nodes": 3  # 例如:3 个候选节点扩容至 4 个时,阈值从 2 调整为 3
    }
    }'
  2. 配置新节点为 Master 候选节点(node.master: true),启动后加入集群。

  3. 注意:配置文件中的阈值与集群元数据(cluster meta)中的阈值需保持一致,避免集群重启时出现选举异常。

4. Master 候选节点缩容

  1. 先将目标节点下线;

  2. 待集群稳定后,降低 minimum_master_nodes 阈值(与扩容流程相反)。

  3. 警告:Master 节点及相关配置变更风险极高,错误操作可能导致脑裂、数据损坏或丢失。

基于 Zookeeper 的替代实现方案

1. Zookeeper 核心能力

Zookeeper 是分布式系统的协调工具,可解决节点管理、配置同步、主从选举等问题,核心特性包括:

  • 数据存储:以目录树结构管理 znode,每个 znode 包含状态(stat)、数据(data)、子节点(children);

  • 临时节点:session 结束后自动删除,适用于选举和故障检测;

  • Watch 机制:监听 znode 的增减、更新事件,实现状态同步。

2. Zookeeper 实现 ES 核心功能

  • 节点发现:节点启动后在 Zookeeper 特定目录注册临时 znode,Master 监听该目录的子节点变化,自动纳入新节点;

  • Master 选举:候选节点竞争注册“master”临时 znode,注册成功者成为 Master,失败者监听该 znode 变化;

  • 错误检测:节点或 Master 故障时,对应的临时 znode 自动删除,集群通过 Watch 机制感知并触发重新选举;

  • 集群扩缩容:无需手动调整 minimum_master_nodes,操作更简洁。

3. Zookeeper 方案优劣

优势 劣势
简化 ES 分布式一致性逻辑,正确性有保障 增加集群依赖,部署和运维复杂度提升
避免 ZenDiscovery 的潜在 Bug 额外占用服务器资源
扩缩容更便捷 学习成本增加(需掌握 Zookeeper 基础)

ES 选举算法与 Raft 算法对比

Raft 是主流分布式一致性算法,与 ES 自研选举算法的核心差异如下:

1. 相同点

  • 多数派原则:均需获得超过半数节点支持才能当选主节点;

  • 数据一致性保障:当选主节点均拥有最新已提交数据(ES 靠 clusterStateVersion,Raft 靠日志复制)。

2. 不同点

对比维度 ES 选举算法 Raft 算法
正确性 未经过严格数学论证,依赖实践 Bug 修复 经过严格论证,正确性有理论保障
选举周期 无 term 概念,无法保证单轮选举每个节点仅投一票 引入 term 机制,每轮选举 term 递增,每个节点仅投一票
选举倾向性 版本相同时,NodeID 越小优先级越高 只要节点拥有最新数据,即有机会当选

3. 总结

Raft 算法在正确性和规范性上更优,ES 选举算法经多次迭代后逐渐向 Raft 靠拢。由于 ES 开发初期 Raft 尚未普及,未来可能逐步演进为 Raft 实现。