ES的索引结构与算法解析

这篇具有很好参考价值的文章主要介绍了ES的索引结构与算法解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作者:京东物流 李洪吉

提到ES,大多数爱好者想到的都是搜索引擎,但是明确一点,ES不等同于搜索引擎。不管是谷歌、百度、必应、搜狗为代表的自然语言处理(NLP)、爬虫、网页处理、大数据处理的全文搜索引擎,还是有明确搜索目的的搜索行为,如各大电商网站、OA、站内搜索、视频网站的垂直搜索引擎,他们或多或少都使用到了ES。

​作为搜索引擎的一部分,ES自然具有速度快、结果准确、结果丰富等特点,那么ES是如何达到“搜索引擎”级别的查询效率呢?首先是索引,其次是压缩算法,接下来我们就一起了解下ES的索引结构和压缩算法

1 结构

1.1 Mysql

Mysql下的data目录存放的文件就是mysql相关数据,mysql文件夹对应的就是数据库mysql。

其中表columns_priv对应了3个文件:columns_priv.frm、columns_priv.MYD、columns_priv.MYI。

.frm:表结构;.MYD:myisam存储引擎原数据;.MYI:myisam存储引擎索引;.ibd:innodb存储引擎数据

1.2 Elasticsearch

cfe为索引文,cfs 为数据文件,cfe文件保存Lucene各文件在.cfs文件的位置信息

cfs、cfe 在segment还很小的时候,将segment的所有文件都存在在cfs中,在cfs逐渐变大时,大小超过shard的10%,则会拆分为其他文件,如tim、dvd、fdt等文件

1.3 存储结构

倒排索引结构分为倒排表、词项字典、词项索引

倒排表包含某个词项的所有id的数据存储了在.doc文件中

词项字典包含了index field的所有经过处理之后的词项数据,最终存储在.tim文件中

1.4 结构对比

我们以某商城的手机为例,左侧为es倒排索引结构,右侧为原始数据。左侧图示只是为了展示倒排索引结构,并不是说es中倒排表就是简单的数组

以上面结构对比示例图为例,假如共有10亿条数据需要存储在ES中(上图右),分词后存储的倒排表(上图左)大概包含分词term以及对应的id数组等,在10亿条数据中,分词“小米”相关的数据有100万条,也就是说分词“小米”对应的数组Posting List长度是100万

id是int类型的有序主键,分词“小米”在数组Posting List中100万int类型数字总长度=100万✖每个int占4字节=400万Byte≈4MB。1个分词占4MB空间,假如10亿条数据有500万个分词,总空间=4MB✖500万=2千万MB,磁盘空间直接爆炸

2 算法

分词对应的数组Posting List实际就是一个个有序数组,而有序数值数组是比较容易进行压缩处理的,而且一般来说压缩效益也不错,如果能对其进行压缩是能够大大节约空间资源的

ES中倒排索引的压缩算法主要有FOR算法(Frame Of Reference)和RBM算法(RoaringBitMap)

2.1 FOR

FOR算法的核心思想是用减法来削减数值大小,从而达到降低空间存储。 假设V(n)表示数组中第n个字段的值,那么经过FOR算法压缩的数值V(n)=V(n)-V(n-1)。也就是说存储的是后一位减去前一位的差值。存储是也不再按照int来计算了,而是看这个数组的最大值需要占用多少bit来计算

我们按照差值计算的方式来保存数据,初始值为1,2与1的差值为1,3与2的差值为1……最终我们就将原始Posting List数据转化为100万个1,每个1我们可以用1bit来记录,总空间=1bit✖100万=100万bit,相比原有400万Byte=3200bit,空间压缩了32倍

在实际生产中,不可能出现一个term的Posting List是这种差值均为1的情况,所以我们以通用示例举例。假如原数据为[73,300,302,332,343,372],数组中6个数字占据总空间为24字节。按照差值方式记录,数组转化为[73,227,2,30,11,29],最大数字为227,大于2的7次方128,小于2的8次方256,所以每个数字可以使用8bit即1Byte来保存,占据总空间为1Byte*6 + 1Byte=7Byte

在此基础上,我们将差值数组按照密集度划分为[73,227]和[2,30,11,29],其中[73,227]中最大值227介于2的7次方和2的8次方之间,所以用8bit=1Byte作为切割分段,[2,30,11,29]中最大数30介于2的4次方和2的5次方之间,所以用5bit作为切割分段。

数组[73,227]占据总空间为8bit✖2个=16bit=2Byte

数组[2,30,11,29]占据总空间为5bit✖4个=20bit=3Byte

为什么20bit=3Byte呢?因为8bit=1Byte,小于8bit也会占据1个字节空间,所以17bit到24bit均为3Byte

所以,最终占据总空间=1+2+1+3=7Byte

疑问一:既然原数组[73,300,302,332,343,372]要按照密集度拆分为[73,227]和[2,30,11,29]两个数组,那为什么不继续往下拆分,直接拆分到每个数字是一个数组,这样使用bit记录时占据总空间会更少?

答:如果继续拆分数组,空间确实会使用更少,但是,之前我们提到搜索引擎速度快的方式有两种:高效的压缩算法和快速的编码解码速度,单个数字存储确实压缩了空间,但是我们无法再通过解码的方式将源数据还原

疑问二:为什么源数据使用差值记录占据6Byte,拆分数组后占据7Byte,拆分后占据空间不变,有时候甚至会变大,为什么?

答:数据量小的情况下确实会出现该情况,因为我们需要拆分数组并记录拆分数组的长度(如上面示例中的8bit和5bit),在原数据存储空间基础上还要存储拆分长度,所以数据量小的情况下会出现比直接存储占据空间大的情况。但是不管是搜索引擎还是Elasticsearch更多处理的是海量数据,数据量越多,差值数组拆分的方式节省空间越明显

2.2 RBM

我们已经了解了FOR压缩算法,算法核心是将PostingList按照差值密集度转化成两个差值数组。在这里我们要考虑一种情况就是:在大数据中,10亿条数据分词500万个,如果分词“小米”所在PostList比较分散且差值很大,此时使用FOR算法效果就会大打折扣。所以稀疏的数组,不适合使用FOR算法

在这里我们以[1000,62101,131385,132052,191173,196658]为例,如果按照FOR算法,转化成的差值数组为[1000,61101,69284,667,59121,5485]密集度很低。我们采用RBM算法

源数据PostingList是由int类型组成的数组,int类型=4Byte=32bit,最大值=2的32次方-1=4294967295≈43亿。当数据较大且稀疏时,我们将32bit拆分为16bit和16bit,16bit最大值=65535,前16bit存放,后16bit存放余数,所以商和余数都不会超过65535.我们将源数组的值除以65536,得到的商和余数分别存放在前16bit和后16bit。

以数字196658为例,转化为2进制,前16位=3,后16位=50

得到的结果以K-V存放。Key最大值为16bit,所以以short[]数组存放,Value以Container存放。

由于源数组为有序数组,所以按照高低16位转化后,商和余数都是从小到大排列

通过看Container源码,我们可以看到Container有3种:ArrayContainer、BitmapContainer、RunContainer。

  1. ArrayContainer本质为集合,所以随着数组中数量越多,占用空间越多,呈正向增长。

当数组种数量为4096时,占据总空间=4096个✖16bit(即2Byte)➗1024=8KB

当数组种数量为65536时,占据总空间=65536个✖16bit(即2Byte)➗1024=128KB

  1. BitmapContainer位图,核心就是将原有存储数值转化成该数值在哪个位置上存在

由于余数最大值为65535,所以我们需要65536位位图,数值是多少,在位图上对应的位置就是多少。数值等于4096,则位图上4096位值为1;数值等于65535,则位图上65535位值为1。每个位置上的数都占用8KB空间(8KB=65536bit)

  • RunContainer用法相对狭隘,这种类型是Lucene 5之后新增的类型,主要应用在连续数字的存储商,比如倒排表中存储的数组为 [1,2,3…100W] 这样的连续数组,如果使用RunContainer,只需存储开头和结尾两个数字:1和100W,即占用8个字节。这种存储方式的优缺点都很明显,它严重收到数字连续性的影响,连续的数字越多,它存储的效率就越高
  • 如果数组是如下形式 [1,2,3,4,5,100,101,102,999,1000,1001] 就会被拆分为三段:[1,5],[100,102],[999,1001]

至于每次存储采用什么容器,需要进行一下判定,比如ArrayContainer,当存储的元素少于4096个时,他会比BitmapContainer占用更少空间,而当大于4096个元素时,采用ArrayContainer所需要的空间就会大于8kb,那么采用BitmapContainer就会占用更少空间

3 总结

ES在处理海量数据时通过其独到的结构和压缩算法,将索引效率尽可能的提升。虽然在实际业务处理中我们极少遇到海量数据处理的情况,但是通过了解ES的原理,能够帮我们开阔下视野,了解数字之美,算法之美。文章来源地址https://www.toymoban.com/news/detail-423879.html

到了这里,关于ES的索引结构与算法解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 事务,不只ACID | 京东物流技术团队

    1. 什么是事务? 应用在运行时可能会发生数据库、硬件的故障,应用与数据库的网络连接断开或多个客户端端并发修改数据导致预期之外的数据覆盖问题,为了提高应用的可靠性和数据的一致性, 事务 应运而生。 从概念上讲,事务是 应用程序将多个读写操作组合成一个逻

    2024年02月13日
    浏览(33)
  • 极智嘉x吉利汽车 x京东物流,引领汽车行业智慧物流新变革!

    近日,中国领先的汽车制造商吉利汽车携手中国领先的技术驱动的供应链解决方案及物流服务商京东物流、全球仓储机器人引领者极智嘉(Geek+),在西安吉利汽车制造基地RDC仓库率先落地SkyPick上存下拣解决方案,实现了全物流链精益化、智能化、一体化管理,创造了汽车行业

    2024年02月11日
    浏览(27)
  • 菜鸟、京东物流再提速,快递业卷出新高度

    随着行业的成熟,物流快递行业的服务效率之争再次提速。3月31日,天猫超市宣布在杭州启动半日达服务,这意味着其快递包裹从下单到签收仅需半天。据公开资料显示,此次半日达服务从2022年底就开始筹备了。作为天猫超市的物流合作方,菜鸟提出了“1212”物流履约模式

    2023年04月23日
    浏览(41)
  • 浅谈常态化压测 | 京东物流技术团队

    常态是指:“正常的状态”;“化”在这里是表示转变为某种性质或状态。 “常态化”的含义就是:趋向正常的状态。 那么常态化压测顾名思义就可以解释为,让压测趋于正常的状态,趋于合理 ;因此通过调研给了如下定义:常态化压测是指在某个产品或系统上进行自定义

    2024年02月16日
    浏览(23)
  • MySQL表结构转换为ES索引Mapping

    日常开发过程中肯定会存在MySQL表数据迁移至ES的情况,以canal为例,数据迁移时需要提前在ES中创建索引Mapping,但是如果碰到字段特别的表时,创建Mapping将是一件耗费心神的事情。为了解决这些重复工作,我使用Python编写了一个脚本,自动将MySQL中的表结构同步到ES中,本脚

    2024年02月03日
    浏览(32)
  • ES删除索引中的所有数据(不删除索引结构)含curl删除方式

    场景:想只删除索引下的数据,不删除索引结构,(windows环境)服务器中没有postman工具 第一种:只删除索引中的所有数据,不删除索引结构 第二种:删除索引中的指定的数据,不删除索引结构 第三种:删除所有数据,删除索引结构 windows环境中curl方式删除 第一种:删除所有

    2024年02月11日
    浏览(36)
  • Java单元测试及常用语句 | 京东物流技术团队

    编写Java单元测试用例,即把一段复杂的代码拆解成一系列简单的单元测试用例,并且无需启动服务,在短时间内测试代码中的处理逻辑。写好Java单元测试用例,其实就是把“复杂问题简单化,建单问题深入化“。在编写的过程中, 我们也可以对自己的代码进行一个二次检查

    2024年02月10日
    浏览(25)
  • @ControllerAdvice注解使用及原理探究 | 京东物流技术团队

    最近在新项目的开发过程中,遇到了个问题,需要将一些异常的业务流程返回给前端,需要提供给前端不同的响应码,前端再在次基础上做提示语言的国际化适配。这些异常流程涉及业务层和控制层的各个地方,如果每个地方都写一些重复代码显得很冗余。 然后查询解决方案

    2024年02月14日
    浏览(39)
  • 倒排索引:ES倒排索引底层原理及FST算法的实现过程

    这也许是你全网你能找到的最详细的倒排索引的底层解读。博主把倒排索引的讲解划分为以下七个部分,理解难度递增,可根据自身需要选择依次阅读或者针对性阅读。 通常来说,应付一般的面试,理解第一部分即可。如果需要面试搜索相关业务的岗位,需要深层次理解倒排

    2024年01月21日
    浏览(37)
  • 破局主键重复问题的坎坷路 | 京东物流技术团队

    伴随着业务的不断发展,逐渐由单库单表向分库分表进行发展。在这个过程中不可避免的一个问题是确保主键要的唯一性,以便于后续的数据聚合、分析等等场景的使用。在进行分库分表的解决方案中有多种技术选型,大概分为两大类客户端分库分表、服务端分库分表。例如

    2024年02月10日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包