在日志系统中有时为了数据分析,可能需要提取上百万的数据出来分析,但是elasticsearch 默认只支持10000条数据的提取,超过一万就会错误,如下:
{
"type": "query_phase_execution_exception",
"reason": "Result window is too large, from + size must be less than or equal to: [10000] but was [10002]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting."
}
我们可以通过下面的命令改变index.max_result_window参数来扩大查询的最大记录书。
curl -XPUT http://192.168.46.163:9200/myindex/_settings -d '{ "index" : { "max_result_window" : 100000000}}'
但是这个方法非常的消耗性能。深度分页的代价根源是结果集全局排序,如果去掉全局排序的特性的话查询结果的成本就会很低,scroll就是这样的方式,类似数据库的cursor 。
大家可以通过如下表达式,查询:
GET /old_index/_search?scroll=1m
{
"query": { "match_all": {}},
"sort" : ["_doc"],
"size": 1000
}
这个查询和我们以前的查询没有任何的区别,只是在返回结果里面会多一个scroll_id.然后通过这个id,继续查询。
GET /_search/scroll
{
"scroll": "1m",
"scroll_id" : "cXVlcnlUaGVuRmV0Y2g7NTsxMDk5NDpkUmpiR2FjOFNhNnlCM1ZDMWpWYnRROzEwOTk1OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MTA5OTM6ZFJqYkdhYzhTYTZ5QjNWQzFqVmJ0UTsxMTE5MDpBVUtwN2lxc1FLZV8yRGVjWlI2QUVBOzEwOTk2OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MDs="
}
就会返回下一页的结果。这里注意通过scroll_id 查询时,不需要指定索引,因为id,其实是对于上面条件的hash值,直接集成上面的查询,排序,提取数等。
在使用scroll方式的时候一些优化的地方总结如下
1.保持游标查询窗口设置小一点,本例中为1分钟(这个过期时间的参数很重要,因为保持这个游标查询窗口需要消耗资源,所以我们期望如果不再需要维护这种资源就该早点儿释放掉)。
2.排序最好使用["_doc"],这样是按文档自然属性,是最有效的排序顺序。