一、前言

    上一篇说了一下查询和存储机制,接下来我们主要来说一下排序、聚合、分页;

写完文章以后发现之前文章没有介绍Coordinating Node,这个地方补充说明下Coordinating Node(协调节点):搜索请求或索引请求可能涉及保存在不同数据节点上的数据。例如,搜索请求在两个阶段中执行,当客户端请求到节点上这个阶段的时候,协调节点将请求转发到保存数据的数据节点。每个数据节点在分片执行请求并将其结果返回给协调节点。当节点返回到客端这个阶段的时候,协调节点将每个数据节点的结果减少为单个节点的所有数据的结果集。这意味着每个节点具有全部三个node.master,node.data并node.ingest这个属性,当node.ingest设置为false仅作为协调节点,不能被禁用。

二、排序

   ES默认使用相关性算分来排序,如果想改变排序规则可以使用sort:

也可以指定多个排序条件:

排序的过程是指是对字段原始内容排序的过程,在排序的过程中使用的正排索引,是通过文档的id和字段进行排序的;Elasticsearch针对这种情况提供两种实现方式:fielddata和doc_value;

fielddata

fielddata的数据结构,其实根据倒排索引反向出来的一个正排索引,即document到term的映射。只要我们针对需要分词的字段设置了fielddata,就可以使用该字段进行聚合,排序等。我们设置为true之后,在索引期间,就会以列式存储在内存中。为什么存在于内存呢,因为按照term聚合,需要执行更加复杂的算法和操作,如果基于磁盘或者 OS 缓存,性能会比较差。用法如下:

fielddata加载到内存中有几种情况,默认是懒加载。即对一个分词的字段执行聚合或者排序的时候,加载到内存。所以他不是在索引创建期间创建的,而是查询在期间创建的。

fielddata在内存中加载的这样就会出现一个问题,数据量很大的情况容易发生OOM,这种时候我们该如何控制OOM的情况发生?

1.内存限制

indices.fielddata.cache.size: 20% 默认是无限制,限制内存使用以后频繁的导致内存回收,容易照成GC和IO损耗。

2.断路器(circuit breaker)

如果查询一次的fielddata超过总内存,就会发生内存溢出,circuit breaker会估算query要加载的fielddata大小,如果超出总内存,就短路,query直接失败;

indices.breaker.fielddata.limit:fielddata的内存限制,默认60%

indices.breaker.request.limit:执行聚合的内存限制,默认40%

indices.breaker.total.limit:综合上面两个,限制在70%以内

3.频率(frequency)

加载fielddata的时候,也是按照segment去进行加载的,所以可以通过限制segment文档出现的频率去限制加载的数目;

min :0.01 只是加载至少1%的doc文档中出现过的term对应的文档;

min_segment_size: 500 少于500 文档数的segment不加载fielddata;

fielddata加载方式:

1.lazy

这个在查询的放入到内存中,上面已经介绍过;

2.eager(预加载)

当一个新的segment形成的时候,就加载到内存中,查询的时候遇到这个segment直接查询出去就可以;

3.eager_global_ordinals(全局序号加载)

构建一个全局的Hash,新出现的文档加入Hash,文档中用序号代替字符,这样会减少内存的消耗,但是每次要是有segment新增或者删除时候回导致全局序号重建的问题;

 doc_value

   fielddata对内存要求比较高,如果数据量很大的话对内存是一个很大的考验。所以Elasticsearch又给我们提供了另外的策略doc_value,doc_value使用磁盘存储,与fielddata结构完全是一样的,在倒排索引基础上反向出来的正排索引,并且是预先构建,即在建倒排索引的时候,就会创建doc values。,这会消耗额外的存储空间,但是对于JVM的内存需求就会减少。总体来看,dov_valus只是比fielddata慢一点,大概10-25%,则带来了更多的稳定性。

类型是string的字段,生成分词字段(text)和不分词字段(keyword),不分词字段即使用keyword,所以我们在聚合的时候,可以直接使用field.keyword进行聚合,而这种默认就是使用doc_values,建立正排索引。不分词的字段,默认建立doc_values,即字段类型为keyword,他不会创建分词,就会默认建立doc_value,如果我们不想该字段参与聚合排序,我们可以设置doc_values=false,避免不必要的磁盘空间浪费。但是这个只能在索引映射的时候做,即索引映射建好之后不能修改。

两者对比:

三、分页

   有3种类型的分页,如下图:

   

1.from/size

form开始的位置,size获取的数量;

数据在分片存储的情况下怎么查询前1000个文档?

在每个分片上都先获取1000个文档,然后再由Coordinating Node聚合所有分片的结果后再排序选取前1000个文档,页数越多,处理文档就越多,占用内存越多,耗时越长。数据分别存放在不同的分片上,必须一个去查询;为了避免深度分页,Elasticsearch通过index.max_result_window限定显示条数,默认是10000;

2.scroll

scroll按照快照的方式来查询数据,可以避免深度分页的问题,因为是快照所以不能用来做实时搜索,数据不是实时的,接下来说一下scroll流程:

首先发起scroll查询请求,Elasticsearch在接收到请求以后会根据查询条件查询文档i,1m表示该快照保留1分钟;

接下来查询的时候根据上一次返回的快照id继续查询,不断的迭代调用直到返回hits.hits数组为空时停止

过多的scroll调用会占用大量的内存,可以通过删除的clear api进行删除:

删除某个:

删除多个:

删除所有:

3.search after

避免深度分页的性能问题,提供实时的下一页文档获取功能,通过提供实时游标来解决此问题,接下来我们来解释下这个问题:

第一次查询:这个地方必须保证排序的值是唯一的

第二步: 使用上一步最后一个文档的sort值进行查询

通过保证排序字段唯一,我们实现类似数据库游标功能的效果;

四、聚合分析

  Aggregation,是Elasticsearch除搜索功能外提供的针对Elasticsearch数据做统计分析的功能,聚合的实时性很高,都是及时返回,另外还提供多种分析方式,接下来我们看下聚合的4种分析方式:

Metric

在一组文档中计算平均值、最大值、最小值、求和等等;

Avg(平均值)

Min最小值

Sum求和(过滤查询中的结果查询出帽子的价格的总和)

Percentile计算从聚合文档中提取的数值的一个或多个百分位数;

解释下下面这个例子,网站响应时间做的一个分析,单位是毫秒,5毫秒响应占总响应时间的1%;

Cardinality计算不同值的近似计数,类似数据库的distinct count

当然除了上面还包括很多类型,更加详细的内容可以参考官方文档;

Bucket

按照一定的规则将文档分配到不同的桶里,达到分类分析的目的;

比如把年龄小于10放入第一个桶,大于10小于30放入第二个桶里,大于30放到第三个桶里;

接下来我们介绍我们几个常用的类型:

Date Range

根据时间范围来划分桶的规则;

to表示小于当前时间减去10个月;from大于当前时间减去10个月;format设定返回格式;form和to还可以指定范围,大于某时间小于某时间;

Range

通过自定义范围来划分桶的规则;

这样就可以轻易做到上面按照年龄分组统计的规则;

Terms

直接按照term分桶,类似数据库group by以后求和,如果是text类型则按照分词结果分桶;

比较常用的类型大概就是这3种,比如还有什么Histogram等等,大家可以参考官方文档

Pipeline

对聚合的结果在次进行聚合分析,根据输出的结果不同可以分成2类:

Parent

将返回的结果内嵌到现有的聚合结果中,主要有3种类型:

1.Derivative

计算Bucket值的导数;

2.Moving Average

计算Bucket值的移动平均值,一定时间段,对时间序列数据进行移动计算平均值;

3.Cumulatove Sum

计算累计加和;

Sibling

返回的结果与现有聚合结果同级;

1.Max/Min/Avg/Sum

2.Stats/Extended

Stats用于计算聚合中指定列的所有桶中的各种统计信息;

Extended对Stats的扩展,提供了更多统计数据(平方和,标准偏差等);

3.Percentiles

Percentiles 计算兄弟中指定列的所有桶中的百分位数;

更多介绍,请参考官方文档

Matrix

矩阵分析,使用不多,参考官方文档;

原理探讨与数据准确性探讨:

Min原理分析:

先从每个分片计算最小值 -> 再从这些值中计算出最小值

Terms聚合以及提升计算值的准确性:

Terms聚合的执行流程:每个分片返回top10的数据,Coordinating node拿到数据之后进行整合和排序然后返回给用户。注意Terms并不是永远准确的,因为数据分散在多个分片上,所以Coordinating node无法得到所有数据(这句话有同学会有疑惑请查看上一篇文章)。如果要解决可以把分片数设置为1,消除数据分散的问题,但是会分片数据过多问题,或者设在Shard_Size大小,即每次从Shard上额外多获取的数据,以提升准确度。

Terms聚合返回结果中有两个值:

doc_count_error_upper_bound 被遗漏的Term的最大值;

sum_other_doc_count 返回聚合的其他term的文档总数;

在Terms中设置show_term_doc_count_error可以查看每个聚合误算的最大值;

Shard_Size默认大小:shard_size = (size*1.5)+10;

通过调整Shard_Size的大小可以提升准确度,增大了计算量降低响应的时间。

由上面可以得出在Elasticsearch聚合分析中,Cardinality和Percentile分析使用是近似统计算法,就是结果近似准确但是不一定精确,可以通过参数的调整使其结果精确,意味着会有更多的时间和更大的性能消耗。

五、结束语

Search分析到此基本结束,下一篇介绍一些常用的优化手段和建立索引时的考虑问题;欢迎大家加群438836709,欢迎大家关注我公众号!

Elastic Stack-Elasticsearch使用介绍(四)的更多相关文章

  1. ElasticSearch搜索介绍四

    ElasticSearch搜索 最基础的搜索: curl -XGET http://localhost:9200/_search 返回的结果为: { "took": 2, &quo ...

  2. Elastic Stack 笔记(四)Elasticsearch5.6 索引及文档管理

    博客地址:http://www.moonxy.com 一.前言 在 Elasticsearch 中,对文档进行索引等操作时,既可以通过 RESTful 接口进行操作,也可以通过 Java 也可以通过 ...

  3. ES 集中式日志分析平台 Elastic Stack(介绍)

    一.ELK 介绍 ELK 构建在开源基础之上,让您能够安全可靠地获取任何来源.任何格式的数据,并且能够实时地对数据进行搜索.分析和可视化. 最近查看 ELK 官方网站,发现新一代的日志采集器 File ...

  4. 集中式日志分析平台 Elastic Stack(介绍)

    一.ELK 介绍 二.ELK的几种常见架构 >>ELK 介绍<< ELK 构建在开源基础之上,让您能够安全可靠地获取任何来源.任何格式的数据,并且能够实时地对数据进行搜索.分析 ...

  5. Elastic Stack之ElasticSearch分布式集群二进制方式部署

    Elastic Stack之ElasticSearch分布式集群二进制方式部署 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 想必大家都知道ELK其实就是Elasticsearc ...

  6. Elastic Stack之ElasticSearch分布式集群yum方式搭建

    Elastic Stack之ElasticSearch分布式集群yum方式搭建 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.搜索引擎及Lucene基本概念 1>.什么 ...

  7. Elastic Stack核心产品介绍-Elasticsearch、Logstash和Kibana

    Elastic Stack 是一系列开源产品的合集,包括 Elasticsearch.Kibana.Logstash 以及 Beats 等等,能够安全可靠地获取任何来源.任何格式的数据,并且能够实时地 ...

  8. Elastic Stack(ElasticSearch 、 Kibana 和 Logstash) 实现日志的自动采集、搜索和分析

    Elastic Stack 包括 Elasticsearch.Kibana.Beats 和 Logstash(也称为 ELK Stack).能够安全可靠地获取任何来源.任何格式的数据,然后实时地对数据 ...

  9. 浅尝 Elastic Stack (一) Elasticsearch、Kibana、Beats 安装

    Elastic Stack 包括 Elasticsearch.Kibana.Beats 和 Logstash,也称为 ELK Stack.能够安全可靠地获取任何来源.任何格式的数据,然后实时地对数据进 ...

  10. ELK stack elasticsearch/logstash/kibana 关系和介绍

    ELK stack elasticsearch 后续简称ES logstack 简称LS kibana 简称K 日志分析利器 elasticsearch 是索引集群系统 logstash 是日志归集集 ...

随机推荐

  1. oracle和mysql批量合并对比

    orm框架采用mybatis,本博客介绍一下批量合并merge用oracle和mysql来做的区别, oracle merge合并更新函数的详细介绍可以参考我以前的博客:https://blog.cs ...

  2. 使用xUnit为.net core程序进行单元测试(1)

    导读 为什么要编写自动化测试程序(Automated Tests)? 可以频繁的进行测试 可以在任何时间进行测试,也可以按计划定时进行,例如:可以在半夜进行自动测试. 肯定比人工测试要快. 可以更快速 ...

  3. numpy操作

    python中使用了numpy的一些操作,特此记录下来: 生成矩阵,替换值 import numpy as np # 生成一行10列的矩阵 dataset = np.zeros((1, 10)) # ...

  4. 用Python教你微信防撤回(文本、图片、语音、视频、名片等...)

    大家在使用微信过程中,有时候消息还没看到,就被撤回了.毕竟好奇心大家都有,明知到消息被撤回了,就更想去看一下是什么内容心里想着万一是女神给我表白了呢.. 今天就用Python来做个微信防撤回的小功能. ...

  5. c# 获取当前时间的微秒

    获取毫秒大家都经常用到. 大家应该都知道怎么用. 但是,毫秒下面还有微秒. 其实这个方法也已经在c#中. 只不过很少有人用到,所以查找资料也很少有人说. 下面代码就是获取微秒的方式: DateTime ...

  6. T4模板简单了解

    T4模板基础 T4即为Text Template Transformation Toolkit,一种可以由自己去自定义规则的代码生成器.根据业务模型可生成任何形式的文本文件或供程序调用的字符串 在VS ...

  7. Python generator和yield介绍

    Python生成器(generator)并不是一个晦涩难懂的概念.相比于MetaClass和Closure等概念,其较为容易理解和掌握.但相对于程序结构:顺序.循环和分支而言其又不是特别的直观.无论学 ...

  8. 初步认识Swiper_前端交互控制神器_滚动3D切换等特效简单制作

    前言: 本人在项目的工作中负责研发,页面及交互基本都是交给前端去做的.以前前端写的东西大概都知道,都是一些JS,CSS和HTML等的一些基本控制,都懂!但是今天前端突然做了一个具有特殊效果的DOM:页 ...

  9. 程序猿想聊天 - 創問 4C 團隊教練心得(二)

    在第二天裡,主要談的是關於 Courage (勇氣) . Co-Create (共創) 的部分因為我們不是真實的團隊,就沒有繼續下去了 一早開始先回顧了一下前一天的內容,接下來我們就開始玩小遊戲 這個 ...

  10. Web项目也能一键打包Android、IOS

    随着移动互联网的不断发展,智能手机配置的不断提高,越来越多的年轻人基本都在使用手机,如微信.支付宝等等.已基本成为一种习惯,坐电梯也好.吃饭也好.开车也好,基本都捧着一个手机在那按来按去,开车就不建议 ...