设计网站中如何设置特效,wordpress 做商城,音乐网站制作源代码,个人做网站1、正排索引
1.1 正排索引#xff08;doc values #xff09;和倒排索引
概念#xff1a;从广义来说#xff0c;doc values 本质上是一个序列化的 列式存储 。列式存储 适用于聚合、排序、脚本等操作#xff0c;所有的数字、地理坐标、日期、IP 和不分词#xff08; no…1、正排索引
1.1 正排索引doc values 和倒排索引
概念从广义来说doc values 本质上是一个序列化的 列式存储 。列式存储 适用于聚合、排序、脚本等操作所有的数字、地理坐标、日期、IP 和不分词 not_analyzed 字符类型都会默认开启不支持text和annotated_text类型
区别
倒排倒排索引的优势是可以快速查找包含某个词项的文档有哪些。如果用倒排来确定哪些文档中是否包含某个词项就很鸡肋。正排正排索引的优势在于可以快速的查找某个文档里包含哪些词项。同理正排不适用于查找包含某个词项的文档有哪些。
倒排索引和正排索引均是在index-time时创建保存在 Lucene文件中序列化到磁盘。
1.2 正排索引的数据结构
1.2.1 doc values
doc values是正排索引的基本数据结构之一其存在是为了提升排序和聚合效率默认true如果确定不需要对字段进行排序或聚合也不需要通过脚本访问字段值则可以禁用doc values值以节省磁盘空间。
1.2.2 fielddata
概念查询时内存数据结构在首次用当前字段聚合、排序或者在脚本中使用时需要字段为fielddata数据结构并且创建倒排索引保存到堆中。与 doc value 不同当没有doc value的字段需要聚合时需要打开fielddata然后临时在内存中建立正排索引fielddata 的构建和管理发生在 JVM Heap中。Fielddata默认是不启用的因为text字段比较长一般只做关键字分词和搜索很少拿它来进行全文匹配和聚合还有排序。
语法
PUT /index/_mapping
{properties: {tags: {type: text,fielddata: true //true开启fielddata; false关闭fielddata}}
}**深层解读独家**doc values是文档到词项的映射 inverted是词项到文档id的映射从原理上讲 先说倒排索引为什么不适合聚合你无法通过倒排索引确定doc的总数量并且因为倒排索引默认会执行analysis即使聚合结果也可能不准确所以你还要创建not_analyzed字段徒增磁盘占用举个最简单的例子假如有一张商品表每个商品都有若干标签我们执行了以下查询
GET product/_search
{query: {match: {tags: 性价比}},aggs: {tag_terms: {terms: {field: tags.keyword}}}
}这段聚合查询的意思 查询包含“性价比”这个标签商品的所有标签在执行agg的时候 我们使用倒排索引那么语义将是这样的在倒排索引中扫描逐个term看看这个term对用的倒排表中对应的doc的标签 是否包含“性价比”如果包含则记录由于我们不确定下面一个term是否符合条件所以我们就要一个一个的判断所以就造成了扫表。如果使用正排索引而正排索引的指的是doc中包含了哪些词项也就是当前doc_id当前字段所包含的所有词项的映射我们要查找的是符合条件的doc中所有的标签那么我们直接根据keydoc_id去拿valuesall terms就可以了所以就不用扫表。所以聚合查询使用正排索引效率高本质是两种数据结构的区别 和结不结合倒排索引没有关系结合倒排索引只是预先进行了数据筛选。以上是正排索引在原理上对聚合查询友好的原因 下面我说一下关于两种数据结构在数据压缩上的不同doc values是一种序列化的列式存储结构其values其中也包含了词频数据。而这种结构是非常有利于数据压缩的参考第二版VIP课程中的FOR和RBM压缩算法因为Lucene底层读取文件的方式是基于mmap的原理是上是从磁盘读取到OS cache里面进行解码的使用正排索引的数据结构由于其列式存储的数据和posting list一样可以被高效压缩所以这种方式极大的增加了从磁盘中读取的速度因为体积小了然后把数据在OS Cache中进行解码
2、三角选择原则 3、基数聚合Cardinality
3.1 易并行算法和不易并行算法
3.1.1 易并行算法
如Max、Min、Avg、Sum等指标函数通常只需要在多个分片中计算一个值进行汇总计算因此不必消耗过多内存资源。参考深度分页原理
3.1.2 不易并行算法
如Cardinality函数由于无法在不同分片中保证数据是否重合因此将消耗更多的内存用于数据汇总进行基数聚合尤其是高基聚合。
3.2 高基数与低基数聚合
高基数性能低
低基数性能高
3.3 Cardinality精度内存换算
3.3.1 precision_threshold参数
ES在执行Cardinality聚合的时候通过precision_threshold参数以内存换精度默认3000最大值40000设置再大的值实际也最高只能是4W当小于precision_threshold设置的时候精度接近100%当大于此设置的时候即使数据量有几百万误差也只是1-6。
注意precision_threshold设置较高阈值对低基数聚合时有显著效果而对高基数聚合是并无显著效果反而会占用大量的资源适得其反。
3.3.2 内存精度换算单位
内存消耗 precision_threshold * 8 个Byte比如 precision_threshold 1000内存消耗约 8KB。
3.4 HyperLogLog介绍
HyperLogLogHLL算法是依赖于field value计算hash在做cardinality运算的时候ES会动态为每一个field value计算hash用于提升聚合性能。
3.5 低基聚合的优化方案maper-murmur3
3.5.1 作用
提升低基聚合的查询性能副作用是消耗较大磁盘空间。
3.5.2 原理
maper-murmur3提升低基聚合的原理就是通过预先为字段值计算hash在做cardinality计算的时候使用提前准备好的hash值参与计算避免了动态运算从而节省性能建议在字段基数较大并且可能会有大量重复值得时候使用这样可能会产生显著的性能提升不然可能不但不会带来显著的性能提升而且会徒增磁盘消耗得不偿失。
3.5.3 安装与使用
安装
bin/elasticsearch-plugin install mapper-murmur3
使用
PUT index
{mappings: {properties: {type: {type: keyword,doc_values: true,fields: {hash: {type: murmur3}}}}}
}
POST /index/_search?size0
{aggs: {type_count: {cardinality: {field: type.hash}}}
}4、深度优先DFS和广度优先BFS
4.1 概念和基本原理
背景Terms 桶基于我们的数据动态构建桶它并不知道到底生成了多少桶。 大多数时候对单个字段的聚合查询还是非常快的 但是当需要同时聚合多个字段时就可能会产生大量的分组最终结果就是占用 es 大量内存从而导致 OOM 的情况发生。
在Elasticsearch中对于具有许多唯一术语和少量所需结果的字段延迟子聚合的计算直到顶部父级聚合被修剪会更有效。通常聚合树的所有分支都在一次深度优先传递中展开然后才会发生任何修剪。在某些情况下这可能非常浪费并且可能会遇到内存限制。
基本原理即推迟子聚合的计算
4.2 原理
4.3 适用场景及基本用法
4.3.1 用法Collect mode
collect_mode: {collect_mode.value} 4.3.2 参数
breadth_first广度优先模式属于最上层桶的一组文档被缓存以备后续重播因此执行此操作时内存开销与匹配文档的数量成线性关系。即先做第一层聚合逐层修剪。depth_first即先构建完整的树然后修剪无用节点。
4.4 注意
广度优先仅仅适用于每个组的聚合数量远远小于当前总组数的情况下因为广度优先会在内存中缓存裁剪后的仅仅需要缓存的每个组的所有数据以便于它的子聚合分组查询可以复用上级聚合的数据。
广度优先的内存使用情况与裁剪后的缓存分组数据量是成线性的。对于很多聚合来说每个桶内的文档数量是相当大的。