加配置项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队列,提升搜索集群索引能力;
以上涉及到索引节点/字段 粒度的配置,均可在创建时代码指定;
————————————————
原文链接:https://blog.csdn.net/my201110lc/article/details/81712183
备注: segment合并的影响可能只有5%;现象:”发现每次搜索请求时,磁盘需要读40M+的数据,然而一次请求的数据不过10+k“,这个是由于,es底层的lucene对文件的读取采用了mmap方式,而你的机器内存不足以映射所有的文件,所以前几次查询时,会读磁盘,而mmap读取磁盘会默认预读2M的数据量,这才是你请求10K的数据,却有40M的io的真正原因,预读的2M数据,假设有20条同步不在一个段上,那么就会产生40M的磁盘io。
解决这个问题的方法是设置这个参数:index.store.type为niofs,两种方式,启动时设置yml,对所有索引生效;或者在新建索引时指定settings中,对于已经建好的索引,必须先close,然后修改调用接口修改settings。再提一点,es默认的mmapfs其实是针对内存足够的情况下使用的,也就是堆外内存能把所有的segment数据都加载进来。对于内存不足的情况,用niofs比较合适,因为它不会预读,每次都走磁盘。
index.store.type 为 niofs
curl -XPUT 'http://localhost:9200/twitter/' -d '{
"settings" : {
"index" : {
"store":{
"type":"niofs"
},
"refresh_interval":"60s"
}
}
}'
Mmap fs可能让大索引访问变得缓慢: https://elasticsearch.cn/article/754
总结:
结论: 如果ES结点上会存放海量的索引数据,经常会有大索引(如1TB+)的搜索聚合操作,使用NIOFS会更安全,可以避免很多怪异的性能问题。 |