真实把一个alias同时指向两个索引,验证写入时的歧义拒绝、is_write_index如何消歧,以及读取操作为什么完全不受这层限制影响。
代码POST /_aliases {"actions": [ {"add": {"index": "alias_idx1", "alias": "multi_alias"}}, {"add": {"index": "alias_idx2", "alias": "multi_alias"}} ]} POST /multi_alias/_doc {"a": 2} # 往这个alias写一条新文档 GET /multi_alias/_search # 从这个alias读数据
POST /multi_alias/_doc {"a": 2}
→ 400 illegal_argument_exception:
"no write index is defined for alias [multi_alias]. The write index may be
explicitly disabled using is_write_index=false or the alias points to
multiple indices without one being designated as a write index"这是真实合理的设计:如果一个alias真实同时指向两个索引,ES没有办法替调用方决定"这条新文档到底该写进哪一个",与其悄悄挑一个(可能是别的系统依赖的顺序,不稳定也不可控),ES真实选择直接拒绝这次写入,把这个决定权交还给调用方——不管写入时有没有显式指定文档ID,这条规则真实都一视同仁地生效。
POST /_aliases {"actions": [
{"add": {"index": "alias_idx1", "alias": "multi_alias", "is_write_index": true}}
]}
POST /multi_alias/_doc {"a": 2}
→ {"_index": "alias_idx1", "result": "created", ...} ← 真实写进了alias_idx1alias_idx1里有一条{"a":2},alias_idx2里有一条{"a":3}
GET /multi_alias/_search {"query":{"match_all":{}}}
→ hits.total = 2
alias_idx1: {"a": 2}
alias_idx2: {"a": 3}
真实两条数据都被搜到了,尽管只有alias_idx1被标记成了write_index这是本文认为这篇最该记住的真实结论:write_index这个限制只影响写入,完全不影响搜索——查询一个多索引的alias,ES真实会把它当成对所有成员索引做一次跨索引的联合搜索,不管这些索引里哪个被标记成了write_index,数据都真实会被同时检索到。应用代码用alias而不是直接用索引名字访问数据的真实价值正在于此:读写双方都通过同一个稳定的alias名字操作,底层真实有多少个索引、哪个在接收新数据、哪个只是历史数据的只读分区,这些细节对使用alias的代码完全透明。
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
_aliases API 与 is_write_index