Elasticsearch是一个真正的时间分布式搜索和分析引擎。在使用过程中,有一些典型的用法场景,例如页面和遍历。
在使用关系数据库时,我们被告知我们必须注意甚至明确禁止使用深度分页。同样,在Elasticsearch中,我们还应该尝试避免使用深度分页。
本文主要介绍Elasticsearch中的分页相关内容!
在ES中,第10个比赛命中的顶部的分页查询10。
如果您需要分页,则需要使用来自和大小参数。
一个基本的查询语句是:
上面的查询表明,从搜索结果的第100条开始的10个数据。
那么,该查询语句如何在ES群集内部执行?
在ES中,搜索通常包括两个阶段。可以简要理解查询和提取阶段。查询阶段确定要采用哪些文档,并在提取阶段取出特定的文档。
查询阶段
如上图所示,描述了搜索请求的查询阶段:·
在上面的示例中,协调节点获取数据,然后选择先前的条形数据以保存优先级队列,并在合并和对其进行排序以使用fetch阶段。
此外,每个片段的数据返回到协调节点都用于选择前栏数据,因此只有唯一一个标记DOC和用于排序的数据。这也可以确保返回的数据量足够小。
在协调节点计算您的优先级队列后,查询阶段结束并进入提取阶段。
提取阶段
查询阶段知道要采用什么数据,但是没有特定的数据,这是提取阶段要做的。
上图显示了获取过程:
在协调节点的优先级队列中有一个,但是在提取阶段,无需检索所有数据。在上面的示例中,不需要获取前100片数据。数据达到110件。
需要获取的数据可能是不同的切片,也可以在同一段中。协调节点使用Multi-get避免使用多个平板电脑来拾取数据多次,从而提高性能。
以这种方式进行 - 深入分页存在问题:
我们可以假设在索引中以5个主碎片进行搜索。当我们要求结果的第一页(结果为1到10)时,每个碎片都会在前10个结果中产生,然后返回协调节点,并协调一致节点为50个结果排名前10个结果。
现在假设我们要求第1000页 - 从10001到10010。所有切片必须以相同的方式产生前10010个结果。然后协调节点以对所有50050结果进行排序,最后放弃这些结果的50040结果。
分类结果的成本随着分页深度而增加。
注1:
大小的大小不能超过此参数的设置,默认值为10000。
如果搜索大小大于10000,则需要设置参数
注意2:
删除未来版本,请参考:
Elasticsearch的来自/大小方法提供了分页函数,同时也有相应的限制。
例如,一个具有10亿数据的索引,分为10片,然后,搜索请求,= 1000000,尺寸= 100,此时将带来严重的性能问题:CPU,内存,IO,IO,网络band bandwidthessence
在查询阶段,每个碎片都需要返回1000100个数据以协调节点,并且需要接收到100个数据,即使每个数据仅和谐,此数据量也很大?
另一方面,我们意识到,这个深度分页的请求是不合理的,因为我们很少查看背后的请求。100页。
例如,有大量的微信V,有1000万个粉丝,向所有粉丝群发送消息或发送省级粉丝群。目前,所有合格的粉丝都需要获得。但是,这是不现实的。目前,Elasticsearch提供的其他方法可用于实现遍历。
深层分页问题可以大致分为两类:
以下引入了几种官方深度分页方法
滚动遍历数据
我们可以将滚动作为关系数据库中的光标。因此,滚动不适合实时搜索,而是更适合背景批处理处理任务(例如组发行)。
此分页用法不是要实时查询数据,而是一次查询大量数据(甚至所有数据)。
因为此卷轴等同于维护当前索引段的快照信息,所以当您执行此滚动查询时,此快照信息是快照。在此快照中找不到此查询后任何新索引的数据。
但是,将其与来自和大小的尺寸进行比较,而不是查询所有数据,然后消除不需要的零件,而是记录读取位置以确保下次我继续快速阅读时。
无论排序如何,都可以组合使用。
滚动可以分为初始化和遍历的两个部分。在初始化期间,所有符合搜索条件缓存的搜索结果(请注意,这里只是缓存DOC_ID,并未真正缓存所有文档数据。数据在Fetch阶段完成。)可以将其想象为快照。
在转移此快照的数据之后,即初始化后,索引插入,删除和更新数据不会影响遍历结果。
基本用途
初始化表示索引和类型,然后使用参数滚动,指示临时搜索结果的时间,其他类似于普通的搜索请求。
将返回一个数据以获取数据的数据。
遍历
上次您通过初始化进行遍历或返回时,您需要带上滚动参数。
重复此步骤,直到返回的数据为空,也就是说,遍历已完成。
请注意,必须每次传递参数,并且搜索结果的缓存时间进行刷新。此外,您无需指定索引和键入。
设置滚动时,您需要将搜索结果缓存到下一个遍历。同时,不应该太长。毕竟,空间有限。
的优点和缺点
缺点:
优势:
适用于大量数据的非真实时间处理,例如数据迁移或索引更改。
ES提供了滚动扫描方法以进一步改善遍历性能,但是滚动扫描不支持排序,因此滚动扫描适合不需要排序的场景。
基本用途
滚动扫描的遍历与普通滚动的扫描相同,并且初始化有点差异。
需要指示参数:
滚动扫描和滚动之间的区别
如果您有大量数据,则无法使用滚动遍历数据接受它。现在,滚动接口可以通过数据遍历发布。
每个滚动请求都可以分为多个切片请求,可以理解为切片。每个切片都是独立且平行的,比滚动浏览的速度要快。
上面的示例可以单独请求两块数据,并且五个数据合并的结果与直接滚动扫描相同。
其中,Max是块的数量,ID是第一件。
建议最大值不超过官方文档中的碎片数,否则可能会导致内存爆炸。
这是ES 5引入的新的分页查询机制,该原理几乎与滚动相同,因此代码几乎相同。
基本用途:
第一步:
返回的结果信息:
上面的请求将返回一个包含每个文档的排序分类值的数组。
这些排序值可以在参数中使用,以捕获下一页上的数据。
例如,我们可以使用最后一个文档的排序值将其传递给参数:
如果我们想遵循最后读取的结果以读取下一页,则根据第一个查询的语句添加第二个查询,并指示哪些数据开始读取。
基本的
ES保持真实的时间光标。上述查询的最后记录是光标,对于下一页来说很方便。这是一个无状态查询,因此每个查询都是最新数据。
由于它将记录用作光标,因此搜索法需要在DOC中至少一个全局唯一变量(每个文档都有一个唯一的值字段作为排序规格)
的优点和缺点
优势:
缺点:
它不是免费跳到任何页面的解决方案,而是并行多个查询的解决方案。
从 +尺寸起的灵活性良好,可以用少量数据意识到少量的深度分页问题,这些数据可以忍受深度分页问题scrol,以解决高 - 时间(快照版本)的维护成本,这些维护成本无法反映在数据中。导出需要查询数据搜索数据集的数据集。最好反映数据的真实时间更改。由于第二查询的结果,它不适用于大规模页面的分页来查询大量数据。参考:https://www.lastic.co/guide/en/elasticsearch/reference/paginate-results.html#scroll-search-results
在该版本中,ES官员不再建议使用Croll方法进行深度分页,但建议使用坑来查询;
从版本开始,您可以使用参数通过上一页中的一组排序值来检索下一页。
使用具有相同查询和排序值的多个搜索请求。
如果这些请求得到刷新,则可能会更改结果的顺序,这将导致页面之间的结果不一致。
为了防止这种情况,您可以创建一个时间点(PIT),以在搜索过程中保留当前的索引状态。
在搜索请求中指定坑:
单独获取分页,10个数据(前提为10W),性能大致是:
ES中没有相应的API,但是根据官方声明(https://github.com/elastic/elasticsearch/issues/29449))
滚动和原理基本上是相同的,它们都使用光标进行深度分页。
尽管这种方法可以在一定程度上解决深页问题的问题。但是,它们不是深页的最终解决方案。必须避免深页!
对于滚动,不可避免地要维护和历史悠久的快照,以及必须保证的生存时间,这对服务器来说是一个巨大的负担。
对于用户,允许用户大量跳入页面,这将在短时间内频繁地搜索操作。这样的效率非常低,这也将增加服务器的负载。同时,在查询过程中,索引将导致查询数据增加查询数据。矛盾或排序更改,从而导致结果不准确。
这本身就是业务折扣解决方案。它不允许指定的跳转到页面,而仅提供下一页函数。
滚动将来会删除所有合格的数据,因此它只是搜索所有资格(这也是分类的官方建议,因为它本身会被缓存,如果其他领域进行分类,其他领域也会增加上下文用于下次您需要从Shard的文档开始。
这就是为什么官员不建议滚动对用户使用真实的时间分页询问,而是适用于大量拉数据的原因,因为它不是实时设计的,可以实时读取数据。