Fork me on GitHub

版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | https://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

请我喝瓶饮料

微信支付码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注