elasticsearch的查询方式和数据库事务隔离级别的思考

2024-01-07 17:16:29

目录

普通分页

解除查询限制

scroll查询

search_after

官方改进

轻量级试图(pit,Point in time)

总结


项目中用到了?elasticsearch,发现有几种查询方式不太一样,思考了一下,总结如下

普通分页

等同于关系数据库的分页查询,例如 mysql 的 limit,如下 sql

select * from test limit 100000,10

这种查询方式有一个问题,需要查询?1000010 条数据到内存中,然后筛选出最后的 10 条数据进行返回,这样就会造成一个问题,对内存大大浪费。

对于?elasticsearch 也是这样,所以针对分页数量大于 10000 的数据做了限制,需要手动开启参数?track_total_hits 为 true 才行,如果这样做了会产生一个问题,就是大量数据加载 jvm 中(elasticsearch使用java开发,使用的lucene也是),内存吃紧开销大,造成频繁的 gc。

解除查询限制

PUT _all/_settings
{
  "index" : {"max_result_window" : 1000000}
}

这种方式是治标不治本,不建议修改

需要确保如下要求

from + size < max_result_window

为了解决这个深分页的问题,滚动查询出现了

scroll查询

https://www.elastic.co/guide/en/elasticsearch/reference/5.0/search-request-scroll.html

从 5.0 版本开始添加。

scroll API 可用于从单个搜索请求检索大量结果(甚至所有结果),这与在传统数据库上使用游标的方式大致相同。
scroll?并不是为了实时用户请求,而是为了处理大量数据,只能往下查询。

通过第一次查询后返回一个scroll?id,往后每次查询都基于这个scroll id,直到查询不到数据为止。

开始查询时形成一个快照,连续查询过程中,不会将新增加或修改的数据添加到查询结果中,也不支持跳页查询。

初始化时将所有符合搜索条件的搜索结果缓存起来,可以想象成快照,在遍历时,从这个快照里取数据,也就是说,在初始化后对索引插入、删除、更新数据都不会影响遍历结果。

如果想要在查询过程中某些数据修改了,需要查询到最新的数据。需要使用?search_after 来实现。

类似于事务隔离级别中的?REPEATABLE READ,每个事务只会在第一次执行查询语句时生成一个 ReadView,即数据修改了不影响本次查询的结果。

search_after

https://www.elastic.co/guide/en/elasticsearch/reference/5.0/search-request-search-after.html

和 scroll 查询一样,从 5.0 版本开始添加。使用的场景不同。

search_after不是自由跳转到随机页面的解决方案,而是并行滚动许多查询的解决方案。

它与 API 非常相似,与 scroll 不同的是,search_after参数是无状态的,它总是根据搜索器的最新版本进行解析。因此,排序顺序可能会在步行过程中发生变化,具体取决于索引的更新和删除。

在查询过程中至少指定一个唯一不重复字段来排序。

类似于事务隔离级别中的?READ COMMITTED,每个事务在每次查询开始时都会生成一个独立的 ReadView,即数据修改了每次执行查询了数据都是不同的。

官方改进

轻量级试图(pit,Point in time)

https://www.elastic.co/guide/en/elasticsearch/reference/7.10/point-in-time-api.html

从 7.10 版本中开始添加。

https://www.elastic.co/guide/en/elasticsearch/reference/7.10/scroll-api.html

在这个文档上,指出了不推荐使用 scroll 查询,使用?search_after 和 pit 来代替。即针对快照数据建议使用这种方式。

对于search_after 和 pit 结合使用与?scroll 的到底有什么区别,官方文档也没做说明,也没找到对应的性能对比测试。

总结

查询方式数据量实时查询排序跳页使用场景与关系数据库事务隔离级别对应关系
from+size浅分页<=1000支持支持支持实时跳页查询,搜索引擎READ COMMITTED
scroll>10000不支持支持不支持深分页,无序批量查询.。
后台批处理、导出
REPEATABLE READ
search_after>10000支持支持不支持深分页,实时大批量查询READ COMMITTED

参考链接

https://blog.csdn.net/liaomingwu/article/details/117323936

https://blog.csdn.net/weixin_46097842/article/details/107889284

https://cloud.tencent.com/developer/article/1825190

https://juejin.cn/post/7088110134076899365

https://blog.csdn.net/UbuntuTouch/article/details/119926953

?

文章来源:https://blog.csdn.net/zlpzlpzyd/article/details/135381925
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。