在es的实践学习中,我觉得它的文档是最好的老师,所以先把这部分链接贴出来,本文只是引导,文档全是细节,还是推荐大家事后认真看看文档
Metadata fields-routing
在es搜索中,请求是先分发到所有分片,然后聚合结果返回,如果我们将相同业务领域的数据聚集到同一个或者少部分分片,搜索的时候只搜索这几个分片,那么将会减少机器压力,提高搜索性能。
在没有指定路由的情况,所有的数据是依据文档_id(_routing的默认为_id),然后套公式均匀的分发到分片中,公式如下:
//我这边用的是7.9.3版本,我看7.17的公式多加了一个num_routing_shards参数,分片算法改进但本质结果没有变。
shard_num = hash(_routing) % num_primary_shards
从公式中我们可以看到id的不同必然导致文档会分散到不同的分片中,这就是没有自定义路由的普遍情况。
如何指定路由要分析产品需求和数据上的相通性,就拿商品搜索来说,商品分布在不同的门店,而同一门店的商品可能会有列表搜索,有了这么一个需求,那么同一门店的商品是不是放在一个分片里是最好选择?
分析好需求以后我们确定了针对门店编码做路由,首先我们简单建立一个索引
PUT ***/routing
{
"settings": {
"number_of_shards": "3",
"number_of_replicas": "3",
"index.routing_partition_size": "2",
"index.number_of_routing_shards": "3"
},
"mappings": {
"_routing": {
"required": true
}
}
}
除了指定了常见的分片数,副本数,还有两个新的参数index.routing_partition_size和
index.number_of_routing_shards,
当使用了路由,可以让路由相同的文档分配到同一个分片上,从而减少查询时需要的分片数,提高查询效率。但是使用该参数容易导致数据不平衡。为此,ES还提供了一个index.routing_partition_size参数,用于将路由相同的文档映射到不止一个分片上,默认值是1,这样一方面可以减少查询的分片数,另一方面又可以在一定程度上防止分片数据不平衡。引入该参数后计算公式如下
shard_num = (hash(_routing) + hash(_id) % routing_partition_size) % num_primary_shards
这个参数只是对上面公式的进一步延申,我在索引参数中设置了2,说明在这个3个分片的索引中,路由相同的文档分配到其中2个分片上,后面我们导入数据时看看效果。
当在es中使用自定义路由时,路由分片的数量(number_of_routing_shards)决定了有多少分片用于路由。如果不指定此设置,则无论设置的分区大小(routing_partition_size)是多少,都只使用一个分片进行路由。为了确保正确实现分区大小,请将number_of_routing_shards设置为索引中的主分片数(number_of_shards)。这将确保根据指定的路由分片大小(number_of_routing_shards)使用预期数量的分片(number_of_routing_shards)进行路由。
在很多资料中,只提了routing_partition_size但是没有提number_of_routing_shards,如果不设置number_of_routing_shards,routing_partition_size的作用就会失效,这里着重强调,我在例子中设置了3,跟主分片数量一样。
其次,mappings里_routing的required值为true,会让使用自定义路由时,每当保存、获取、删除或更新文档时,都必须提供路由值,否则报错。我们要明白一点,如果不强制设置这个必填,会导致一条数据在多个分片中出现,没错,连_id都会一模一样,因为在es机制中,不同的路由值下的_id才必须是唯一的。这一条规则(Unique IDs with custom routing)文档也有写清。
同一个routing随意导入若干条数据,看看数据分片的情况
插入数据
POST http://***/routing/_doc?routing=107U
{
"shopCode": "107U"
}
查询分片情况:
GET
http://***/_cat/shards/routing?v
可以看到在同一个路由的情况下,数据只分布在2个分片中,符合预期。
index shard prirep state docs store ip node
routing 1 p STARTED 13 5.1kb 10.6.11.20 node-2
routing 1 r STARTED 13 5.1kb 10.6.11.20 node-1
routing 1 r STARTED 13 5.1kb 10.6.11.20 node-3
routing 2 r STARTED 7 4.8kb 10.6.11.20 node-2
routing 2 r STARTED 7 4.8kb 10.6.11.20 node-1
routing 2 p STARTED 7 4.8kb 10.6.11.20 node-3
routing 0 r STARTED 0 208b 10.6.11.20 node-2
routing 0 p STARTED 0 208b 10.6.11.20 node-1
routing 0 r STARTED 0 208b 10.6.11.20 node-3
自定义路由在用户了解查询需求和业务的基础之上,可以对查询性能进行优化,然而使用不当会导致数据不平衡,重复ID等问题。所以要充分了解其机制再去使用(这里再次推荐看下官方文档),避免反向优化。