ES 聚合索引简介

ES 聚合索引简介,第1张

本章会简单介绍es的聚合索引,通过分析bucket和metric和使用来进一步了解聚合索引。

Bucket Aggregation通过字段term对field字段进行桶排序,以上语句含义为:划分到达不同目的地国家的统计。

以上我们看到搜索中hits是为空的,聚合下可以看到以目的地国家为划分的不同的桶

以上通过目的地国家进行分桶,并且对最大,最小,平均值进行了统计计算。

以上我们能看到不同的桶下对三种类型计算产生的输出结果。

本章介绍了聚合,通过两个demo简单介绍了Bucket和Metric两种聚合使用。

公司的电商app需要做搜索功能,分析整理后列出如下需求点:

接下来就是愉悦(tongku)的设计和coding了

商品表已经在业务库中存在直接用,只需要设计出es索引就可以。es安装后顺带装上jk、pinyin插件,因为后续要用到拼音功能,不过在本阶段先不管拼音的事儿。

产品表定义:

产品类对应Repository定义:

maven-pom文件增加引用

applicationyml文件添加es相关配置

以上定义完成后,启动项目,成功后可以看到如下提示(debug级别下):

如果没有伴随出现报错信息(es索引配置有误,不能创建索引时会给出相应提示),此时es中的 product 索引应该已经成功创建了。

使用es GET /demo-product/_mapping 命令可查看索引结构已经完整创建:

索引表的插入,可使用spring-boot的@Schedule定时器,以指定间隔扫描产品表的新增数据,以es对应product表的字段封装后,插入es索引即可

此时索引表结构和数据已经准备就绪,可以开始写查询方法了!

我们先准备一些测试商品数据:

  此处有一点需要注意,由于商品品牌名称大多为互相无关联意义的字组成,如果使用默认分词,会被分的很散,不符合要求,所以需要将品牌名中文部分列出来,加入到ik分词插件的扩展词典中去,此处不展开。

  分析一下搜索需求,当用户传入搜索关键词后,需要在商品名称、描述、类目名称和品牌名称四个字段中做match *** 作,暂定互相之间的权重比为05:01:02:1,可使用NativeSearchQuery创建查询方法:

  打开浏览器,输入 /product/风衣%20毛衣/1/10 ,可以得到如下结果:

至此,第一步工作算是暂时完成。

ILM :索引生命周期管理,即 Manage the index lifecycle 。

索引的生命周期有四个阶段:

索引的生命周期策略指定了适用于哪些阶段、在每个阶段中执行哪些 *** 作以及何时在各个阶段之间进行转换。

当索引满足一定条件之后,将不再写入数据,而是自动创建一个索引,所有的数据将写入新的索引。

使用滚动索引能够:

官方推荐使用 data stream 数据流来管理时间序列数据。每个数据流都需要一个 索引模板 ,其中包括:

数据流专为追加数据而设计,其中数据流名称可用作 *** 作(读取、写入、翻转、收缩等)目标。如果需要更新数据,可以使用 索引别名 来管理时间序列数据。

ILM 会根据你的配置: 索引大小 、 文档数量 、 所在阶段 ,当满足这些条件时,自动实现 rollover 。

要让 ILM 管理索引,必须要在 indexlifecyclename 索引设置中指定有效的策略。

要为滚动索引创建生命周期策略,你要创建该策略并把它加入到 索引模板 中。

可以通过 Kibana 管理页面设置,也可以通过API设置。

可以通过 Kibana 管理页面设置,也可以通过API设置。

如果要给滚动索引设置策略,需要手动创建第一个被该策略管理的索引,并指定为可写索引。

索引的名称必须跟索引模板里定义的模式相匹配,并且以数字结尾。

你可以在创建索引的时候指定一个策略,也可以直接将策略应用到一个已经存在的索引上通过 Kibana 管理或者更新设置的API。一旦你应用了策略, ILM 立即会开始管理该索引。

查看错误:

重新运行报错的一步:

查看 ILM 状态:

终止 ILM :

开启 ILM :

设置 indexlifecycleindexing_complete 为 true 。

举个例子,如果你要改变一系列新索引的名称,并保留之前根据你配置的策略产生的索引数据,你可以:

相关连接: >

之前进行了Es集群的搭建,这次总结下Es的IndexApi,这里主要会和Solr进行部分对比来描述,如果对Solr不熟悉的可以自行略过。

Es采用REST FULL的Api,这让Es具有很好的可读性,调用一目了然,当然RESTFuL的API不建议用到生产环境,原因是这种API接口基本都是短链接,这样消耗比较大,最好使用的时候,用长连接的接口进行包装,这样每次查询都是基于长连接的请求,能很好的减小服务端的开销。

一个索引请求:

这是一个ES建索引的>

>

有些聚合分析的算法,是很容易就可以并行的,比如说max

有些聚合分析的算法,是不好并行的,比如说,count(distinct),并不是说,在每个node上,直接就出一些distinct value,就可以的,因为数据可能会很多,假设图中的协调节点3百万个数据去重后还剩下100万distinct的数据,那么内存需要来存储这100万条数据,这是不可能的

es会采取近似聚合的方式,就是采用在每个node上进行近估计的方式,得到最终的结论,cuont(distcint),100万,1050万/95万 --> 5%左右的错误率

近似估计后的结果,不完全准确,但是速度会很快,一般会达到完全精准的算法的性能的数十倍

precision_threshold优化准确率和内存开销

brand去重,如果brand的unique value,在100个以内,小米,长虹,三星,TCL,HTL。。。

在多少个unique value以内,cardinality,几乎保证100%准确

cardinality算法,会占用precision_threshold 8 byte 内存消耗,100 8 = 800个字节

占用内存很小。。。而且unique value如果的确在值以内,那么可以确保100%准确

100,数百万的unique value,错误率在5%以内

precision_threshold,值设置的越大,占用内存越大,1000 8 = 8000 / 1000 = 8KB,可以确保更多unique value的场景下,100%的准确

field,去重,count,这时候,unique value,10000,precision_threshold=10000,10000 8 = 80000个byte,80KB

doc value正排索引

搜索+聚合 是怎么实现的?

假设是倒排索引实现的

倒排索引来实现是非常不现实的,因为我们搜索的那个字段search_field 有可能是分词的,这就需要去扫描整个索引才能实现聚合 *** 作,效率是及其低下的。

正排索引结构:

doc2: agg1

doc3: agg2

1万个doc --> 搜 -> 可能跟搜索到10000次,就搜索完了,就找到了1万个doc的聚合field的所有值了,然后就可以执行分组聚合 *** 作了

doc value原理

1、doc value原理

(1)index-time生成

PUT/POST的时候,就会生成doc value数据,也就是正排索引

(2)核心原理与倒排索引类似

正排索引,也会写入磁盘文件中,然后呢,os cache先进行缓存,以提升访问doc value正排索引的性能

如果os cache内存大小不足够放得下整个正排索引,doc value,就会将doc value的数据写入磁盘文件中

(3)性能问题:给jvm更少内存,64g服务器,给jvm最多16g

es官方是建议,es大量是基于os cache来进行缓存和提升性能的,不建议用jvm内存来进行缓存,那样会导致一定的gc开销和oom问题

给jvm更少的内存,给os cache更大的内存

64g服务器,给jvm最多16g,几十个g的内存给os cache

os cache可以提升doc value和倒排索引的缓存和查询效率

2、column压缩

doc1: 550

doc2: 550

doc3: 500

合并相同值,550,doc1和doc2都保留一个550的标识即可

(1)所有值相同,直接保留单值

(2)少于256个值,使用table encoding模式:一种压缩方式

(3)大于256个值,看有没有最大公约数,有就除以最大公约数,然后保留这个最大公约数

重点:

对分词的field,直接执行聚合 *** 作,会报错,大概意思是说,你必须要打开fielddata,然后将正排索引数据加载到内存中,才可以对分词的field执行聚合 *** 作,而且会消耗很大的内存

先修改 字段的fielddata属性为true,再查 就能查找到数据

当然,我们也可以使用内置field(keyword)不分词,对string field进行聚合,如果对不分词的field执行聚合 *** 作,直接就可以执行,不需要设置fieldata=true

分词field+fielddata的工作原理

doc value --> 不分词的所有field,可以执行聚合 *** 作 --> 如果你的某个field不分词,那么在index-time,就会自动生成doc value --> 针对这些不分词的field执行聚合 *** 作的时候,自动就会用doc value来执行

分词field,是没有doc value的。。。在index-time,如果某个field是分词的,那么是不会给它建立doc value正排索引的,因为分词后,占用的空间过于大,所以默认是不支持分词field进行聚合的

分词field默认没有doc value,所以直接对分词field执行聚合 *** 作,是会报错的

对于分词field,必须打开和使用fielddata,完全存在于纯内存中。。。结构和doc value类似。。。如果是ngram或者是大量term,那么必将占用大量的内存。。。

如果一定要对分词的field执行聚合,那么必须将fielddata=true,然后es就会在执行聚合 *** 作的时候,现场将field对应的数据,建立一份fielddata正排索引,fielddata正排索引的结构跟doc value是类似的,

但是只会讲fielddata正排索引加载到内存中来,然后基于内存中的fielddata正排索引执行分词field的聚合 *** 作

如果直接对分词field执行聚合,报错,才会让我们开启fielddata=true,告诉我们,会将fielddata uninverted index,正排索引,加载到内存,会耗费内存空间

为什么fielddata必须在内存?因为大家自己思考一下,分词的字符串,需要按照term进行聚合,需要执行更加复杂的算法和 *** 作,如果基于磁盘和os cache,那么性能会很差

我们是不是可以预先生成加载fielddata到内存中来???

query-time的fielddata生成和加载到内存,变为index-time,建立倒排索引的时候,会同步生成fielddata并且加载到内存中来,这样的话,对分词field的聚合性能当然会大幅度增强

何为倒排索引?首先要了解索引表:由关键词为key,关键词位置属性为value组成的一张表。由于该表不是由key来确定value值,而是由value的属性值来确定key的位置,所以称为倒排索引,带有倒排索引的文件称为倒排文件。通俗的讲倒排索引就好比书的目录,通过目录咱们可以准确的找到相应的数据。下面对lucene倒排索引的结构与算法进行介绍。

对于获取关键词有两种思路,1根据空格分隔获取所有的字符2过滤文档中没有意义的词,获取其中的关键词。除此以上还会对词的时态,大小写,同义词,标点符号等做相应的处理,不同的分词器对文档索引的时候做的 *** 作有所差异。

实例1:Tom lives in Zhangye,I live in Zhangye too

关键词1:[tom][live][in][zhangye][i][live][zhangye]

实例2:He once lived in Shanghai

关键词2:[he][live][shanghai]

根据关键词我们就可以确定关键词所在的文章号,关键词在文章中出现的频次以及该关键词在文章中出现的位置(根据上面获取关键词我们可以知道,索引的时候要么索引所有字符,要么索引关键词,lucene采取的就是索引关键词的方式,这样会节省大量的空间),具体索引如下表:

1)词典文件:每个关键词以及指向频率文件和位置文件的指针和filed(用于表达信息位置,每个关键词都有一个或多个field)信息

2)频率文件:关键词在每个文件中出现频率的文件

3)位置文件:关键词所在文章中的位置文件

关键词压缩为<前缀长度,后缀>,例如:“我爱你中国”=》<3,中国>,另外对数字的压缩,只记录与上一个数字的差值,比如当前文章号是11890,上一个文章号是11870,压缩后只需要报错20,这样就极大的缩小了存储空间。

倒排索引服务于es查询 *** 作,对数据的聚合,排序则需要使用正排索引,下面我们介绍正排索引。

正排索引说白了就是document每个field的值的排序,其实就是doc values,举例说明:

实例:

doc1: { "name": "张三", "age": 27,"sex":"男" }

doc2: { "name": "李四", "age": 30,"sex":“女” }

正排索引:

document name age sex

doc1 jack 27 男

doc2 tom 30 女

正排索引使用场景是排序,聚合,过滤等

注意:

对于分词的field进行聚合(aggregation) *** 作,需要将fielddata设置为true,否则会报错提示你打开fielddata、将正排索引加载到内存中

doc values是被保存在磁盘上的,此时如果内存足够,os会自动将其缓存在内存中,性能还是会很高;如果内存不足够,os会将其写入磁盘上。

到此对倒排索引与正排索引就介绍完毕了,如有帮助,请关注!谢谢!

以上就是关于ES 聚合索引简介全部的内容,包括:ES 聚合索引简介、基于es的商品搜索功能实现(上)、ES中的索引生命周期管理等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/9772548.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存