Elastic search 数据库索引原理介绍

    最近接触了公司一个内部后台的产品设计需求,其中有部分数据存储在Elastic search数据库中(下文简称ES库),这种Nosql的数据库,以往只是进行简单的增删改查,没深入了解过,接触最多的还是关系型数据库比如MSSQL Server、Mysql之类的。接触ES库给我最大的感觉就是一个字『快』,特别是多条件联合查询,在数据量过10亿的情况下,可明显感知搜索速度的差异。本次正好借本文介绍一下ES库的基本原理。

  介绍

    ES库是一个分布式可扩展的数据库,主要用于大并发的大数据量的实时数据检索。快速的检索是有代价的,代价就是不支持类似事务管理,不支持回滚,删除数据可就真删除了。任何事情都有代价的,要想速度快就要减少一切非必要的操作。ES的这种特点决定了它不适合做OLTP类型的数据存储,因为不支持事务这一条就pass掉了。

  基本概念

    对于一个数据库产品,按照惯例,首先要了解一下这个数据库的组成,比如表结构、表字段啥的,ES库比较特殊,他是Nosql数据库,是非结构化存储的,它是面向文档型的数据库,一条数据就是一个文档。下图为关系型数据库与es库的结构对比。


可以看到,ES库在层次上和关系型数据库类似,不过在物理存储结构上就不同了,ES的数据通过Json格式存储。与ES交互,通过HTTP的Restful API方式,比如我想往ES中插入一条数据,可以通过:PUT  /project/contract/129001,来实现,PUT后边的路径分别表示的是:索引名,类型名,文档ID

{

    "ID" :    7892,

    "city_name" :      "beijing",

    "project_name" :      "KMlop",

    "create_date": "2019-08-25",

    "detail" :    "this is fist pj"

}

对于ES的增删改操作,本次不去详细描述,本文主要是分享ES的快速搜索的原理,下面我们开始了解ES快速搜索数据的原理。

索引

让我们回想一下,对于关系型数据库,如何加快速度访问的呢?第一反应就是:上索引。不管上的是聚集索引还是非聚集索引,总之,我给需要检索的列上了索引,搜索速度就上去了,那么同理,ES想要快速访问数据,也要有索引,不过ES的索引的原理和关系型的不同了,原因是上文我们提到,ES是非结构化存储,数据以JSon存储,关系型数据库的B+tree索引没办法用在这种的数据结构上,ES用的索引是倒排索引。

那什么是倒排索引呢?

倒排索引的思路是不去索引列值而是索引关键字。比如对于一个存储网站内容的列,如果索引的是这个列的内容,那么如果检索一个关键字,就需要索引全扫描,索引量如果很大或者多个关键字联合搜索就会很慢,如果索引的是关键字,那么对于这种关键字类型的查询速度就就会非常快,因为索引存的是关键字对应的记录ID。倒排索引,建立索引之前需要对内容先进行切词。

举个例子,比如有以下三条记录:

ID    name              age

1      micah latin      23

2      Jones              23

3      pink                56

4      robotic            63

假设切词直接按照单个字切分,那么nane列的切分结果为:

ID        name

1      micah/ latin

2    Jones

3    pink 

4    robotic

age列切分结果:

ID        age

1       23

2       23

3       56

4       63

其中的ID是文档ID,斜杠表示的是切分位置。  切分后就可以组织倒排索引了,

对于name列,倒排索引结果为:

Term Dictionary    Posting List

Jones                    [2]

latin                        [1]

micah                      [1]

pink                        [3]

robotic                    [4]

对于age列,倒排索引结果:

Term Dictionary    Posting List

23                            [1,2]

56                            [3]

63                            [4] 

其中,Term Dictionary是切分后的结果,可简单理解为关键字,Posting List为包该含关键字的文档ID。建立倒排索引之后,检索包含关键字的记录就非常容易了,比如检索age=23的记录,就可以很快得出是记录ID为1和2的。我们从例子上看,Term Dictionary 是有序的,因为如果不排序,那么检索索引的时间复杂度就是O(n),如果是有序的,就可以通过二分法查找,复杂度就变成LogN了,检索效率进一步提升。ES是面相大数据量检索的,如果Term Dictionary 非常大,几十亿,如果索引放不进内存,查找效率又会减下来,有没有办法呢?想一下,这时候的数据结构是不是就可以通过B+tree索引再索引一次?这就组成了二级索引,B+tree索引用来索引Term Dictionary ,而Term Dictionary 索引posting list。


压缩算法

  考虑这样一种情况,索引列是性别,那么假设性别就两种,那么每一个性别下索引的记录ID会非常多,这时候就需要对索引进行压缩。因为记录ID是整形的,就可以想到存储的时候只需要第一个记录的完整ID,其余的记录只需要记录与前一个记录的差值就可以,这样就实现了对记录ID的压缩存储,而用这种方式存储数据,就需要存储的数据结构是变化的,因为很明显,存储数字100000,和存储10不能用一个数据结构,这样会造成空间的浪费。那么怎么实现变长的数据存储呢?把需要存储的posting list进行分组,每组用一段bit存储。每段bit开头给出这段bit中用几个bit存储一个数字。


压缩的步骤为:

1、通过delta编码算法,把posting list中的整数进行增量编码。编码的步骤为:

1)用Elisa Gamma Code的方式编码x的长度:Cr (floor(log(x)) + 1);

2)求出x的二进制表示,并且用Cr做前缀

3)去掉x二进制表示中的第一个1

2、将第一步得到的增量编码进行分块(一块128个数据,上图为了解释原理,3个数字一个块)。

3、对每个分块统计其中最大的数需要多少个bit,把这个数放到数据块头部,读取数据时用于判断多少位表示一个数据。

总结

ES为了极致的查询速度,舍弃了一切不必要的操作(事务管理)。通过倒排全文索引配合使用二级索引,进一步提高检索效率,对于索引数据进行增量压缩,以便索引可以放入内存,这是CPU时间换内存空间的策略。根据压缩策略算法可知,如果记录ID是随机的,那么压缩效率就会很低,所以记录的ID最好是连续的,这样压缩效率最好。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339

推荐阅读更多精彩内容