中文商城html网站模板,济宁做网站建设的公司,整套网站模板,承包网站开发前言随着Elastic的上市#xff0c;ELK不仅在互联网大公司得到长足的发展#xff0c;而且在各个中小公司都得到非常广泛的应用#xff0c;甚至连婚庆网站都开始使用Elasticsearch了。随之而来的是 Elasticsearch 相关部署、框架、性能优化的文章早已铺天盖地。因… 前言随着Elastic的上市ELK不仅在互联网大公司得到长足的发展而且在各个中小公司都得到非常广泛的应用甚至连婚庆网站都开始使用Elasticsearch了。随之而来的是 Elasticsearch 相关部署、框架、性能优化的文章早已铺天盖地。因为ES家族团队已在设计阶段做了大量的设计所以整个ELK家族的组件使用起来非常容易上手对于初学者甚至会进入幻觉—:一键部署、导入数据、检索聚合、动态扩展这些都是如此简单。但实际上呢仅就 Elasticsearch 索引设计请回答如下几个问题倒排索引是什么有限状态转换的机制是什么对于亿级数据ES是如何做到毫秒级甚至秒级回复它有哪些独特的原理 相比于大多数人熟悉的MySQL数据库的索引Elasticsearch的索引机制是完全不同于MySQL的BTree结构。索引会被压缩放入内存用于加速搜索过程这一点在效率上是完爆MySQL数据库的。但是Elasticsearch会对全部text字段进行索引必然会消耗巨大的内存为此Elasticsearch针对索引进行了深度的优化。在保证执行效率的同时尽量缩减内存空间的占用。为了方便以下统一用ES来代替Elasticsearch。简介Elasticsearch是一个基于Lucene库的开源搜索引擎它提供分布式的实时文件存储和搜索可扩展性好并且支持通过HTTP网络接口交互数据以JSON格式展示。ES的索引处理机制是将所有数据存放于内存中从而提高搜索效率。这一点对于我们熟悉的MySQL的B树索引结构在设计上有了显著提升和优化。因为B树需要将索引放入磁盘每次读取需要先从磁盘读取索引然后寻找对应的数据节点。另外一方面Mysql并不支持聚合操作ES可以完成复杂的操作每个字段都是有索引的。再各种场景中可以互相组合。 ES能够直接在内存中就找到目标文档对应的大致位置最大化提高效率。并且在进行组合查询的时候MySQL的劣势更加明显它不支持复杂的组合查询比如聚合操作即使要组合查询也要事先建好索引但是ES就可以完成这种复杂的操作默认每个字段都是有索引的在查询的时候可以各种互相组合。索引前面已经说过ES的索引和MySQL的概念不太一样首先我们查看ES和Mysql中的关键概念如图通过图可知ES的索引跟Mysql中的库相对应。但是再ES中不需要像MySQL那样需要手动建立相关内容。为了可以在大数据量中快速定位查找到内容ES建立索引的时候采用了一种叫做倒排索引的机制。倒排索引现在有三句话Winter is comingOurs is furyThs choice is yours按照一般常规的查询策略想要去找到其中的choice需要数据库查询整个表单内容然后通过每一条过滤才能找到对应内容所对应的id。显然这样效率非常低如果数据量非常的情况下很难得到结果。提高效率的方法就是建立索引我们给所有输入的数据都建立索引并且把这样的索引和对应的文档建立一个关联关系相当于一个词典。当我们在寻找choice的时候就可以直接像查字典一样直接找到所有包含这个数据的文档的id然后找到数据。Lucene在对文档建立索引的时候会给词典的所有的元素排好序如上图所示每一个元素都会统计出出现的频率和所在的文档在搜索的时候直接根据二分查找的方法进行筛选就能够快速找到数据这样会使效率大为提高。根据词频树进行二分查找这点可能会有些眼熟其实这就是MySQL的索引方式的直接用B树建立索引词典指向被索引的文档的原理是一样的。相比较Lucene做法ES又进一步做了更深次的处理ES希望把这个词典“搬进”内存显然直接从内存读取数据要比从磁盘读数据要快很多。但另一个问题必须解决对于海量的数据内存空间消耗必然十分巨大。如果是直接将数据放到内存肯定是不合适的。ES做了进一步的处理建立词典索引(term index)。通过词典索引可以直接找到搜索词在词典中的大致位置然后从磁盘中取出词典数据再进行查找。所以大致的结构图就变成了这样ES通过有限状态转化器把词典(term dictionary)变成了词典索引(term index)放进了内存所以这个词典索引究竟是怎么样的我们见介绍另一个概念有限状态转换有限状态转换有限状态转换器(Finite State Transducers)相当于是一个Trie前缀树可以直接根据前缀就找到对应的term在词典中的位置。比如我们现在有已经排序好的单词mop、moth、pop、star、stop和top以及他们的顺序编号0..5可以生成一个下面的状态转换图当遍历上面的每一条边的时候都会加上这条边的输出比如当输入是stop的时候会经过s/3和o/1相加得到的排序的顺序是4而对于mop得到的排序的结果是0。需要特别注意的是上面这个树它其实并没有包含所有的term而是包含了term的前缀它是通过这些前缀而快读定位到磁盘上的区域然后根据区域再去找文档列表。ES为了进一步压缩词典空间实际上每个区块只是报错block的不同部分例如start,stop在同一个以st开头的block中那么对应词典里面只会报错art和op正式通过这样的设计是ES的空间利用率提高了一倍。帧引用(Frame of Reference)在进行查询的时候经常会进行组合查询比如查询同时包含choice和the的文档那么就需要分别查出包含这两个单词的文档的id然后取这两个id列表的交集如果是查包含choice或者the的文档那么就需要分别查出posting list然后取并集。为了能够高效的进行交集和并集的操作posting list里面的id都是有序的。同时为了减小存储空间所有的id都会进行delta编码(delta-encoding我觉得可以翻译成增量编码)比如现在有id列表[73, 300, 302, 332, 343, 372]转化成每一个id相对于前一个id的增量值(第一个id的前一个id默认是0增量就是它自己)列表是[73, 227, 2, 30, 11, 29]。在这个新的列表里面所有的id都是小于255的所以每个id只需要一个字节存储。实际上ES会做的更加精细它会把所有的文档分成很多个block每个block正好包含256个文档然后单独对每个文档进行增量编码计算出存储这个block里面所有文档最多需要多少位来保存每个id并且把这个位数作为头信息(header)放在每个block 的前面。这个技术叫Frame of Reference我翻译成索引帧。比如对上面的数据进行压缩(假设每个block只有3个文件而不是256)压缩过程如下:在返回结果的时候其实也并不需要把所有的数据直接解压然后一股脑全部返回可以直接返回一个迭代器iterator直接通过迭代器的next方法逐一取出压缩的id这样也可以极大的节省计算和内存开销。通过以上的方式可以极大的节省posting list的空间消耗提高查询性能。不过ES为了提高filter过滤器查询的性能还做了更多的工作那就是缓存。总结ES为了提高搜索效率、优化存储空间做了很多工作。为了能够快速定位到目标文档ES使用倒排索引技术来优化搜索速度虽然空间消耗比较大但是搜索性能提高十分显著。由于索引数量巨大ES无法直接把全部索引放入内存转而建立词典索引构建有限状态转换器(FST)放入内存进一步提高搜索效率。数据文档的id在词典内的空间消耗也是巨大的ES使用了索引帧(Frame of Reference)技术压缩posting list带来的压缩效果十分明显。ES的filter语句采用了Roaring Bitmap技术来缓存搜索结果保证高频filter查询速度的同时降低存储空间消耗。以上为全部内容。