# 优化Elasticsearch和OpenSearch集群查询性能
CSS服务中的Elasticsearch和OpenSearch集群在使用前，建议参考本文进行集群的查询性能优化，便于提高集群的查询性能，提升使用效率。
#### 数据查询流程
图1数据查询流程   
![](https://support.huaweicloud.com/bestpractice-css/figure/zh-cn_image_0000001934020406.png "点击放大")
如[图1]所示，以Elasticsearch集群为例，介绍客户端往Elasticsearch或OpenSearch集群发送查询请求的流程。图中的P表示主分片Primary，R表示副本分片Replica，主副分片在数据节点Node里是随机分配的，但是不能在同一个节点里。
1. 客户端向Node1发送查询请求，此时Node1为协调节点。
2. 节点Node1根据查询请求的索引以及其分片分布，进行分片选择；然后将请求转发到Node1、Node2、Node3。
3. 各分片分别执行查询任务；当各分片查询成功后，将查询结果汇聚到Node1，然后协调节点向客户端返回查询结果。
对于某个查询请求，其在节点上默认可并行查询5个分片，多于5个分片时将分批查询；在单个分片内，通过逐个遍历各个Segment的方式查询。
图2Elasticsearch的索引组成   
![](https://support.huaweicloud.com/bestpractice-css/figure/zh-cn_image_0000001961178889.png "点击放大")
#### 查询性能优化
基于Elasticsearch的数据查询流程分析，有以下几种性能优化方案。
表1查询性能优化 
| 优化方案                            | 方案说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
|:---|:---|
| 通过routing减少检索扫描的分片数              | 在数据入库时指定routing值，将数据路由到某个特定的分片，查询时通过该routing值将请求转发到某个特定的分片，而不是相关索引的所有分片，进而提升集群整体的吞吐能力。 Elasticsearch 7.x版本中，设置命令如下： - 指定routing值插入数据 ``` PUT /{index}/_doc/1?routing=user1 { "title": "This is a document" } ```   - 根据routing值去查询数据 ``` GET /{index}/_doc/1?routing=user1 ```    |
| 采用index sorting减少检索扫描的Segments数 | 当请求落到某个分片时，会逐个遍历其Segments，通过使用index sorting，可以使得范围查询、或者排序查询在段内提前终止(early-terminate)。 Elasticsearch 7.x版本中，示例命令如下： ``` //假设需要频繁使用字段date做范围查询。 PUT {index} { "settings": { "index": { "sort.field": "date", "sort.order": "desc" } }, "mappings": { "properties": { "date": { "type": "date" } } } } ```                                                                                                                                                                                                                          |
| 增加query cache提升缓存命中的概率           | 当filter请求在段内执行时，会通过bitset保留其刷选结果，当下一个类似的查询过来时，就可以复用之前查询的结果，以此减少重复查询。 增加query cache可以通过修改集群的参数配置实现，将自定义缓存参数"indices.queries.cache.size"设置为更大的值。具体操作请参见[参数配置](https://support.huaweicloud.com/usermanual-css/css_01_0080.html)，修改参数配置后一定要重启集群使参数生效。                                                                                                                                                                                                                                                                           |
| 提前Forcemerge，减少需要扫描的Segments数   | 对于定期滚动后的只读索引，可以定期执行forcemerge，将小的Segments合并为大的Segments，并将标记为"deleted"状态的文档彻底删除，提升查询效率。 Elasticsearch 7.x版本中，配置示例如下： ``` //假设配置索引forcemerge后segments数量为10个。 POST /{index}/_forcemerge?max_num_segments=10 ```                                                                                                                                                                                                                                                                                                                 |
   
