在刚开始学习ES的时候,觉得自带的from+size
就足够使用了,但是在后续的学习中,不断看到一种说法,就是from+siz
e,在要获取10000+10
的时候就很影响性能。既然我们使用elasticsearch
来处理大数据,那取10000
条数据简直不要太随便,况且size
默认不能超过10000
,超过的话还要设置index.max_result_window
参数,实在麻烦。所以博主这里使用scroll
来实现数据的遍历查询。
相关链接:
Elasticsearch:from&size返回值最大记录的修改设置
Elasticsearch——分页查询From&Size VS scroll
相关概念请看上面两篇博文,咱们这里不一一赘述了,直接开始php操作
1、在es-php使用scroll的文档
官方scroll文档:https://www.elastic.co/guide/cn/elasticsearch/php/current/search_operations.html#scrolling%E6%B8%B8%E6%A0%87%E6%9F%A5%E8%AF%A2
2、代码
public function getIndexByTime($start,$end)
{
$start = strtotime($start) + 600; // 冗余10分钟的数据
$end = strtotime($end);
//组装搜索的索引
$params = [
'index' => $date_arr['index'], //多索引一起用,逗号隔开以数组的形式传过去,实测可以
'type' => '_doc', // type必须保持一致,且索引建立之后,无法更改索引
"scroll" => "30s", //这个代表每次翻页的时间间隔
"size" => 1000, //代表每次分页查询的条数
'body' => [
"_source" => [
"includes" => ["pixel.is50mClient","pixel.newbie", "pixel.channel", "pixel.os", "pixel.type", "pixel.user_id", "pixel.uuid", "*country_code2","clientip", "timestamp","@timestamp"], //查询的字段,最好是把自己需要的字段都列出来,不要查太多冗余字段
],
'query' => [
"bool" => [
"filter" => [
"range" => [
"@timestamp" => [
"gt" => $start_range,
"lt" => $end_range,
]
],
],
]
]
]
];
$repos = $this->client->search($params);
while (isset($repos['hits']['hits']) && count($repos['hits']['hits']) > 0) {
foreach($repos['hits']['hits'] as $key=>$v)
{
// 这里写上你的逻辑
$scroll_id = $repos['_scroll_id'];
$repos = $this->client->scroll([ //这里通过while循环,取得上次的scroll_id,继续查询,直到查不出来数据位置
"scroll_id" => $scroll_id,
"scroll" => "30s"
]
);
}
}
大概的代码如上,可以参照注释部分理解。
1、出现内存不够的情况,报错
Out of memory (allocated 364904448) (tried to allocate 262144 bytes)
这个报错是php的报错,也就是查出的内存超过了php设置的内存。一般我们本地的内存设置成128M
是够用的。所以出现这个情况优先考虑自己是不是操作查出的数组太频繁,foreach
数组占用大量内存等。
2、搜索字段少一些
博主在出现内存告急之后试了下:
当搜索字段是全字段的时候,size超过200条就出现内存不足的情况
当搜索字段只列出需要的部分,size设置400条就出现内存不足的情况
当搜索字段只有一个的时候,size部分设置1000都可以
综上所述,我们可以知道,在查询的时候,查出的字段要尽量的少,其次是size设置成合适的大小。(这部分只是举个例子,内存告急是代码部分的问题,修改之后就好了。)
优化数组内存部分:https://blog.csdn.net/LJFPHP/article/details/90053455
3、不够灵活
当结果足够大的时候, scroll
性能更佳。但是不灵活和 scroll_id
难管理问题存在。使用 scroll
必须是按照顺序一页一页进行翻阅,如果是无规则的翻页,它的性能消耗也是极大的。这部分我们可以理解为类似于抖音视频的那种样子,我们看的时候只能往下拉而不能直接选择跳到多少页。因为跳页操作对于大数据来说是非常耗费性能的,对scroll来说也一样。所以大家要根据自己的实际需求去选择分页的方式。
博主这里的数据对实时性要求不是很高,也不需要进行跳页操作,所以选用了scroll的方式,大家仁者见仁智者见智吧。加油!
end