ElasticSearch简介
ElasticSearch是一个分布式、可扩展、近实时的高性能搜索与数据分析引擎。

ElasticSearch提供了搜索、分析、存储数据三大功能,其主要特点有:分布式、零配置、易装易用、自动发现、索引自动分片、索引副本机制、RESTful风格接口、多数据源和自动搜索负载等。

ElasticSearch基于Java编写,其内部使用Lucene做索引与搜索,通过进一步封装Lucene,向开发人员屏蔽了Lucene的复杂性。开发人员只需使用一套简单一致的RESTfulAPI即可。

除此之外,ElasticSearch解决了检索相关数据、返回统计结果、响应速度等相关的问题。因此,ElasticSearch能做到分布式环境下的实时文档存储和实时分析搜索。实时存储的文档,每个字段都可以被索引与搜索。

最令人惊喜的是,ElasticSearch能胜任上成百上千个服务节点的分布式扩展,支持PB级别的结构化或者非结构化海量数据的处理。

2019年4月10日,ElasticSearch发布了7.0版本。该版本的重要特性包含引入内存断路器、引入ElasticSearch的全新集群协调层-Zen2、支持更快的前k个查询、引入Functionscore2.0等。

其中内存断路器可以更精准的检测出无法处理的请求,并防止它们使单个节点不稳定;Zen2是ElasticSearch的全新集群协调层,提高了可靠性、性能和用户体验,使ElasticSearch变更更快、更安全,并更易于使用。

Lucene简介
Lucene是一个免费、开源、高性能、纯Java编写的全文检索引擎。

2005年,Lucene升级成为Apache顶级项目。

Lucene包含大量相关项目,核心项目有Lucene Core、Solr和PyLucene。

需要支持的是,Lucene仅仅是一个工具包,它并非一个完整的全文检索引擎,突出有点如下:

索引文件格式独立于应用平台
Lucene定义了一套以8位字节为基础的索引文件格式,能够兼容系统或者不同平台的应用能够共享创立的索引文件。

索引速度快
在传统全文检索引擎的倒排索引的基础上,实现了分块索引,能够针对新的文件建立小文件索引,提升索引速度。然后通过与原有索引的合并,达到优化的目的。

简单易学
优秀的面向对象的系统架构,降低了Lucene扩展的学习难度,方便扩充新功能。

跨语言
设计了独立于语言和文件格式的文件分析接口,索引器通过接受token流完成索引文件的创立,用户扩展新的语言与文件格式,只需实现文本分析的接口即可。

强大的查询引擎
Lucene默认实现了一套强大的查询引擎,默认实现了布尔操作、模糊查询、分组查询等。

Lucene主要模块有Analysis模块、Index模块、Store模块、QueryParser模块、Search模块和Similarity模块。

① Analysis模块:主要负责词法分析及语言处理,也就是我们常说的分词,通过该模块可最终形成存储或者搜索的最小单位元Term。

② Index模块:主要负责索引的创建工作。

③ Store模块:主要负责索引的读和写,主要是对文件的一些操作,其主要目的是抽象出和平台文件系统无关的存储。

④ QueryParser模块:主要负责语法分析,把查询语句生成Lucene底层可以识别的条件。

⑤ Search模块:主要负责对索引的搜索工作。

⑥ Similarity模块:主要负责相关性打分和排序的实现。

相关术语汇总如下:

① Term:索引中最小的存储和查询单元。对于英文语境而言,一般是指一个单词;对于中文语境而言,一般是指一个分词后的词。

② 词典:是Term的集合。词典的数据结构有很多种,各有优缺点。如可以通过排序数据(通过二次查找来检索数据)、HashMap(哈希表,检索速度更快,属于空间换时间的模式)、FST(Finite-State Transducer,有很好的压缩率)等来实现。

③ 倒排表:一篇文章通常由多个词组成,倒排表记录的是某个词在哪些文章中出现过。

④ 正向信息:原始的文档信息,可以用来做排序、聚合、展示等。

⑤ 段:索引中最小的独立存储单元。一个索引文件由一个或者多个段组成。在Lucene中,段有不变性,段一旦生成,在段上只能读取、不可写入。

知识关联点
REST定义
REST(Representational State Transfer,表达性状态转移)是所有Wen应用都应该遵守的架构设计指导原则。

REST关键原则
① Resource(资源)表示为所有事物定义ID。

② Hypertext Driven(超文本驱动)表示将所有事物链接在一起。

③ Uniform Interface(统一接口)表示使用标准方法。

7个HTTP方法:POST、GET、PUT、DELETE、PATCH、HEAD、OPTIONS。
HTTP头信息(可自定义)。
HTTP响应状态代码(可自定义)。
一套标准的内容协商机制。
一套标准的缓存机制。
一套标准的客户端身份认证机制。
④ Representation(资源的表述)表示资源多重表达的方式。

⑤ State Transfer(状态转移)表示无状态的通信。

搜索技术基本知识
数据搜索方式
数据有两种类型:即结构化数据与非结构化数据。

与数据形态相对应的,数据的搜索分两种,即结构化数据搜索与非结构化数据搜索。

结构化数据可以基于关系型数据库来存储,而关系数据库往往支持索引,因此结构化数据可以通过关系数据库来完成搜索与查找。

对于非结构化数据,数据的搜索主要有顺寻扫描和全文见搜两种方法。顺序扫描时效率很低,因此全文检索技术应运而生。

在实现全文检索的过程中,一般都需要提取非结构化数据中的有效信息,重新组织数据的承载结构形式。而搜索数据时,需要基于新结构化的数据展开,从而达到提供搜索速度的目的。显而易见,全文检索是一种空间换时间的做法——前期进行数据索引的创建,需要花费一定的时间和空间,但能显著提高后其搜索的效率。

搜索引擎工作原理
通用搜索引擎的工作原理如图:

 

搜索引擎的工作原理分为两个阶段,即网页数据爬取和索引阶段、搜索阶段。其中网页数据爬取和索引阶段包含网络爬虫、数据预处理、数据索引三个主要动作,搜索阶段包含数据关键词、输入内容预处理、搜索关键词查询三个主要动作。

常见的预处理动作有去除噪声内容、关键词处理(如中文分词、去除停止词)、网页间链接关系计算等。

数据预处理后,要进行数据索引过程。索引过程先后经历正向索引和倒排索引阶段,最终建立索引库。

倒排索引
正排索引的数据结构如图:

 

在正排索引种,以网页或文档映射关系为key、已分词的列表value。而在实际搜索网页或文章时恰恰与此结构相反,即在搜索时是以查询语句的分词列表为key来进行搜索的。因此,为了提高搜索效率,我们需要对正排索引进行转化,将其转化为分词为key、以网页或文章列表为value的结构,而这个结构就是倒排索引。

倒排索引的数据结构如图:

 

在倒排索引中,有词条(Term)、词典(Term Dictionary)、倒排表(Post List)三个名词。

词条时索引里面最小的存储和查询单元。一般来说,在英文语境中词条是一个单词,在中文语境中词条指的是分词后的一个词组。
词典又称字段,是词条的集合。单词词典一般是由网页或文章集合中出现过的所有词构成的字符串集合。
倒排表记录的是词出现在哪些文档里、出现的位置和频率等。
在倒排表中,每条记录被称作一个倒排项。

Elasticsearch是基于Lucene实现的。在Lucene中,词典和倒排表是实现快速检索的重要基石。另外,词典和倒排表是分两部分存储的,词典存储在内存中,倒排表存储在磁盘上。

结果排序
搜索结果排序是搜索引擎查询服务的核心所在排序结果决定了搜索引擎体验的好与坏、用户的使用满意度和搜索引擎的口碑。

搜索结果的排序算法也是不断迭代发展的,早期主要基于查询词出现的频率来排序,随后出现了PageRank和相关性等算法排序。

当前,在目前的搜索引擎中,还都不约而同引入了用户行为分析、数据挖掘等技术,来提升搜索结果的质量。

文档处理过程解析
文档的索引过程
写入磁盘的倒排索引是不变的。Elasticsearch主要基于一下几个考量:

(1) 读写操作轻量级,不需要锁。如果Elasticsearch从来不需要更新一个索引,则就不必担心多个程序同时尝试修改索引的情况。

(2) 一旦索引被读入文件系统的内存,它就会一直在那里,因为不会改变。此外,当文件系统内存足够大的空间时,大部分的索引读写操作是可以直接访问内存,而不是磁盘就能实现的,显然这有助于提升Elasticsearch的性能。

(3) 当写入单个大的倒排索引时,Elasticsearch可以压缩数据,以减少磁盘I/O和需要存储索引的内存大小。

倒排索引的不可变性也是一把“双刃剑”,不可变的索引也有它的缺点。首先就是它不可变,用户不能改变它。如果想要搜索一个新文档,则必须重建整个索引。这不仅严重限制了一个索引所能装下的数据,还限制了一个索引可以被更新的频率。

那么Elasticsearch是如何在保持倒排索引不可变好处的同时又能更新倒排呢?答案是:使用多个索引。

Elasticsearch不是重写整个倒排索引,而是增加额外的索引反映最近的变化。每个倒排索引都可以按顺序查询,从最“老旧”的索引开始查询,最后把结果聚合起来。

Elasticsearch的底层依赖Lucene,Lucene中的索引其实是Elasticsearch中的分片,Elasticsearch中的索引是分片的集合。当Elasticsearch搜索索引时,它发送查询请求给该索引下的所有分片,然后过滤这些结果,最后聚合成全局的结果。

为了避免混淆,Elasticsearch引入了per-segment search的概念。一个段(segment)就一个是有完整功能的倒排索引。Lucene中的索引指的是段的集合,再加上提交点(common point,包括所有段的文件)。新的文件在被写入磁盘的段之前,需要先写入内存区的索引。

一个per-segment search的工作流程如下所示:

(1) 新的文档首先被写入内存区的索引。

(2) 内存中的索引不断被提交,新段不断产生。当新的提交点产生时就将这些新段的数据写入磁盘,包括新段的名称。写入磁盘是文件同步写入的,也就是说,所有的写操作都需要等待文件系统内存的数据同步到磁盘,确保它们可以被物理写入。

(3) 新段被打开,于是它包含的文档就可以被检索到。

(4) 内存被清除,等待接收新的文档。

当一个请求被接收,所有段一次被查询时。所有段上的term统计信息会被聚合,确保每个term和文档的相关性被正确计算。通过这种方式,新的文档就能够以较小的代价加入索引。

段是不可变的,那么Elasticsearch是如何删除和更新文档数据的呢?

段的不可变特性,意味着文档既不能从旧的段中移除,旧的段中的文档也不能被更新。于是Elasticsearch在每一个提交点都引入一个.del文件,包含了段上已经被删除的文档。

当一个文档被删除时,它实际上只是在.del文件中被标记为删除。在进行文档查询时,被删除的文档依然可以被匹配查询,但是在最终返回之前会从结果中删除。

当一个文档被更新时,旧版本的文档会被标记为删除,新版本的文档在新的段中被索引。当对文档进行查询时,改文档的不同版本都会匹配一个查询请求,但是较旧的版本会从结果中被删除。

被删除的文件越积累越多,每个段消耗的如文件句柄、内存、CPU等资源越来越大。如果每次搜索请求都需要依次检查每个段,则段越多,查询就越慢。这些势必会影响Elasticsearch的性能,那么Elasticsearch是如何处理的呢?Elasticsearch引入了段合并段。在段合并时,我们会展示被删除的文件是如何从文件系统中清除的。

Elasticsearch通过后台合并段的方式解决了上述问题,在段合并过程中,小段被合并成大段,大段再合并成更大的段。再合并段时,被删除的文档不会被合并到大段中。

欢迎使用66资源网
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
7. 本站有不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!

66源码网 » ElasticSearch实战与原理解析

提供最优质的资源集合

立即查看 了解详情