Elasticsearch 核心概念与集群部署

这一章我们聊聊 Elasticsearch 的骨架。说白了,不搞懂集群架构、节点角色和分片原理,你写告警规则再多也容易跑偏。我经历过的几个线上事故,根因全都是对 ES 内部机制理解不透导致的。咱们一步步来。

1. 集群架构与节点角色

ES 集群不是单机玩具,它天然是分布式设计。每个节点可以承担不同角色,我先用一张图把整体结构亮出来,再逐个拆解。

▸ 一句话: 节点角色分离是生产环境的第一道防线。
Elasticsearch 集群节点角色与交互关系 ES 集群节点角色与交互关系 客户端 / Logstash / Beats Coordinating Node Master Node (候选) Ingest Node Data Node Shard 1 (P) Shard 2 (R) 说明 1. 客户端请求先到达 Coordinating Node,再由它路由到 Data Node。 2. Master Node 只负责集群管理(元数据、索引创建),不参与数据写入/查询。 3. Ingest Node 可做数据预处理(如 Grok 解析),减轻 Data Node 压力。 4. 分片 (Shard) 是物理存储单元,主分片 (P) 负责写入,副本分片 (R) 负责容灾和读分担。

2. 节点角色拆解

2.1 Master 节点

Master 是大脑。它不存数据,专管集群状态、路由、索引创建。我在项目中见过有人让所有节点都当 master,结果脑裂了——三个节点互相抢主。建议 node.master: true 的节点至少 3 个,且数量必须奇数。

⚠️ 我曾经的一个避坑: 脑裂是因为候选人节点数量是偶数,两台互相选举不成。后来改成了 3 个专用 Master 节点 + 部署了 Zen Discovery 配置才稳住。

2.2 Data 节点

Data 节点才是真正扛数据写入和查询的。它负责分片的存储、索引、搜索。你想想看,如果 data 节点挂了一个,Lucene 索引会被重新平衡,但系统依然可用——前提是你有副本。

生产环境我建议 data 节点使用本地 SSD,内存至少 64GB,CPU 要高频。磁盘 RAID0 也是可以的,但一定要保证副本。

2.3 Ingest 节点

Ingest 节点用于数据预处理。比如你用 Logstash 或者 Filebeat 直接送到 ES 时,可以在 Ingest 链里做 Grok、转换、降噪。如果不小心写错了 Ingest pipeline,会导致所有数据无法索引,我曾经因为这个在凌晨 3 点被叫醒。

2.4 Coordinating 节点

Coordinating 节点是请求的分发器和汇聚器。它本身不存数据,只负责接收客户端的查询,然后分发到各 Data 节点,最后汇总结果返回。如果你写了一条大范围聚合查询,协调节点很容易成为瓶颈。我会放 2~3 个专属协调节点,并用负载均衡器在前面做七层转发。

3. 索引与分片原理

索引在 ES 里相当于数据库,但它被切成了分片。每个分片是一个独立的 Lucene 索引实例。为什么分片?为了并行和扩展。举个例子,如果你有 5 个主分片,写入时 ES 会根据文档 ID 的 hash 路由到其中一个分片——这个路由算法非常快。

▸ 关键公式: route = hash(文档 _id) % number_of_primary_shards

副本分片的数量可以随时调整,但主分片数一旦创建就不可改变。所以在设计索引时,一定要预估未来半年的数据量。我踩过的坑:日志索引一天一个,结果主分片设置多了,导致 segment 过多、集群状态暴涨。

分片参数建议(基于我踩过的坑)
场景 主分片数 副本分片数 单分片大小预估
业务日志(每天 50GB) 5 ~ 10 1 ≤ 40GB
业务订单(冷热分离) 3 ~ 6 1 ≤ 50GB
全文检索(流量大) 10 ~ 20 2 ≤ 20GB
指标监控(时序) 3 1 ≤ 30GB

4. 硬件选型与配置建议

硬件不是越贵越好。我见过用 256GB 内存跑 ES 的,结果全部给了 JVM heap(超过了 32GB),触发了指针压缩失效,性能反而下降。ES 的 JVM heap 上限建议 32GB,剩余内存留给操作系统 page cache,因为 ES 重度依赖文件系统缓存。

  • CPU: 数据节点至少 8 核(4 核用于 Lucene 线程池),Master 节点 4 核即可。
  • 内存: 64GB 起步(heap 设置 31GB),Master 节点 16GB 足够。
  • 磁盘: 使用 SSD(NVMe 更佳),容量根据分片总量 × 1.5 倍预留。我曾经因为磁盘剩余 < 15% 导致 ES 强制只读,那是噩梦。
  • 网络: 10Gbps 内网,集群间心跳延迟 < 1ms。

5. 生产环境部署最佳实践

这部分是我多年积累的 checklist,每一条都经历过线上验证。

  1. 节点角色分离: 专用 Master 节点 3 个(奇数),Data 节点按需扩缩,协调节点 2~3 个,Ingest 节点可选。
  2. 最小化权限: 关闭 http.cors.enabled,使用防火墙限制端口 9200/9300 只对内网开放。
  3. 索引生命周期管理 (ILM): 即便你只有 10 个索引,也建议用 ILM 管理 hot、warm、cold、delete 阶段。我在某客户现场因为没配置 ILM,一周内积压了 500 个索引,严重影响性能。
  4. 监控与告警: 至少盯住集群健康状态、节点堆内存使用率、JVM GC 暂停时间、写入/查询吞吐量。这些指标在你写告警规则时直接用上。
  5. 配置持久化: 用 elasticsearch.yml + 环境变量组合,避免手动改配置文件。我曾经因为节点重启后配置丢失导致索引分片分配失败。
💡 重点提醒: 如果你在 Docker 或 Kubernetes 上跑 ES,务必设置 bootstrap.memory_lock: true 和 ES_JAVA_OPTS 的 heap 上限,否则 swap 会毁了你的集群。

好了,这一章的核心内容就是这些。ES 集群的节点角色和分片原理是你后面理解告警规则的基础。当你看到告警规则里写 node.roles: data 或者 index.number_of_shards 时,不会觉得是黑话——这些都是实实在在的生产要素。下一部分我们会进入索引模板和数据流,那是告警规则真正落地的地方。