欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 美景 > Elasticsearch搜索优化-自定义路由规划(routing)

Elasticsearch搜索优化-自定义路由规划(routing)

2024/10/24 13:18:34 来源:https://blog.csdn.net/lovejj1994/article/details/139437631  浏览:    关键词:Elasticsearch搜索优化-自定义路由规划(routing)

在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,

index.routing_partition_size

当使用了路由,可以让路由相同的文档分配到同一个分片上,从而减少查询时需要的分片数,提高查询效率。但是使用该参数容易导致数据不平衡。为此,ES还提供了一个index.routing_partition_size参数,用于将路由相同的文档映射到不止一个分片上,默认值是1,这样一方面可以减少查询的分片数,另一方面又可以在一定程度上防止分片数据不平衡。引入该参数后计算公式如下

shard_num = (hash(_routing) + hash(_id) % routing_partition_size) % num_primary_shards

这个参数只是对上面公式的进一步延申,我在索引参数中设置了2,说明在这个3个分片的索引中,路由相同的文档分配到其中2个分片上,后面我们导入数据时看看效果。

index.number_of_routing_shards

当在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,跟主分片数量一样。

Unique IDs with custom routing

其次,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等问题。所以要充分了解其机制再去使用(这里再次推荐看下官方文档),避免反向优化。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com