3. 集群部署拓扑与高可用设计
Elasticsearch 的高可用不是靠“多买几台机器”堆出来的,而是由拓扑结构和节点角色共同决定的。同一份数据放在同一机架、同一可用区,即使有 3 个副本,一次断电也会同时失效;而把主节点、数据节点、协调节点混部在同一批机器上,一次 GC 抖动就可能让整个集群失去主节点。本节从部署拓扑和角色划分两个维度,说明如何设计一个真正能扛故障的集群。
一、三种典型部署拓扑
多节点单可用区是最基础的形态:所有节点部署在同一机房或同一可用区,通过副本数(通常 1~2)实现节点级容错。它能抵御单台服务器宕机、单块磁盘损坏,但无法抵御机架掉电、交换机故障或整个可用区中断。适合开发测试、日志量不大且可容忍短时不可用的内部系统。
多可用区部署是生产环境的主流选择。以三可用区为例,节点均匀分布在 AZ-a、AZ-b、AZ-c,通过分片分配感知(cluster.routing.allocation.awareness.attributes: zone)让主分片与副本分片落在不同可用区。这样任意一个可用区整体失效,数据仍有完整副本,集群可继续读写。代价是跨可用区网络延迟会抬高写入和查询的响应时间,通常要求同区域内 AZ 间 RTT 在 1~2ms 以内。
跨机房/双活部署用于同城双中心或异地容灾。跨机房部署要面对更高的网络延迟和带宽成本,一般有两种做法:一是主集群 + 跨集群复制(CCR)做异地只读副本;二是通过分片分配过滤把副本强制放到远端机房,形成“本地主分片 + 异地副本”。跨机房方案必须明确 RPO/RTO 目标,因为同步复制在跨机房场景下会显著拖慢写入。
二、四类节点的职责划分
主节点(master-eligible)负责集群状态管理:创建/删除索引、维护分片分配、跟踪节点上下线。它不处理数据读写,因此对 CPU、内存要求不高,但对稳定性要求极高。生产环境应配置 3 个专用主节点(node.roles: [master]),并设置 discovery.seed_hosts 与 cluster.initial_master_nodes。主节点数量必须是奇数,避免选举时出现平票。若把主节点与数据节点混部,一次大数据量写入引发的长 GC 就可能让主节点失联,触发不必要的重新选举。
数据节点(data)承担分片的存储与检索,是资源消耗最大的角色。它又细分为热节点与冷节点。热节点使用 SSD,承载最近写入、查询频繁的索引;冷节点使用大容量 HDD,存放只读的历史索引。通过 ILM(索引生命周期管理)策略,索引在滚动更新后从热节点迁移到冷节点,例如:hot → warm → cold → delete。迁移时使用 index.routing.allocation.require.data: cold 强制指定目标节点属性。
协调节点(coordinating)只负责请求分发与结果归并,不存储数据、不参与选举。它的角色配置为 node.roles: [](空角色即纯协调节点)。在查询并发高、聚合复杂的场景下,把协调职责从数据节点剥离,可以避免数据节点的 CPU 被聚合计算占满。协调节点前面通常挂一层负载均衡(如 Nginx、HAProxy 或云 LB),客户端只连接协调层。
冷热节点本质是数据节点的两种规格,通过节点属性(node.attr.data: hot/cold)区分。热节点追求低延迟,冷节点追求低成本。一个常见误区是只设置冷热属性却不配置 ILM,结果索引永远留在热节点,冷节点空转。
三、关键配置与验证
下面是一份三可用区、四角色的节点配置示例(以热数据节点为例):
# elasticsearch.yml —— 热数据节点(AZ-a)
node.name: hot-a-1
node.roles: [data_hot, ingest]
node.attr.zone: az-a
node.attr.data: hot
cluster.routing.allocation.awareness.attributes: zone
discovery.seed_hosts: ["master-a:9300","master-b:9300","master-c:9300"]
部署完成后,用以下命令验证拓扑是否符合预期:
GET _cat/nodes?v&h=name,node.role,master,zone,data
GET _cluster/health?pretty
GET _cat/allocation?v
判断依据:_cat/nodes 中每个可用区都应出现主节点、热节点、协调节点、冷节点;_cluster/health 的 status 为 green,number_of_nodes 与规划一致;_cat/allocation 显示各节点分片数大致均衡,没有节点分片数为 0 或远超平均值。若某个可用区没有主节点,或分片全部集中在单一可用区,说明分配感知未生效,需要检查 awareness.attributes 是否与节点属性名一致。
discovery.seed_hosts 全部指向远端机房。主节点选举依赖低延迟心跳,跨机房 RTT 过高会导致频繁的 master 失联与重新选举。跨机房场景应优先采用 CCR 异步复制,而非把主节点分散到异地。