Routing

ES集群由于多个节点组成,每个索引又有多个分片,想要读写文档就必须知道文档被分配在哪个分片上,这也正是routing功能的作用。

routing参数是一个可选参数,默认使用文档的_id值,可以用在INDEX, UPDATE,GET, SEARCH, DELETE等各种操作中。在写入(包括更新)时,用于计算文档所属分片,在查询(GET请求或指定了routing的查询)中用于限制查询范围,提高查询速度。

shard id的计算

ES中shard Id的计算公式如下:

shardId = hash(_routing) % num_primary_shards

例:假设有一个index有三个主分片P0,P1,P2,现在需要新增文档

(1)新增文档时,都会带有一个routing number,这个routing number默认为文档的_id,而这个_id可以自己指定,也可以系统生成。假如指定了_id=1

(2)将这个routing number的值1传入hash函数,然后计算出一个hash值,假如为20,即:hash(routing)=20

(3)将生成的这个hash值和number_of_primary_shards做模运算【这个结果的范围:0~number_of_primary_shards – 1】,得到余数,即:20 % 3 = 2,这个余数2就表示文档所在的shard,即P2

通过该公式可以保证使用相同routing的文档被分配到同一个shard上,当然在默认情况下使用_id作为routing起到将文档均匀分布到多个分片上防止数据倾斜的作用。


在查询数据时,同样经历shard id的运算过程:

image-20220709092405007

何时使用指定routing值

默认routing规则: 默认按照_id完成的

自定义routing: 在发送索引请求的时候,可以手动指定一个routing value,如:

PUT /test_index/test_type/id?routing=test_id

作用: 手动指定routing可以保证某一类的document一定会被路由到某一个shard上去,在后续进行应用的负载均衡时可以提升读取性能。