【es】索引的路由规则

1.索引数据路由的原理 

默认,ES使用如下公式决定数据写入的分片编号 
shard_num=hash(_routing)% num_primary_shards 

默认情况下 _routing 的值时文档的_id 值,也就是根据主键的散列值对分片数进行取模运算,
得到写入分片的编号。如果允许主分片数量发送改变,就意味着所有的数据需要重新路由,
因此ES禁止在索引建立以后修改主分片的数量。实际上,_routing 的值可以定义为
任意一个字段内容甚至时任意一个字符串。可以自定义路由值。

需要注意:虽然手动指定路由值可以减少查询使用的分片数,但是这有可能引发大量的数据被
路由到少数几个分片,而其余的很多分片数据量太少,使得分片的大小不均匀。
ES 为了解决这个问题,提供了索引分区的配置,允许使用同一个路由的数据被分发到多个分片 
而不是一个分片,该配置需要在索引的 index.routing_partition_size 中进行设置。
当配置 index.routing_partition_size 后,分片编号的计算公式为: 
shard_num=(hash(_routing)+hash(_id)% routing_partition_size) % num_primary_shards 

这是分片编号的计算结果由路由值和主键共同决定。
但是又引发另外一个问题:
routing_partition_size > 1 时,可以让同一个routing 值的记录分散在多个分片上。但是 Join在索引中
不可用,因为join 字段要求同一路由值的文档必须写入同一个分片。这两者时背道而驰的。

要使用 join ,routing_partition_size 就不能使用。
要使用 routing_partition_size,join 就不能使用。 

主键+路由值决定分片 
2.使用自定义路由分发数据 

(1)创建一个新的索引 
curl  -u elastic:elastic  -k -XPUT http://192.168.1.800:9200/test-3-3-2  -H 'Content-Type: application/json' -d  '
{
 "settings":{
  "number_of_shards":"3",
  "number_of_replicas":"1"
 },
 "mappings":{
  "_routing":{"required":true}
 }
}'

查询该索引时必须使用路由值。
(2)添加数据 
curl  -u elastic:elastic  -k -XPOST "http://192.168.1.800:9200/test-3-3-2/_doc/1?routing=张三&refresh=true"  -H 'Content-Type: application/json' -d  '
{
 "id":"1",
 "name":"张三",
 "subject":"语文",
 "score":100
}'

(3)根据路由值查询 
curl  -u elastic:elastic  -k -XGET "http://192.168.1.800:9200/test-3-3-2/_doc/1?routing=张三"
{
    "_index":"test-3-3-2",
    "_type":"_doc",
    "_id":"1",
    "_version":1,
    "_seq_no":0,
    "_primary_term":1,
    "_routing":"张三",
    "found":true,
    "_source":{
        "id":"1",
        "name":"张三",
        "subject":"语文",
        "score":100
    }
}

(4)当修改数据时要带上路由值 
curl  -u elastic:elastic  -k -XPOST "http://192.168.1.800:9200/test-3-3-2/_update/1?routing=张三&refresh=true" -H 'Content-Type: application/json' -d  '
{
 "doc":{"score":230}
}'

当检索数据时,如果带上路由值,可以跳过无法的分片,能减少资源的占用和加快查询速度。
curl  -u elastic:elastic  -k -XGET "http://192.168.1.800:9200/test-3-3-2/_search?routing=张三" -H 'Content-Type: application/json' -d  '
{
 "query":{"match_all":{}}
}'
全表查询 
{
    "took":3,
    "timed_out":false,
    "_shards":{
        "total":1,
        "successful":1,
        "skipped":0,
        "failed":0
    },
    "hits":{
        "total":{
            "value":1,
            "relation":"eq"
        },
        "max_score":1,
        "hits":[
            {
                "_index":"test-3-3-2",
                "_type":"_doc",
                "_id":"1",
                "_score":1,
                "_routing":"?? ??",
                "_source":{
                    "id":"1",
                    "name":"张三",
                    "subject":"语文",
                    "score":230
                }
            }
        ]
    }
}

如果想查看某个路由值会检索到哪个分片,可以使用REST端点。
curl  -u elastic:elastic  -k -XGET "http://192.168.1.800:9200/test-3-3-2/_search_shards?routing=张三" 

{
    "nodes":{
        "ziwZn3mQQ4-LH-6vLuYMUw":{
            "name":"node-1",
            "ephemeral_id":"9rkx_e4-SuuikCAbY3LAYw",
            "transport_address":"192.168.1.800:9300",
            "attributes":{
                "xpack.installed":"true",
                "zone":"zone1",
                "transform.node":"true"
            },
            "roles":[
                "data",
                "data_cold",
                "data_content",
                "data_frozen",
                "data_hot",
                "data_warm",
                "ingest",
                "master",
                "remote_cluster_client",
                "transform"
            ]
        },
        "xT-aakS2RficXV5PI2fU9Q":{
            "name":"node-2",
            "ephemeral_id":"uQl3l6QkTXOIqY8GgRe_-A",
            "transport_address":"192.168.1.808:9300",
            "attributes":{
                "ml.machine_memory":"4129558528",
                "ml.max_open_jobs":"512",
                "xpack.installed":"true",
                "ml.max_jvm_size":"524288000",
                "zone":"zone2",
                "transform.node":"true"
            },
            "roles":[
                "data",
                "data_cold",
                "data_content",
                "data_frozen",
                "data_hot",
                "data_warm",
                "ingest",
                "master",
                "ml",
                "remote_cluster_client",
                "transform"
            ]
        }
    },
    "indices":{
        "test-3-3-2":{

        }
    },
    "shards":[
        [
            {
                "state":"STARTED",
                "primary":true,
                "node":"ziwZn3mQQ4-LH-6vLuYMUw",
                "relocating_node":null,
                "shard":2,
                "index":"test-3-3-2",
                "allocation_id":{
                    "id":"cKpApPwsTyaARC7i9PKr6Q"
                }
            },
            {
                "state":"STARTED",
                "primary":false,
                "node":"xT-aakS2RficXV5PI2fU9Q",
                "relocating_node":null,
                "shard":2,
                "index":"test-3-3-2",
                "allocation_id":{
                    "id":"z-jwkFBUQzuBwxmxOJw-iA"
                }
            }
        ]
    ]
}

由此可见,该文档只在分片2上。shard:2;
总结:
自定义路由能够减少查询的分片的数量,从而加快查询速度.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值