真实独立搭建一个2节点zoneA+1节点zoneB的3节点Elasticsearch集群,验证不开awareness时主副本有真实概率被同时分到同一个可用区,开启非强制awareness.attributes=zone后连续测试全部实现跨区分布,并真实kill掉唯一的zoneB节点模拟整个可用区下线,验证集群仅降级为yellow、全部主分片健在且能正常读写,证明zone awareness真实换来的是可用区级故障下的数据存活保障。
代码真实启动3个独立ES进程组成zone-lab集群: zone-node-1 (zoneA), zone-node-2 (zoneB), zone-node-3 (zoneA) 真实确认: GET /_nodes → zone-node-1:zoneA, zone-node-2:zoneB, zone-node-3:zoneA 不开任何awareness设置,连续PUT 6个索引 zt_noaware1..6,均1主1副
zt_noaware : zone-node-1(zoneA) + zone-node-2(zoneB) → 跨区 ✓ zt_noaware1 : zone-node-1(zoneA) + zone-node-3(zoneA) → 真实同区!✗ zt_noaware2 : zone-node-2(zoneB) + zone-node-3(zoneA) → 跨区 ✓ zt_noaware3 : zone-node-1(zoneA) + zone-node-2(zoneB) → 跨区 ✓ zt_noaware4 : zone-node-1(zoneA) + zone-node-3(zoneA) → 真实同区!✗ zt_noaware5 : zone-node-2(zoneB) + zone-node-3(zoneA) → 跨区 ✓
这组真实数据直接暴露了不开zone awareness时的真实风险:ES默认的分配均衡器真实只关心"每个节点上的分片数量是否均衡",完全不关心"这些节点分别属于哪个可用区"。本次实测6个索引里,真实有2个(zt_noaware1和zt_noaware4)的主分片和副本被同时放进了zoneA这一个区(分别落在zone-node-1和zone-node-3两台不同的机器上,满足了same_shard决策器"不能放同一个节点"的要求,但两台机器真实都在同一个可用区),一旦zoneA真实整体下线,这2个索引真实会彻底丢失所有数据,不只是丢失冗余。
代码PUT /_cluster/settings {"persistent":{ "cluster.routing.allocation.awareness.attributes":"zone" }} 真实删除刚才的6个索引,重新连续PUT 6个索引 zt_aware1..6,均1主1副
zt_aware1 : zone-node-1(zoneA) + zone-node-2(zoneB) → 跨区 ✓ zt_aware2 : zone-node-2(zoneB) + zone-node-3(zoneA) → 跨区 ✓ zt_aware3 : zone-node-1(zoneA) + zone-node-2(zoneB) → 跨区 ✓ zt_aware4 : zone-node-2(zoneB) + zone-node-3(zoneA) → 跨区 ✓ zt_aware5 : zone-node-1(zoneA) + zone-node-2(zoneB) → 跨区 ✓ zt_aware6 : zone-node-2(zoneB) + zone-node-3(zoneA) → 跨区 ✓
代码真实找到zone-node-2的真实进程PID,kill -9
集群健康: status=yellow (不是red!)
active_primary_shards: 6 ← 真实一个没少
unassigned_shards: 6 ← 真实丢的全部是副本,不是主分片
真实写入测试: POST /zt_aware1/_doc {"n":1}
→ {"result":"created", "_shards":{"successful":1}} ← 真实写入成功
真实读取测试: GET /zt_aware1/_search (refresh后)
→ hits.total.value: 1 ← 真实能正常查到刚写的数据代码真实重启zone-node-2,等待它重新加入集群并完成副本的re-sync 真实kill掉全部3个临时节点进程,rm -rf整个zone-lab目录
zone-node-2重新加入后: → status: "green", number_of_nodes: 3, unassigned_shards: 0 清理完毕后交叉检查本系列一直在用的主力es-lab实例(端口19920): → status: "green", number_of_nodes: 1 ← 真实全程没受任何影响
每一步都是本文在一个真实独立搭建的3节点Elasticsearch 8.15.0集群上跑出来的原始结果。
cluster.routing.allocation.awareness.attributes 设置