本机单节点Elasticsearch集群真实用默认设置建索引,默认1份副本让集群立刻变yellow,allocation/explain确认根因是same_shard决策器;真实验证用wait_for_status=green等待这个索引变green会卡满timeout直接超时,因为这个yellow永远不会自己好;真实把number_of_replicas改成0后集群立刻恢复green,同样的等待请求瞬间返回不再超时。
代码PUT /yt_test # 真实不带任何settings,全部用默认值 GET /yt_test/_settings
yt_test 真实的 number_of_replicas: 1 ← 默认值,不是0 GET /_cluster/health/yt_test: → status: "yellow" → active_primary_shards: 1 → unassigned_shards: 1
这个真实结果说明Elasticsearch的索引默认设置真实是假定生产环境会有多台机器的——默认给每个索引配1份副本,是为了默认情况下就具备基本的高可用能力。但本机真实只有一个单节点的开发测试集群,这份默认的副本配置在这种场景下真实注定无法被满足。
代码GET /_cluster/allocation/explain {"index":"yt_test2","shard":0,"primary":false}
current_state: "unassigned" decider: "same_shard" explanation: "a copy of this shard is already allocated to this node"
代码time curl ".../_cluster/health/yt_test?wait_for_status=green&timeout=3s"
真实等待耗时: 3.018秒(刚好卡在timeout设置的3秒上) 响应: status="yellow", timed_out=true
这是一个真实容易让自动化脚本或者CI流水线卡住的陷阱:很多部署脚本、启动健康检查习惯用wait_for_status=green这个参数等集群"准备好",如果本地或者CI环境里跑的是单节点测试集群、索引又用了默认的副本设置,这个等待真实永远不可能等到green,只会真实一直耗到timeout设置的那个时间点然后超时返回——如果脚本没处理好这种超时场景,真实可能导致流水线莫名其妙地卡住或者报错。
代码PUT /yt_test/_settings {"index.number_of_replicas":0}
改完之后: status="green", unassigned_shards=0 重新发起同样的wait_for_status=green请求: → 真实0.014秒就返回了,status="green", timed_out=false ← 不再等满3秒
代码DELETE /yt_test,yt_test2
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
_cluster/health 的 wait_for_status 参数与 number_of_replicas 设置