你不会是程序猿吧?

虚拟机上,Elasticsearch 单索引文件越大,查询性能越来越差,如何优化?

Elasticsearch | 作者 piaofeng84 | 发布于2017年06月02日 | 阅读数:9165

进行模拟测试,不断的存储,每s 400条记录,然后每隔半个小时查一次上个半小时的记录,能够查到72w条。发现记录数越来越多的时候,查询时间越来越长,这个有什么优化的方法吗? 虚拟机4G的内存,jvm内存大概3G,而且记录数到1000w左右,开始OOM了,内存回收不了呢?
已邀请:

kennywu76 - Wood

赞同来自: piaofeng84

下面三个设置完全没帮助,可以去掉:


index.cache.field.type: soft
index.cache.field.expire: 10m
index.fielddata.cache.size: 30%
 


从你贴的状态信息看,索引文件本身消耗的内存,以及各类cache消耗的内存都非常非常小!
 
问题应该是搜索语句本身引起的。  你给的搜索Param本身的确是很简单,但是否搜索的时候会fetch非常多的数据回来?也就是搜索参数里的from + size会比较大?  因为我看到集群设置里有下面这个设置:


# Required for Kibana 4.x support
index.max_result_window: 2147483647


max_result_window大小默认是1万,你们改成了21亿,想必是有查询场景需要用到这么大的值?
 
如果一次查询真有上千万,甚至上亿的数据返回,会是非常大的问题,需要消耗非常多的内存!  ES这个值默认设置为1万,就是为了防止这种情况的发生。

novia - 1&0

赞同来自:

机器配置太差了

piaofeng84

赞同来自:

机器配置是不高,但是每s的数据量其实也不多。有没有在当前机器性能情况下的什么优化方法呢?

leighton_buaa

赞同来自:

你把不需要分词的字段的mapping设置为keyword,同事diable "_all" 试试

piaofeng84

赞同来自:

我想实验下下面几个配置,不懂有没有用:
index.cache.field.type: soft
index.cache.field.expire: 10m
index.fielddata.cache.size: 30%

piaofeng84

赞同来自:

其实我做过另外一个试验,进行半个小时的分表查询,之前是天表,半个小时分表的方案其实是不会出现OOM的,性能也稳定,因为每张表的数据记录是固定的。 但是怕跨表查询性能怕,所以还是想优化天表这种方式。

kennywu76 - Wood

赞同来自:

1个索引,1000万的数据,写入量400/s,查询又没有什么量(半小时才查一次?)的情况下, 4GB内存的虚拟机完全够用。  如果用的ES版本不是很老旧,默认的配置已经可以足够好的工作,集群参数不需要任何调优。OOM多半是对ES不熟悉,在集群参数设置上,或者查询方式上存在问题造成的。
 
提供以下信息有助于帮助诊断问题:
1.  集群版本号
2. 集群配置文件elasticsearch.yml
3. 用cat api获取集群的stats,  命令: GET /_cluster/stats 
4. 索引的mapping设置
5. 查询语句

KerwinC

赞同来自:

你把官网上的推荐配置改好了,重要系统配置改好,再出现问题只能是服务器性能不够导致的了,不过我感觉你根本就没有按照官网的推荐配置以及重要系统配置哪里进行修改。

piaofeng84

赞同来自:

@kennywu76,索引创建如图。
查询其实蛮简单的,条件组合如下:
QueryESParm queryESParm = new QueryESParm();
            queryESParm.setLongStartTime(startTime);
            queryESParm.setLongEndTime(endTime);
            List<EsAndCondition> conditionList = new ArrayList<>();
            queryESParm.setAndConditionList(conditionList);
            QueryESParm.AddCondition(conditionList, "device_id", deviceId);
            QueryESParm.AddCondition(conditionList, "web_id", String.valueOf(webid));
            QueryESParm.AddCondition(conditionList, "client_ip", ip.getValue());

youryida - 简单的事情细心做!

赞同来自:

看看是否已经用到了虚拟内存

要回复问题请先登录注册