一、执行原理如下:
比如查询offset=500,limit=20的数据
由于ElasticSearch中数据都存储在各分片中,按照一般的查询流程来说,如果想查询前10条数据要经过如下过程:
1、客户端将请求发给集群主节点
2、主节点将请求转发到个个分片,查询每个分片上的前500+20=520条数据
3、各分片将结果返回给主节点,整合数据,提取第500到520条
4、数据返回给请求客户端
这样会带来的问题就是当分页较深比如取5000到5010条数据时,elasticsearch需要首先在每一个分片上取出5010条数据,然后汇总到主节点,由主节点再排序所有的结果以选出顶端的10个结果返回给客户端,其余数据全部丢弃。
所以当分页很深的时候特别容易造成集群OOM,即便不OOM,也很消耗CPU和内存资源。
因此ES使用index.max_result_window:10000配置作为保护措施,即默认 from + size 不能超过10000,虽然这个参数可以动态修改,也可以在配置文件配置,但是最好不要这么做,因为这样实在是太消耗集群的资源和性能。
二、scroll“深”分页
幸运的是,ElasticSearch还提供了一种scroll“深”分页的方式,可以支持我们在es集群上进行深度翻页,甚至是读取全部数据。
执行原理如下:
可以把scroll理解为关系型数据库里的cursor,scroll具体分为初始化和遍历两步:
1、初始化时将所有符合搜索条件的搜索结果缓存起来,可以想象成快照,并返回一个_scroll_id
2、在遍历时,通过_scroll_id从这个快照里取数据
3、每次取完数据之后会返回一个新的_scroll_id记录当前读取的位置,下一次可根据这个新的_scroll_id继续读取后面的数据
4、如果没有数据了,就会回传空的hits,可以由此判断是否遍历完成了所有数据
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net