`
weitao1026
  • 浏览: 1047316 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Elasticsearch是当今最流行的分布式搜索引擎

阅读更多

Elasticsearch是当今最流行的分布式搜索引擎,GitHub、 SalesforceIQ、Netflix等公司将其用于全文检索和分析应用。在Insight,我们用到了Elasticsearch的诸多不同功能,比如:

  • 全文检索 

比如找到与搜索词项(term)最相关的维基百科文章。

  • 聚合 

比如在广告网络中,可视化的搜索词项的竞价直方图。

  • 地理空间API 

比如在顺风车平台,匹配最近的司机和乘客。

正是因为Elasticsearch如此流行并且就在我们身边,我决定深入研究一下。本文,我将分享Elasticsearch的存储模型和CRUD操作的工作原理。

当我在思考分布式系统是如何工作时,我脑海里的图案是这样的:

剖析Elasticsearch集群:存储模型和读写操作

<iframe style="position: static; display: block; padding: 0; margin: 0; border: none; vertical-align: baseline; width: 100%; height: 74px;" frameborder="0" scrolling="no"></iframe>

 

 

水面以上的是API,以下的才是真正的引擎,一切魔幻般的事件都发生在水下。本文所关注的就是水下的部分,我们将关注:

  • Elasticsearch是主从架构还是无主架构

  • Elasticsearch的存储模型是什么样的

  • Elasticsearch是怎么执行写操作的

  • Elasticsearch是怎么执行读操作的

  • 如何定义搜索结果的相关性

在我们深入这些概念之前,让我们熟悉下相关的术语。

1 辨析Elasticsearch的索引与Lucene的索引

Elasticsearch中的索引是组织数据的逻辑空间(就好比数据库)。1个Elasticsearch的索引有1个或者多个分片(默认是5个)。分片对应实际存储数据的Lucene的索引,分片自身就是一个搜索引擎。每个分片有0或者多个副本(默认是1个)。Elasticsearch的索引还包含"type"(就像数据库中的表),用于逻辑上隔离索引中的数据。在Elasticsearch的索引中,给定一个type,它的所有文档会拥有相同的属性(就像表的schema)。

剖析Elasticsearch集群:存储模型和读写操作

<iframe style="position: static; display: block; padding: 0; margin: 0; border: none; vertical-align: baseline; width: 100%; height: 74px;" frameborder="0" scrolling="no"></iframe>


图a展示了一个包含3个分片的Elasticsearch索引,每个分片拥有1个副本。这些分片组成了一个Elasticsearch索引,每个分片自身是一个Lucene索引。图b展示了Elasticsearch索引、分片、Lucene索引和文档之间的逻辑关系。

 

对应于关系数据库术语 

Elasticsearch Index == Database 
Types == Tables 
Properties == Schema

现在我们熟悉了Elasticsearch世界的术语,接下来让我们看一下节点有哪些不同的角色。

2 节点类型

一个Elasticsearch实例是一个节点,一组节点组成了集群。Elasticsearch集群中的节点可以配置为3种不同的角色:

  • 主节点:控制Elasticsearch集群,负责集群中的操作,比如创建/删除一个索引,跟踪集群中的节点,分配分片到节点。主节点处理集群的状态并广播到其他节点,并接收其他节点的确认响应。

    每个节点都可以通过设定配置文件elasticsearch.yml中的node.master属性为true(默认)成为主节点。

    对于大型的生产集群来说,推荐使用一个专门的主节点来控制集群,该节点将不处理任何用户请求。

  • 数据节点:持有数据和倒排索引。默认情况下,每个节点都可以通过设定配置文件elasticsearch.yml中的node.data属性为true(默认)成为数据节点。如果我们要使用一个专门的主节点,应将其node.data属性设置为false。

  • 客户端节点:如果我们将node.master属性和node.data属性都设置为false,那么该节点就是一个客户端节点,扮演一个负载均衡的角色,将到来的请求路由到集群中的各个节点。

Elasticsearch集群中作为客户端接入的节点叫协调节点。协调节点会将客户端请求路由到集群中合适的分片上。对于读请求来说,协调节点每次会选择不同的分片处理请求,以实现负载均衡。

在我们开始研究发送给协调节点的CRUD请求是如何在集群中传播并被引擎执行之前,让我们先来看一下Elasticsearch内部是如何存储数据,以支持全文检索结果的低延迟服务的。

存储模型

Elasticsearch使用了Apache Lucene,后者是Doug Cutting(Apache Hadoop之父)使用Java开发的全文检索工具库,其内部使用的是被称为倒排索引的数据结构,其设计是为全文检索结果的低延迟提供服务。文档是Elasticsearch的数据单位,对文档中的词项进行分词,并创建去重词项的有序列表,将词项与其在文档中出现的位置列表关联,便形成了倒排索引。

这和一本书后面的索引非常类似,即书中包含的词汇与其出现的页码列表关联。当我们说文档被索引了,我们指的是倒排索引。我们来看下如下2个文档是如何被倒排索引的:

文档1(Doc 1): Insight Data Engineering Fellows Program 
文档2(Doc 2): Insight Data Science Fellows Program

词项 文档
data Doc 1, Doc 2
engineering Doc 1
fellows Doc 1, Doc 2
insight Doc 1, Doc 2
program Doc 1, Doc 2
science Doc 2

如果我们想找包含词项"insight"的文档,我们可以扫描这个(单词有序的)倒排索引,找到"insight"并返回包含改词的文档ID,示例中是Doc 1和Doc 2。

为了提高可检索性(比如希望大小写单词都返回),我们应当先分析文档再对其索引。分析包括2个部分:

  • 将句子词条化为独立的单词

  • 将单词规范化为标准形式

默认情况下,Elasticsearch使用标准分析器,它使用了:

  • 标准分词器以单词为界来切词

  • 小写词条(token)过滤器来转换单词

还有很多可用的分析器在此不列举,请参考相关文档。

为了实现查询时能得到对应的结果,查询时应使用与索引时一致的分析器,对文档进行分析。

注意:标准分析器包含了停用词过滤器,但默认情况下没有启用。

现在,倒排索引的概念已经清楚,让我们开始CRUD操作的研究吧。我们从写操作开始。

剖析写操作

创建((C)reate)

当我们发送索引一个新文档的请求到协调节点后,将发生如下一组操作:

  • Elasticsearch集群中的每个节点都包含了改节点上分片的元数据信息。协调节点(默认)使用文档ID参与计算,以便为路由提供合适的分片。Elasticsearch使用MurMurHash3函数对文档ID进行哈希,其结果再对分片数量取模,得到的结果即是索引文档的分片。

    shard = hash(document_id)%(num_of_primary_shards)

  • 当分片所在的节点接收到来自协调节点的请求后,会将该请求写入translog(我们将在本系列接下来的文章中讲到),并将文档加入内存缓冲。如果请求在主分片上成功处理,该请求会并行发送到该分片的副本上。当translog被同步(fsync)到全部的主分片及其副本上后,客户端才会收到确认通知。

  • 内存缓冲会被周期性刷新(默认是1秒),内容将被写到文件系统缓存的一个新段上。虽然这个段并没有被同步(fsync),但它是开放的,内容可以被搜索到。

  • 每30分钟,或者当translog很大的时候,translog会被清空,文件系统缓存会被同步。这个过程在Elasticsearch中称为冲洗(flush)。在冲洗过程中,内存中的缓冲将被清除,内容被写入一个新段。段的fsync将创建一个新的提交点,并将内容刷新到磁盘。旧的translog将被删除并开始一个新的translog。

下图展示了写请求及其数据流。

<iframe style="position: static; display: block; padding: 0; margin: 0; border: none; vertical-align: baseline; width: 100%; height: 74px;" frameborder="0" scrolling="no"></iframe>

 

 

更新((U)pdate)和删除((D)elete)

删除和更新也都是写操作。但是Elasticsearch中的文档是不可变的,因此不能被删除或者改动以展示其变更。那么,该如何删除和更新文档呢?

磁盘上的每个段都有一个相应的.del文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并(我们将在本系列接下来的文章中讲到)时,在.del文件中被标记为删除的文档将不会被写入新段。

接下来我们看更新是如何工作的。在新的文档被创建时,Elasticsearch会为该文档指定一个版本号。当执行更新时,旧版本的文档在.del文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。

文档被索引或者更新后,我们就可以执行查询操作了。让我们看看在Elasticsearch中是如何处理查询请求的。

剖析读操作((R)ead)

读操作包含2部分内容:

  • 查询阶段

  • 提取阶段

我们来看下每个阶段是如何工作的。

查询阶段

在这个阶段,协调节点会将查询请求路由到索引的全部分片(主分片或者其副本)上。每个分片独立执行查询,并为查询结果创建一个优先队列,以相关性得分排序(我们将在本系列的后续文章中讲到)。全部分片都将匹配文档的ID及其相关性得分返回给协调节点。协调节点创建一个优先队列并对结果进行全局排序。会有很多文档匹配结果,但是,默认情况下,每个分片只发送前10个结果给协调节点,协调节点为全部分片上的这些结果创建优先队列并返回前10个作为hit。

提取阶段

当协调节点在生成的全局有序的文档列表中,为全部结果排好序后,它将向包含原始文档的分片发起请求。全部分片填充文档信息并将其返回给协调节点。

下图展示了读请求及其数据流。

<iframe style="position: static; display: block; padding: 0; margin: 0; border: none; vertical-align: baseline; width: 100%; height: 74px;" frameborder="0" scrolling="no"></iframe>

 

 

如上所述,查询结果是按相关性排序的。接下来,让我们看看相关性是如何定义的。

搜索相关性

相关性是由搜索结果中Elasticsearch打给每个文档的得分决定的。默认使用的排序算法是tf/idf(词频/逆文档频率)。词频衡量了一个词项在文档中出现的次数 (频率越高 == 相关性越高),逆文档频率衡量了词项在全部索引中出现的频率,是一个索引中文档总数的百分比(频率越高 == 相关性越低)。最后的得分是tf-idf得分与其他因子比如(短语查询中的)词项接近度、(模糊查询中的)词项相似度等的组合。

接下来有什么?

这些CRUD操作由Elasticsearch内部的一些数据结构所支持,这对于理解Elasticsearch的工作机制非常重要。在接下来的系列文章中,我将带大家走进类似的那些概念并告诉大家在使用Elasticsearch中有哪些坑。

  • Elasticsearch中的脑裂问题及防治措施

  • 事务日志

  • Lucene的段

  • 为什么搜索时使用深层分页很危险

  • 计算搜索相关性中困难及权衡

  • 并发控制

  • 为什么Elasticsearch是准实时的

  • 如何确保读和写的一致性

分享到:
评论

相关推荐

    elasticsearch安装及使用教程

    Elasticsearch 是一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎,可以说 Lucene 是当今最先进,最高效的全功能开源搜索引擎框架。Elasticsearch 使用 Lucene 作为内部引擎,但是在你使用它做全文搜索...

    elasticsearch与hadoop比较

    Elasticsearch是一个基于Lucene的分布式搜索服务器,其设计目的是提供一个分布式的、可扩展的全文搜索引擎,同时也具备数据的聚合和统计分析能力。而Hadoop是一个由Apache软件基金会开发的开源框架,它允许使用简单...

    elasticsearch-jdbc-2.3.3.0-dist.zip

    Elasticsearch作为一个强大的开源搜索引擎,以其分布式、实时、灵活的特性,广泛应用于日志分析、信息检索等领域。而MySQL作为常用的SQL数据库,存储了大量的结构化数据。将这两者结合,通过Elasticsearch的JDBC插件...

    elasticsearch-analysis-ik-6.6.1.zip

    Elasticsearch(简称ES)是当今最流行的开源全文搜索引擎,它基于Lucene库,提供分布式、实时、可扩展的搜索和分析功能。而Analysis IK插件则是专门为Elasticsearch定制的,它的设计目标是使中文分词更加智能和灵活...

    Python库 | guillotina_elasticsearch-1.3.11-py3-none-any.whl

    首先,Elasticsearch是当今最流行的开源全文搜索引擎,它基于Lucene构建,具有分布式、实时、可扩展的特点,广泛应用于日志分析、网站搜索、实时数据分析等多个场景。而guillotina_elasticsearch则是Python框架...

    分布式日志处理系统调研报告

    - 实时分析的分布式搜索引擎 - 分布式实时文件存储,所有字段均被编入索引 - 文档导向,所有对象都被视为文档 - 易于扩展和支持集群操作 - 提供 RESTful 风格 API,支持 JSON 传输 - 高可用性设计,支持自动...

    elasticsearch-learning-to-rank-es_7_6_2.zip

    Elasticsearch,作为一个开源、分布式、实时的全文搜索引擎,因其强大的搜索能力和灵活的数据处理能力,被广泛应用于各种场景。本教程将重点探讨Elasticsearch 7.6.2版本中的学习至排名(Learning to Rank, LTR)...

    Springboot集成elasticsearch

    Elasticsearch(简称ES)作为一个强大的分布式搜索引擎,因其易用性、高可扩展性和实时性能而备受青睐。Spring Boot,作为Java开发框架的明星产品,通过简化配置使得开发变得更加便捷。本文将深入探讨如何将Spring ...

    spring-boot-elasticsearch v1.0.zip

    而Elasticsearch作为一个强大的分布式搜索引擎,为处理海量数据提供了高效、灵活的解决方案。本资料包“spring-boot-elasticsearch v1.0.zip”正是针对这两个技术的整合,旨在帮助开发者快速理解和应用Spring Boot与...

    Elasticsearch+MySQL数据同步示例

    Elasticsearch和MySQL是当今流行的数据库技术,它们在数据存储和检索方面各自有优势。Elasticsearch以其强大的搜索功能著称,而MySQL则是一个成熟的开源关系型数据库管理系统。将Elasticsearch与MySQL结合起来,可以...

    SpringBoot整合ES搜索

    在当今数字化的时代,快速、高效的搜索引擎是每个大数据应用不可或缺的一部分。而Elasticsearch(简称ES),凭借其出色的全文搜索引擎功能,已经在众多场景中得到了广泛应用。结合Spring Boot进行开发,不仅能简化...

    ElasticView 是一款用来监控ElasticSearch状态和操作ElasticSearch索引的web可视化工具

    Elasticsearch是当今广泛使用的分布式全文搜索引擎,常用于大数据分析、日志分析和实时搜索等场景。它的核心特性包括高度可扩展性、实时性能以及强大的分析能力。ElasticView的出现,弥补了Elasticsearch原生管理...

    elasticsearch-analysis-ik-7.15.1.zip

    在当今大数据时代,文本处理与搜索功能是许多应用程序的核心,而Elasticsearch作为一款强大的全文搜索引擎,因其高性能、易扩展的特性,被广泛应用于日志分析、信息检索等领域。在这个背景下,Elasticsearch的IK分词...

    elasticsearch demo 包括本地测试ElasticSearchCreate 增加 删除 修改 查询 和 连接服务器 demo

    **Elasticsearch(ES)是当今广泛使用的分布式搜索引擎和分析平台,尤其在日志分析、实时数据搜索和大数据处理方面表现突出。本示例将详细解释如何在本地环境中进行Elasticsearch的创建、增加、删除、修改和查询操作...

    elasticsearch

    Elasticsearch,简称ES,是当今最流行的大数据搜索引擎之一,尤其在日志分析、实时数据分析和全文检索领域有着广泛的应用。它是一个基于Lucene的开源分布式搜索和分析引擎,设计目标是提供一个高可用性、可扩展且近...

    基于分布式架构的海量文本快速相似度检测研究.pdf

    接着,利用分布式搜索引擎Elasticsearch召回候选样本集。Elasticsearch是一款强大的实时分布式搜索和分析引擎,能够在大规模数据集上提供高效的检索服务。它支持分布式的文档存储、索引和搜索,能够轻松处理海量文本...

    CCTC 2016 Elastic曾勇:Elasticsearch & Bigdata

    Elasticsearch作为一个开源、分布式、可扩展的全文搜索引擎,能够实现实时搜索和分析能力,其易于使用、灵活和可扩展的特点,在当今大数据时代具有重要的地位和作用。它支持的数据量、实时搜索和分析能力以及易于...

    毕设&课程作业_基于ElasticSearch + Spark的智能搜索和推荐系统.zip

    Elasticsearch(简称ES)是一个开源的全文搜索引擎,基于Lucene构建。它提供了分布式、实时、高可用性的搜索和分析能力。在本系统中,Elasticsearch主要负责存储和索引大量数据,以及处理用户的查询请求。其分布式...

    elasticsearch-analysis-ik-1.2.6

    Elasticsearch是当今流行的全文搜索引擎,它基于Lucene库,提供了分布式、实时、可扩展的搜索和分析能力。为了更好地适应中文处理,Elasticsearch引入了各种分析器,其中IK(Intelligent Word Segmentation,智能词...

    基于搜索引擎的大数据分析技术.pptx

    Elasticsearch 是一个强大的分布式搜索和分析引擎,它基于 Lucene 库,并提供了一个 RESTful 风格的接口。Elasticsearch 具有以下几个核心特性: 1. **分布式**: 能够在多台服务器上构建集群,提供高可用性和容错性...

Global site tag (gtag.js) - Google Analytics