Fork me on GitHub

版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | http://vearne.cc

1. 前言

前几天有人在群里问,es是否可以指定某个字段为路由值。ES自定义的doc的路由,不过es的操作是,在写入一个doc时,指定doc的routing key。

2. 例子

2.1 创建一个新的index

PUT /my_index2
{
  "settings": {
    "index": {
      "number_of_shards": 2,
      "number_of_replicas": 1
    }
  }
}

image_1cugf5upa347r7i1vrd1sprcgd9.png-22.6kB
index只有2个shardshard 0和 shard 1

2.2 设置mapping

PUT /my_index2/_mapping/student
{
    "_routing": {
        "required": true
    },
    "properties": {
        "name": {
            "type": "keyword"
        },
        "age": {
            "type": "integer"
        }
    }
}

2.3 指定doc路由

PUT /my_index2/student/1?routing=key1
{
    "name":"n1",
    "age":10
}
PUT /my_index2/student/2?routing=key1
{
    "name":"n2",
    "age":10
}
PUT /my_index2/student/3?routing=key1
{
    "name":"n3",
    "age":10
}

上面的3条命令会使得doc1、2、3放置在同一个shard上
shard 0
屏幕快照 2018-12-12 下午1.54.14.png-95.8kB

shard 1
屏幕快照 2018-12-12 下午1.52.34.png-70.7kB

shard 0上的doc数是0,shard 1上的doc数是3,可见doc的分布是按照我们的要求来执行的。
shard的具体编号由以下公式决定

shard_num = hash(_routing) % num_primary_shards

3. 作用

那么自定义routing到底有什么作用呢?
我们知道,正常的一次查询(search),请求会被发给所有shard(不考虑副本),然后等所有shard返回,再将结果聚合,返回给调用方。如果我们事先已经知道数据可能分布在哪些shard上,那么就可以减少不必要的请求。

GET /_search_shards?routing=key1

返回

{
    "shards": [
        [
            {
                "state": "STARTED",
                "primary": true, // 主副本
                "node": "uf_-1wJHSEqgQmgPxanZJA",
                "relocating_node": null,
                "shard": 1,  // 只需要检索`shard` 1
                "index": "my_index2",
                "allocation_id": {
                    "id": "tZzcW3DRQ12QzGJXvVswvQ"
                }
            },
            {
                "state": "STARTED",
                "primary": false, // 从副本
                "node": "3bo9Z0krShyAK-t_F5Fo8A",
                "relocating_node": null,
                "shard": 1,  // 只需要检索`shard` 1
                "index": "my_index2",
                "allocation_id": {
                    "id": "NWILXOXcTGCXYHrgPJ6_-A"
                }
            }
        ]
    ]
}

下面的查询只会检索与routing key,”key1″和”key2″相关的shard

GET /my_index2/_search?routing=key1,key2
{
  "query": {
    "term": {
      "name": "n2"
    }
  }
}

其它

The default value used for _routing is the document’s _id.

因此在不自定义routing的情况下,形如

GET /my_index1/student/1

只会命中单个shard,效率也并不低。

参考资料

  1. mapping-routing-field

如果我的文章对你有帮助,你可以给我打赏以促使我拿出更多的时间和精力来分享我的经验和思考总结。

微信支付码

发表评论

电子邮件地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据