记一次Elasticsearch查询性能优化

4 篇文章 0 订阅

 

背景:在数据和服务都准备完成的情况下,打开页面,发现请求需要要几秒才返回;

思路:1.查看搜索接口请求本身耗时情况,排除网络抖动因素,发现搜索接口请求到ES返回结果本身耗时较高;

2.检查每次请求到ES的入参,并在原有参数中加入"profile": true,查看ES处理搜索请求的耗时分布情况;
入参:

返回:

发现只是一个简单的termQuery耗时818ms,然后查看是否ES集群负载情况;
3.初步定位:ES集群的cpu和内存消耗较大,磁盘io写入较高,认为是数据同步服务不断的在提交索引建立请求导致ES集群负载较高,影响了查询性能;

4.初步解决:停掉数据同步服务,使ES集群负载降下来,再做查询,发现搜索响应时间没有任何变化,继而再次监控ES机器磁盘IO;
5.再次定位:发现每次搜索请求时,磁盘需要读40M+的数据,然而一次请求的数据不过10+k,考虑到搜索的索引文件是由多个segment组成,这里是读取多个segment到内存进行查询匹配,打开segment分布情况发现一个索引节点有多个小的segment,判断是由于打开多个文件随机读写提升了读取索引数据耗时;
iostat

curl 'http://xxxx:9200/_cat/segments/m_pd_cu_id_wifi_2es_inc_hi_out?v&h=shard,segment,size,size.memory'

6.再次解决:手动合并segment,几分钟后合并完成,并进行搜索,性能显著提升,问题解决;
curl -XPOST 'http://xxxx:9200/_forcemerge?max_num_segments=1'

7.永久解决:加配置项index.merge.policy.floor_segment=设置每个segment最小值,index.merge.scheduler.max_thread_count=ES集群负载较低时,后台合并segment线程数,一般=核数/2;
curl -XPUT http://xxxx:9200/m_pd_cu_id_ip_2es_inc_hi_out/_settings -d '{"index.merge.policy.floor_segment":"100mb"}'
curl -XPUT http://xx:9200/m_pd_cu_id_rela_address_2es_dt_out/_settings -d '{"index.merge.scheduler.max_thread_count":"2"}'
原因分析:数据同步服务不断的在提交索引构建,ES集群接收到构建请求数据后会缓冲到内存,达到一定量后生成segment,每个segment是一个包含正排(空间占比90~95%)+倒排(空间占比5~10%)的完整索引文件,每次搜索请求会将所有segment中的倒排索引部分加载到内存,进行查询和打分,然后将命中的文档号拿到正排中召回完整数据记录;如果不对segment做配置,提交又特别频繁的话,就会导致查询性能下降,另外将这里的普通硬盘换成SSD,预计搜索性能还会提升3~5倍;

【总结】
搜索性能优化建议:
1.segment合并;索引节点粒度配置index.merge.policy.floor_segment=xx mb;segment默认最小值2M
2.索引时不需要做打分的字段,关闭norms选项,减少倒排索引内存占用量;字段粒度配置omit_norms=true;
3.BoolQuery 优于 TermQuery;目前需求场景全部不需要用到分词,所以尽可能用BoolQuery;
4.避免使用对象嵌套结构组建document,建议优化为一个扁平化结构,查询多个扁平化结构在内存做聚合关联;
5.设定字符串类型为不分词,可以用于字符串排序,但是比起数字排序会消耗cpu,搜索效率更低,慎用;
6.cache设置,就目前数据业务类型,保持默认配置即可,设值fielddata.cache之类的缓存命中率低,反而吃掉了ES集群的一部分内存;

索引性能优化建议:
1.调小索引副本数;针对索引节点粒度:curl -XPUT http://xxxx:9200/m_pd_cu_id_gps_2es_inc_hi_out/_settings -d '{"number_of_replicas":1}'
2.设置延迟提交,延迟提交意味着数据提交到搜索可见,有延迟,需要结合业务配置;针对索引节点粒度:curl -XPUT http://xxxx:9200/m_pd_cu_id_gps_2es_inc_hi_out/_settings -d '{"index.refresh_interval":"10s"}';默认值1s;
3.设置索引缓冲buffer,最大512m,默认值是jvm的10%;ES集群粒度config/elasticsearch.yml :indices.memory.index_buffer_size = 10%

4.适当减少备份数,必要字段只需要提供搜索,不需要返回则将stored设为false;

如果ES提交索引请求达到瓶颈,一般任务队列task-queue为50,可以设置task-queue队列,提升搜索集群索引能力;


以上涉及到索引节点/字段 粒度的配置,均可在创建时代码指定;

 

  • 8
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值