ElasticSearch知识点总结

1.分页知识点

       先举个场景,假如ES有10个分片,我们根据某个关键字查询数据,且按照时间排序,当查询第9页的数据,每页100条数据,当客户端发起这个操作,ES的处理流程是怎么样的?(带着问题去思考)

      1. from+size分页方式

      查询过程大体上分为查询和取回这两个阶段,广播查询请求到所有相关分片,并将它们的响应整合成全局排序后的结果集合,这个结果集合会返回给客户( 具体参考From / Size | Elasticsearch Guide [6.4] | Elastic)

     查询阶段: 当一个节点接收到一个搜索请求,这这个节点就会变成协调节点,第一步就是将广播请求到搜索的每一个节点的分片拷贝,查询请求可以被某一个主分片或某一个副分片处理,协调节点将在之后的请求中轮训所有的分片拷贝来分摊负载。
每一个分片将会在本地构建一个优先级队列,如果客户端要求返回结果排序中从from 名开始的数量为size的结果集,每一个节点都会产生一个from+size大小的结果集,因此优先级队列的大小也就是from+size,分片仅仅是返回一个轻量级的结果给协调节点,包括结果级中的每一个文档的ID和进行排序所需要的信息。协调节点将会将所有的结果进行汇总,并进行全局排序,最总得到排序结果。

     取值阶段:查询过程得到的排序结果,标记处哪些文档是符合要求的,此时仍然需要获取这些文档返回给客户端
协调节点会确定实际需要的返回的文档,并向含有该文档的分片发送get请求,分片获取的文档返回给协调节点,协调节点将结果返回给客户端。

     重点回顾:我们想要查询的第9页符合条件的100条数据,可能分布到ES的10个分片里,那么ES需要到每个分片进行查询排序后把文档ID返回给协调节点(也就是每个节点把前1000条数据的文档ID返回给协调节点),协调节点聚合这1000*10条数据后在内存里进行排序,查到那100条数据再到各个分片获取文档的数据

     缺点:通过上面的流程我们看到当查询分页比较深的时候效率会有很大问题,还有一个无法解决的问题是,es 目前支持最大的 skip 值是 max_result_window ,默认为10000 。也就是当 from + size > max_result_window 时,es 将返回错误
 

      2. scroll分页方式

     流程:为了满足深度分页的场景,es 提供了 scroll 的方式进行分页读取(先从各个分片根据搜索结果获取文档ID排序后返回到协调节点,协调节点再进行排序,第一次和from+size流程一样,区别在于通过scroll会把这次搜索的文档ID都汇总到协调节点并缓存起来,下次根据分页获取的时候不再重新构造,而是直接从缓存里获取)具体就是原理上是对某次查询生成一个游标 scroll_id , 后续的查询只需要根据这个游标去取数据(要求接口的出入参把这个scroll_id每次都带上,这个值以返回的为准,尽管一次查询这个ID值都不变),直到结果集中返回的 hits 字段为空(scroll也是为空),就表示遍历结束。scroll查询底层就是按照游标处理的,每次查询通过pageSize进行移动,如果相同的条件查询多次,返回的scrold是一样的,至于分页的page是应用端计算的。关于scroll查询 设置滚动时间长短是指es把本次快照的结果缓存起来的有效时间。scroll 参数相当于告诉了 ES我们的search context要保持多久,后面每个 scroll 请求都会设置一个新的过期时间,以确保我们可以一直进行下一页操作。注意:过期时间是滚动设置的,不是一个整体的过期时间,具体参考官网Scroll | Elasticsearch Guide [6.4] | Elastic

   
     缺点:由于scroll_id 不仅会占用大量的资源(特别是排序的请求),而且是生成的历史快照,对于数据的变更不会反映到快照上。这种方式往往用于非实时处理大量数据的情况

     3.search_after 的方式

    用于在实时情况下如果处理深度分页,ES的版本>= 5.0 版本才提供的功能。

      4.具体使用方式

       todo

2. number?keyword知识点

       我们的项目中经常会有状态这种字段,比如订单状态,这个字段类型我们用number,还是keyword,我们应该怎么用? ES的5.0之前的版本表面上被定义为数值类型的字段,在暗地里都被转换成了字符串进行采用倒排索引,而在5.0之后Lucene6.0引入了重新设计的数值类型的索引结构,不再采用倒排索,而是使用了更适合范围查找的Block K-d Tree(可以理解成一个多维的B+树,考虑引入k-d tree的好处和使用场景),如果状态的值比较少,个人建议用keyword(采用倒排索引,既key是字符串,value是Postings list(它是按照docid顺序存放的,并且在数据结构上还增加了跳表结构,考虑引入跳表结构的好处)5.1.1之后取消了TermQuery的cache),如果状态值比较多区分度比较高就用RangeQuery,如果字段类型设计成number的话,那就用RangeQuery,不建议使用Termquery(没有缓存,且性能差)
这两篇博客解释k-d tree对range查询的优化。以及k-d tree对term和filter查询性能低的影响Searching numb3rs in 5.0 | Elastic Blog
In which order are my Elasticsearch queries/filters executed? | Elastic Blog
number?keyword number?keyword?傻傻分不清楚 - Elastic 中文社区
ElasticSearch中的数据结构 ElasticSearch中的数据结构_whichard的博客-CSDN博客_es数据结构

3 关于超时

1. setTimeout()这个方法的作用是在查询es的时候,会查询到多个分片上的数据,当到了设定的时间如果还没有查询完,则把已经查询到的数据返回。即便是这样,这个timeout也是经常失效,具体参考es官方的issue https://github.com/elastic/elasticsearch/issues/2520
2. 如果想要配置满足在设定时间内查询不到数据就超时抛处理超时(java异步future的超时)timeout异常的效果 可以通过actionGet()或者get()中设置timeout超时时间 actionGet(timeout) T actionGet(long var1, TimeUnit var3) throws ElasticsearchException; 

4 优秀文章

Elasticsearch 的亿级数据毫秒级查询优化思路 Elasticsearch 的亿级数据毫秒级查询优化思路

Elasticsearch 在各大互联网公司大量真实的应用案例!Elasticsearch 在各大互联网公司大量真实的应用案例!

超详细的Elasticsearch高性能优化实践 超详细的Elasticsearch高性能优化实践 - 知乎

Note/scroll-searchAfter.md at master · craftlook/Note · GitHub

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值