《Elasticsearch技术解析与实战》Chapter 1.1:Elasticsearch入门和倒排索引

1. 简介

Elasticsearch是一个机遇Lucene构建的开源、分布式、RESTful接口全文搜索引擎。同时,Elasticsearch仍是一个分布式文档数据库,可以扩展至数百个服务器存储以处理PB级数据,一般做为复杂搜索场景的首选利器。html

Elasticsearch的优势:node

  1. 横向可扩展性:只须要增长一台服务器,配置完毕便可加入集群。
  2. 分片机制提供更好的分布性:同一个索引分红多个分片,相似于HDFS的块机制,分而治之的方式提高处理效率。
  3. 高可用:提供复制机制,一个分片能够设置多个副本,在某台服务器宕机状况下,集群依旧能够工做,并在宕机服务器重启后恢复数据。
  4. 使用简单:开箱即用,快速搭建搜索服务。

Elasticsearch wiki:https://zh.wikipedia.org/wiki/Elasticsearchgit

2. 数据库搜索

在数据量少的状况下能够当作搜索服务来使用,然而数据库归根结底是作持久化存储。若是数据量大就须要作搜索服务,底层数据仍是关系数据库。我司老系统中有一个订单表,数据量已经高达两亿,客服等后台系统一般带有范围或批量条件等查询,这时数据库基本上就没法响应了,报警根本停不下来。所以,用数据库来实现搜索,性能差,可用性不高。github

3. Lucene

Lucene是一个开源的全文搜索引擎工具包,其目的是为开发者提供一个简单工具包,以快速实现全文检索的功能。算法

Lucene wiki:https://zh.wikipedia.org/wiki/Lucene数据库

4. 倒排索引

倒排索引中的索引对象是文档或者文档集合中的单词等,用来存储这些单词在一个文档或者一组文档中的存储位置,是对文档或者文档集合的一种最经常使用的索引机制。搜索引擎的关键步骤就是创建倒排索引,下面介绍Lucene是如何创建倒排索引和相应的生成算法。数组

假设有两篇文章: 文章1:Tom lives in Guangzhou, I live in Guangzhou too. 文章2:He once lived in Shanghai.服务器

4.1 取得关键词

Lucene是基于关键词索引和查询的,首先要进行关键词提取:app

  • 分词:英文单词由空格分隔,较好处理;中文词语因为是连在一块儿的,须要进行特殊的分词处理(后面会介绍分词器相关知识)。分布式

  • 过滤无概念词语:英文中“in”“once”“too”等词没有实际意义;中文中“的”“是”等也无实际意义,这些无概念词语能够过滤掉。

  • 统一大小写:“he”和“HE”表示的含义同样,因此单词须要统一大小写。

  • 语义还原:一般用户查询“live”时但愿能将“lives”和“lived”也查询出来,因此须要将“lives”和“lived”还原成“live”。

  • 过滤标点符号

    通过以上过滤,获得以下结果: 文章1关键词:tom live guangzhou i live guangzhou 文章2关键词:he live shanghai

4.2 创建倒排索引

关键词创建完成后,就能够进行倒排索引创建了。过滤后的关系是:“文章号“对”文章中全部关键词“,倒排索引把这个关系倒过来变成:”关键词“对”拥有关键词的全部文章号“。

一般仅知道关键词在哪些文章中出现还不够,还须要知道关键词在文章中出现的次数和位置,一般有两种位置:

  1. 字符位置,即记录该词是文章中第几个字符(优势是显示并定位关键词快)。
  2. 关键词位置,即记录该词是文章中的第几个关键词(优势是节约索引空间、词组查询快),Lucene中记录的就是这种位置。

以上就是Lucene索引结构中最核心的部分,关键字是按字符顺序排列的(Lucene没有使用B树结构),所以Lucene可使用二元搜索算法快速定位关键词。

4.3 实现

Lucene将上面三列分别做为词典文件(Term Dictionary)、频率文件(frequencies)、位置文件(positions)保存。其中词典文件不只保存了每一个关键词,还保留了指向频率文件和位置文件的指针,经过指针能够找到该关键字的频率信息和位置信息。

Lucene中使用了field的概念,用于表达信息所在的位置(如标题中、文章中、url中),在建索引中,该field信息也记录在词典文件中,每一个关键词都有一个field信息,由于每一个关键字必定属于一个或多个field。

4.4 压缩算法

为了减少索引文件的大小,Lucene对索引仍是用了压缩技术。 首先,对词典文件中的关键词进行压缩,关键词压缩为<前缀长度,后缀>,例如:当前词为”阿拉伯语“,上一个词为”阿拉伯“,那么”阿拉伯语“压缩为<3,语>。 其次大量用到的是对数字的压缩,数字只保存与上一个值的差值(这样能够减小数字的长度,进而减小保存该数字须要的字节数)。例如当前文章号是16389(不压缩要用3个字节),上一文章号是16382,压缩后保存7(只用一个字节)。

压缩算法推荐阅读:https://www.cnblogs.com/dreamroute/p/8484457.html

4.5 实战

查询单词”live“,Lucene先对词典二元查找,找到该词,经过指向频率文件的指针读出全部文章号,而后返回结果。词典一般很是小,能够达到毫秒级返回。而用普通的顺序匹配算法,不创建索引,而是对全部文章的内容进行字符串匹配,过程是很缓慢的,当数据量很大时,耗时更加严重。

5. 基础概念

5.1 索引词(term)

Elasticsearch中可以被索引的精确值。foo、Foo、FOO几个单词是不一样的索引词。索引词能够经过term查询进行准确的搜索。

5.2 文本(text)

文本会被拆分红一个个索引词存储在索引库中,为后续搜索提供支持。

5.3 分析(analysis)

分析是将文本转换为索引词的过程,其结果依赖于分词器。

5.4 集群(cluster)

集群由一个或多个节点组成,对外提供服务。Elasticsearch节点若是有相同的集群名称会自动加入到同一个集群,所以若是你拥有多个独立集群,每一个集群都要设置不一样的名称。

5.5 节点(node)

节点是一个逻辑上独立的服务,是集群的一部分,能够存储数据,并参与集群的索引和搜索功能。

5.6 路由(routing)

文档存储时是经过散列值进行计算,最终选择存储在主分片中,这个值默认是由文档的ID生成。

5.7 分片(shard)

分片是单个Lucene实例,是Elasticsearch管理的比较底层的功能。当索引占用空间很大超过一个节点的物理存储,Elasticsearch将索引切分红多个分片,分散在不一样的物理节点上,以解决单物理节点存储空间有限的问题。

5.8 主分片(primary shard)

每一个文档都存储在一个分片中,存储文档时系统会首先存储在主分片中,而后复制到不一样的副本中。默认状况下一个索引拥有5个主分片,分片一旦创建,主分片数量就没法修改。

5.9 副本分片(replica shard)

每一个主分片有零个或多个副本,是主分片的复制,其主要目的是:

  1. 增长高可用性:当主分片失败时,某一副本分片提高为主分片
  2. 提升性能:副本分片数量能够动态配置,能够为主分片分担查询压力。
  3. 容许水平分割扩展数据
  4. 容许分配和并行操做,从而提升性能和吞吐量。

5.10 复制(replica)

主分片的数据会复制到副本分片中,这样避免了单点问题,当某个节点发生故障,复制能够对故障进行转移,保证系统的高可用。

5.11 索引(index)

索引是具备相同结构的文档合集。

5.12 类型(type)

一个索引能够定义一个或多个类型,类型是索引的逻辑分区。

5.13 文档(document)

文档是存储在Elasticsearch中的一个JSON格式的字符串,就像关系数据库中表的一行记录。

5.14 映射(mapping)

映射像关系数据库中的表结构,每一个索引都有一个映射,它定义了索引中的每个字段类型。映射能够事先被定义,也能够在第一次存储文档时被自动识别。

5.15 字段(field)

文档中包含零个或多个字段,字段能够是一个简单的值,也能够是一个数组或对象的嵌套结构。字段相似于关系数据库中表的列,每一个字段都对应一个字段类型。

5.16 来源字段(source field)

默认状况下源文档将被存储在_source字段中,查询时返回该字段。

5.17 主键(ID)

ID是文件的惟一标识,若是未指定,系统会自动生成一个ID,文档的index/type/id必须是惟一的。

5.18 Elasticsearch核心概念 vs. 数据库核心概念

Elasticsearch 数据库
Document row 行
Type table 表
Index database 库

Tips

本文同步发表在公众号,欢迎你们关注!😁 后续笔记欢迎关注获取第一时间更新!

相关文章
相关标签/搜索