求es查询优化方法
匿名 | 发布于2018年07月16日 | 阅读数:2529
集群现在5个master、3个client、8个data,master和client都是16核cpu、data是8核cpu,都开了超线程,内存都128G,jvm内存xms和xmx都设置30G。elasticsearch.yml见附件。
索引按小时分表,每个索引是5千万-1.2亿条记录,每条记录30个字段。索引会预先建立好mapping,语句如下:
curl -XPUT "http://node1:9200/transcode_2018071401" -d '{"settings" : {"number_of_shards" : 5,"number_of_replicas" : 1, "index.refresh_interval":"30s","index.translog.sync_interval":"5s","index.translog.flush_threshold_size":"4096mb", "index.translog.durability": "async","index.unassigned.node_left.delayed_timeout":"5m"},"aliases":{"transcode_20180714":{},"transcode_201807":{}},"mappings":{"data":{"properties":{"time":{"type":"integer"},"pkgCount":{"type":"integer"},"bytesNum":{"type":"integer"},"stream_id":{"type":"keyword","norms": false}}}}}' -H "Content-type:application/json"
用java程序多线程并行插入数据,插入时指定了routing,值为stream_id字段的值,每秒大概2.5w条数据。
现在需要查询某个时间段内,按照字段stream_id和ip字段的int_ip(ip为struct结构)的值过滤,返回大量的数据(因为前端要用折线图展示,得一下子返回全量数据),查最近两三个小时的数,大概有10000条吧。
目前的处理方式是,在代码里,根据时间段,找到对应的几个小时索引,然后一个索引一个请求 curl node1:9200/_search/ xxx ,多个请求同时发出,并行查询,再对返回的多个结果进行汇总。查询的时候按stream_id字段值路由,请求语句如下:
curl "http://node1:9200/transcode_20 ... ot%3B -X GET -H "Content-type:application/json" -d '{"size":"1001","query":{"bool":{"filter":{"bool":{"must":[{"term":{"stream_id":"jcd9734d813ad"}},{"term":{"ip.int_ip":-776921847}},{"range":{"time":{"from":1531647004,"to":null}}}]}}}},"_source":{"includes":["ip","time","pkgCount","bytesNum"]},"sort":[{"_doc":{"order":"asc"}}]}'
第一次拉取,返回的数据都是几百条的情况下,耗时慢的要十几秒,快的几百毫秒
然后拿到一批返回的_scroll_id,
同样对这批_scroll_id并行使用:
curl "http://node1:9200/_search/scroll" -X GET -H "Content-type:application/json" -d \'{"scroll":"30s","scroll_id":"'.$scrollId.'"}\''
查询,再对返回的_scroll_id并行查询,直到拉完数据。
这步的速度也不稳定,一次拉取有的时候只要几百毫秒,有的时候要一两秒。
跪求优化建议
索引按小时分表,每个索引是5千万-1.2亿条记录,每条记录30个字段。索引会预先建立好mapping,语句如下:
curl -XPUT "http://node1:9200/transcode_2018071401" -d '{"settings" : {"number_of_shards" : 5,"number_of_replicas" : 1, "index.refresh_interval":"30s","index.translog.sync_interval":"5s","index.translog.flush_threshold_size":"4096mb", "index.translog.durability": "async","index.unassigned.node_left.delayed_timeout":"5m"},"aliases":{"transcode_20180714":{},"transcode_201807":{}},"mappings":{"data":{"properties":{"time":{"type":"integer"},"pkgCount":{"type":"integer"},"bytesNum":{"type":"integer"},"stream_id":{"type":"keyword","norms": false}}}}}' -H "Content-type:application/json"
用java程序多线程并行插入数据,插入时指定了routing,值为stream_id字段的值,每秒大概2.5w条数据。
现在需要查询某个时间段内,按照字段stream_id和ip字段的int_ip(ip为struct结构)的值过滤,返回大量的数据(因为前端要用折线图展示,得一下子返回全量数据),查最近两三个小时的数,大概有10000条吧。
目前的处理方式是,在代码里,根据时间段,找到对应的几个小时索引,然后一个索引一个请求 curl node1:9200/_search/ xxx ,多个请求同时发出,并行查询,再对返回的多个结果进行汇总。查询的时候按stream_id字段值路由,请求语句如下:
curl "http://node1:9200/transcode_20 ... ot%3B -X GET -H "Content-type:application/json" -d '{"size":"1001","query":{"bool":{"filter":{"bool":{"must":[{"term":{"stream_id":"jcd9734d813ad"}},{"term":{"ip.int_ip":-776921847}},{"range":{"time":{"from":1531647004,"to":null}}}]}}}},"_source":{"includes":["ip","time","pkgCount","bytesNum"]},"sort":[{"_doc":{"order":"asc"}}]}'
第一次拉取,返回的数据都是几百条的情况下,耗时慢的要十几秒,快的几百毫秒
然后拿到一批返回的_scroll_id,
同样对这批_scroll_id并行使用:
curl "http://node1:9200/_search/scroll" -X GET -H "Content-type:application/json" -d \'{"scroll":"30s","scroll_id":"'.$scrollId.'"}\''
查询,再对返回的_scroll_id并行查询,直到拉完数据。
这步的速度也不稳定,一次拉取有的时候只要几百毫秒,有的时候要一两秒。
跪求优化建议
1 个回复
laoyang360 - 《一本书讲透Elasticsearch》作者,Elastic认证工程师 [死磕Elasitcsearch]知识星球地址:http://t.cn/RmwM3N9;微信公众号:铭毅天下; 博客:https://elastic.blog.csdn.net
赞同来自:
"stream_id"是keyword类型吗?
"ip.int_ip":-776921847 这里是负数吗?
"to":null确认时间没有结束时刻? 这几个点可以考虑优化下。