《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.2.Elasticsearch基础应用——3.4.2.11.Index alias(4) https://developer.aliyun.com/article/1230375
路由别名
将路由字段绑定到对应的别名,通过别名操作时,会执行默认的路由规则,也可以理解为索引的另外一种“视图”。使用路由别名,在一定程度提升写入和查询的性能,结合过滤别名,可以让操作发送到准确的分片上。
如下示例首先创建一个索引,因为本文演示的 Elasticsearch 集群只有两个数据节点,为了方便观察,设置副本数目为 0,主分片数目设置为 2。
PUT /routing-index-000001 { "settings" :{ "index":{ "number_of_shards":2, "number_of_replicas": 0 } }, "mappings": { "properties": { "user": { "properties": { "id": { "type": "keyword" } } } } } }
创建一个路由别名routing-index-alias1绑定索引routing-index-000001。
POST /_aliases { "actions": [ { "add": { "index": "routing-index-000001", "alias": "routing-index-alias1", "routing": "2" } } ] }
创建成功之后,使用别名进行的所有操作,都将以 2 计算路由地址,使用别名写入一个文档。
PUT routing-index-alias1/_bulk {"index":{}} {"user.id":"kimchy"}
除了创建一个路由别名,也可以用索引在写入文档时,后面加上路由参数;往routing-index-000001索引写入两个文档,并指定路由参数为 12。
PUT routing-index-000001/_bulk?routing=12 {"index":{}} {"user.id":"tom"} {"index":{}} {"user.id":"jerry"}
通过查看GET _cat/shards/routing-index-000001?v&h=index,shard,prirep,docs,node,可以发现routing=12的文档被写到了 1 号分片,routing=2的文档被写到了 0 号分片。
index shard prirep docs node routing-index-000001 1 p 2 es-cn-n6w24fib900797tgz-29e2dafd-0003 routing-index-000001 0 p 1 es-cn-n6w24fib900797tgz-29e2dafd-0001
为了验证结果是不是这样的,我可以执行以下 3 种查询进行验证。前两个查询的是等效的,都是以 2 为计算路由值,将返回user.id为kimchy一个文档;第三个查询语句将返回以routing=12写入的文档。
GET /routing-index-alias1/_search GET /routing-index-000001/_search?routing=2 GET /routing-index-000001/_search?routing=12
查询的时候,使用别名查询或者查询参数指定路由值,查询效果是等价的。routing的值并不一定要等于2,只要满足hash函数计算出来的结果一样,定位到分片结果一致。为了保证能够正确查询到文档,建议routing的值和写入的值保持一致。
除了统一设置一个routing,还可以分别设置对不同动作生效的路由。
如下面分别设置查询路由(search_routing)和写入路由(index_routing),使用别名进行操作,查询请求会发送到路由值 12 和 2 对应的分片,写入操作只会写入路由12对应的分片。
POST /_aliases { "actions": [ { "add": { "index": "routing-index-000001", "alias": "routing-index-alias2", "search_routing": "12,2", "index_routing": "12" } } ] }
如上代码块所示search_routing可以由多个以逗号分隔的路由值,index_routing只能有一个值。
其实这也比较好理解,写入的时候,通过一个路由值计算数据,应该写到具体哪个分片,如果写入有多个路由值,将无法确定写入到哪一个分片;一个给定的分片上,可以有很多拥有不同路由值的文档,因此在查询的时候可以写多个路由值。
使用路由别名查询并且参数重新指定routing值;若search_routing的和路径参数routing的个数大于 2,则取两者的交集作为路由参数;若小于等于2且没有交集,则取search_routing的值(写入路由同理)。如下代码是查询不到任何文档的,因为其取交集后的路由值为 2,而包含tom这个文档写入的路由值为 12,所以将查询到对应的内容。
GET /routing-index-alias2/_search?q=user.id:tom&routing=2
正如所预期的一样返回内容如下:
{ "took" : 2, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 0, "relation" : "eq" }, "max_score" : null, "hits" : [ ] } }
《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.2.Elasticsearch基础应用——3.4.2.11.Index alias(6) https://developer.aliyun.com/article/1230372