`
qindongliang1922
  • 浏览: 2147083 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:116317
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:124587
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:58449
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:70347
社区版块
存档分类
最新评论

如何在elasticsearch里面使用深度分页功能

    博客分类:
  • ELK
阅读更多

前面的文章提到过es默认的from+size的分页方式返回的结果数据集不能超过1万点,超过之后返回的数据越多性能就越低。


这是因为es要计算相似度排名,需要排序整个整个结果集,假设我们有一个index它有5个shard,现在要读取1000到1010之间的这10条数据,es内部会在每个shard上读取1010条数据,然后返回给计算节点,这里有朋友可能问为啥不是10条数据而是1010条呢?这是因为某个shard上的10条数据,可能还没有另一个shard上top10之后的数据相似度高,所以必须全部返回,然后在计算节点上,重新对5050条数据进行全局排序,最后在选取top 10出来,这里面排序是非常耗时的,所以这个数量其实是指数级增长的,到后面分页数量越多性能就越下降的厉害,而且大量的数据排序会占用jvm的内存,很有可能就OOM了,这也是为什么es默认不允许读取超过1万条数据的原因。



那么问题来了,我就是想要深度的分页数据应该怎么办? es里面提供了两种方式来读取深度分页的数据:


(1)离线的读取深度分页数据的Scroll方法


(2)能够用于实时和高并发场景的searchAfter方法(5.x之后)




Scroll方式在前面的文章提到过,它通过一次查询请求后维护一个索引快照的search context,然后每次再去批量的读取数据,效率比较高。在5.x之后,还可以通过slice分片来实现并行导出。

它的缺点就是维护一个search context需要占用很多资源,而且在快照建立之后数据变化如删除和更新操作是不能被感知到的,所以不能够用于实时和高并发的场景。



searchAfter的方式通过维护一个实时游标来避免scroll的缺点,它可以用于实时请求和高并发场景。


它的缺点是不能够随机跳转分页,只能是一页一页的向后翻,并且需要至少指定一个唯一不重复字段来排序。


此外还有一个与scorll的不同之处是searchAfter的读取数据的顺序会受索引的更新和删除影响而scroll不会,因为scroll读取的是不可变的快照。




下面来看下如何使用searchAfter:

我们先查询一页数据:

````js
GET twitter/_search
{
    "size": 10,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    },
    "sort": [
        {"date": "asc"},
        {"_id": "desc"}
    ]
}
````


注意,上面用了两个字段来排序,第一个是业务字段可能不唯一,但是第二个id字段一定唯一不重复的。只有这样才能确保searchAfter的翻页顺序读取。

另外searchAfter的from字段一定要设置成0,不然会有问题。



第一个请求发出之后,我们需要获取第一个请求里面最后一条的数据的date和id,然后把这个信息传送到下一个批次,依次类推直到把所有的数据处理完。

如下第二个请求的查询体:

````
GET twitter/_search
{
    "size": 10,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    },
    "search_after": [1463538857, "654323"],
    "sort": [
        {"date": "asc"},
        {"_id": "desc"}
    ]
}
````




总结:

本篇文章介绍了如何在es里面使用深度分页的功能,并对比了scroll和searchAfter的优缺点及不同之处,了解这些知识之后,我们就可以在适合的场景下正确的选择最优的处理方式。

有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。 技术债不能欠,健康债更不能欠, 求道之路,与君同行。

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics