Elasticsearch原理与实现(一)

概述

Elastic官方对Elasticsearch的定义是这样的:Elastic is a highly scalable open-source full-text search and analytics engine。可见官方定义中,Elasticsearch被视为一种高度可伸缩的全文检索和分析引擎,这体现了Elasticsearch具有强大的文档检索和分析能力。Elasticsearch底层基于Apache Lucene,而Lucene本身一种早就闻名于世的全文检索引擎和工具包。Elasticsearch在此基础上进行了封装,不仅继承了Lucene所有优点,还大大降低了使用和开发的复杂度。所以从这个角度来说,Elasticsearch是一种全文检索和分析引擎。
但事实上,Elasticsearch也包含了强大的数据存储能力,它所检索的数据不依赖于外部数据源,而由Elasticsearch统一管理。不仅如此,Elasticsearch还具备创建数据分片(Shard)和数据副本(Replica)的能力,可以满足大数据量下的高可用性和高性能要求。所以在许多文献中,Elasticsearch也被归类为一种基于文档的NoSQL数据库,类似于MongoDB。事实上,正是这种优秀的存储能力,才使Elasticsearch具备了强大的检索和分析能力。

全文检索和倒排索引

先以对比传统数据库的方式来解释一些基本概念。

  • 索引(Index)相当于库;
  • 映射类型(Mapping Type)相当于表;
  • 文档(Document)相当于行;
  • 字段(Field)相当于列。

全文检索

先来解释一下什么叫全文检索。数据库检索的目的是从一系列数据中,根据某一或某些数据特征将特定的数据找出来。从数据检索的角度来看,数据大体上可以分为两种类型:一种是结构化数据;另一种是非结构化数据。结构化数据将数据具有的特征事先以结构化的形式定义好,数据有固定的格式或有限的长度。典型的结构化数据就是传统关系型数据库的表结构,数据特征直接体现在表结构的字段上,所以根据某一特征做数据检索很直接,速度也比较快。比如,根据商品的名称将该商品全部查找出来,通过一条SQL语句就能实现。如果想要提高查找速度,只要在商品名称上创建索引就可以了。许多应用系统都是建立在结构化数据的基础之上,例如财务软件、CRM、MIS等。
非结构化数据则完全不同,他们没有预先定义好的结构化特征,也没有固定格式和固定长度。典型的非结构化数据包括文章、图片、视频、网页、邮件等。其中像HTML网页这种具有一定格式的文档也称为半结构化数据。显而易见,相比结构化数据,非结构化数据的检索要难得多。在对他们的检索中,像文章、网页、邮件这种全文本(Full-text)数据的检索需要占了大多数,而且与图片、视频等非文本数据的检索完全不同,因此形成了一门独立的学科,这就是全文检索。包括Elastic官网在内的很多文献中,经常称全文本数据中的一条数据为文档(Document),而称存储全文本数据的数据库为全文本数据库。所以简单来说,全文本检索是指在全文数据中检索单个文档或文档集合的搜索技术,而Elasticsearch从这个意义来说也可以理解为是一个全文数据库。
与结构化查询相比,全文检索面临的最大问题就是性能问题。全文检索最一般的应用场景是根据一些关键字查询网页。显然,如果没有对文档做特别处理,查找的办法似乎只能是逐条比对。具体来说就是先将所有文档都读取出来,再对文档内容做逐行扫描看是否包含这些关键字。例如,Linux的grep命令就是通过这种算法实现的。但这种方法在数据量非常大的情况下就像大海捞针一样,速度会非常慢。而类似互联网搜索引擎这样的应用面对的文档往往都是天文数字,所以需要有一种更好的办法实现全文检索。
关系型数据库提示数据查询速度的常用方法是给字段添加索引,有了索引的字段会根据字段值排序并创建类似排序二叉树的数据结构(如B树),这样就可以利用二分查找等算法提升查询速度。所以在字段添加索引后,通过这些字段做查询时速度呢能得到非常明显的提升。但由于添加索引后需要对字段排序,所以增加和删除数据时速度会变慢,并且还需要额外的空间存储索引。这是典型的利用空间换取时间的策略。普通的索引对全文检索并适用,因为这种索引使用字段整体值参与排序,所以在检索时也需要通过字段的整体值做查询条件。而全文检索一般是查询包含某一或某些关键字的文档,所以通过文档整体值建立的索引对提供查询速度是没有任何帮助的。为了解决这个问题,人员创建了一种新索引方法,这种索引方法就是倒排索引(Inverted Index)。

倒排索引

倒排索引先将文档中包含的关键字全部提取出来,然后再将关键字与文档的对应关系保存起来,最后再对关键字本身做索引排序。用户在检索某一关键字时,可以先对关键字的索引进行查找,再通过关键字与文档的对应关系找到所在文档。这类似于查字典一样,字典的拼音表和部首中的内容就是关键字与文档的对应关系。为了说明倒排索引的基本思想,以下面两条文档为例:

文档一:I love elasticsearch.
文档二:I love logstash.

针对这两份文档创建倒排索引的第一步,是先对文档提取关键字。对于英文来说比较简单按空格分隔即可,两份文档共提取I、love、elasticsearch和logstash四个关键字。接下来就是建立关键字与文档之间的对应关系,即标识关键字都被哪些文档包含。下面通过一种形象的形式来表示这种对应关系。
在这里插入图片描述
有了倒排索引,用户检索就可以在倒排索引中快速定位到包含关键字的文档。倒排索引与关系型数据库索引类似,会根据关键字做排序。但关系型数据库索引一般是对主键创建,然后索引指向数据内容;而倒排索引则正好相反,它是针对文档内容创建索引,然后索引指向主键(文档一、文档二),这就是这种索引被称为倒排索引的原因。
从以上分析可以看出,倒排索引实际上是对全文数据结构化的过程。对于存储在关系型数据库中的数据来说,他们依赖于人的预先分析将数据拆解为不同字段,所以在数据插入时就已经是结构化的;而在全文数据库中,文档在插入时还不是结构化的,需要应用程序根据规则自动提前关键字,并形成关键字与文档之间的结构化对应关系。由于文档在创建时需要提前关键字并创建索引,所以向全文数据库添加文档比关系型数据库要慢一些。
不难看出,全文检索中提取关键字时非常重要的一步。这些预先提取出来的关键字,在Elasticsearch及全文检索的相关文献中一般称为词项(Term)。文档的词项提取在Elasticsearch中称为文档分析(Analysis),是整个全文检索中较为核心的过程。这个过程必须要区分哪些是词项,哪些不是。对于英文来说,还被必须要知道apple和apples指的同一个东西,而run和running指的是同一个动作。对于中文来说就更麻烦了,因为中文词语不以空格分隔,所以面临的第一个难题是如何将词语分辨出来。

Elasticsearch索引

在Elasticsearch中,添加或更新文档时最重要的动作是将它们编入倒排索引,未被编入倒排索引的文档将不能被检索。也就是说,Elasticsearch中所有数据的检索都必须要通过倒排索引来检索,离开了倒排索引文档就相当于不存在。所以从检索角度来看,文档以倒排索引的形式表现其存在性。正是基于这个原因,Elasticsearch没有引入库的概念,而是将文档的容器直接称为索引(Index)。而这里的索引就是倒排索引,或者更准确的说是一组倒排索引。在概念上可以将索引理解为文档在物理上区分,同一索引中的文档具有相同的索引策略,或者说它们被编入到同一组索引中。从检索的角度来说,用户在检索文档时也要指定从哪一个索引中检索文档。所以从存储和检索两个角度看,以索引区分文档实在是再合适不过了。在Elasticsearch中存储文档最好预先创建索引,尽管这并不是必须的。用户预先创建索引可以指明文档存储时怎么分词,如何创建索引等重要信息,这些对于提示检索速度显然是有益的。
因为文档存储前的分析和索引过程比较好资源,所以为了提升性能,文档在添加到Elasticsearch中时并不会立即被编入索引。在默认情况下,Elasticsearch会没隔1s统一处理一次新加入的文档,可以通过index.refresh_interval参数修改。为了提升性能,在Elasticsearch 7中还添加了index.search.idle.after参数,它的默认值是30s。其大体含义是,如果索引在一段时间内没有收到检索数据的请求,那么它至少要等30s后才会刷新索引数据。所以,从这两个参数的作用看,elasticsearch实际上是准实时的(near realtime,NRT)。也就是说,新添加到索引中的文档,有可能在一段时间内不能被检索到。如果的确需要立即检索到文档,Elasticsearch也提供了强制刷新到索引的方式,包括使用_refresh接口和在操作文档时使用refresh参数。但这会对性能造成一定的影响。
那么未被编入索引的文档在什么地方呢?事实上,它们会被临时保存到缓冲器中,缓冲器的大小可以通过一些配置参数设置,包括indices.memory.index_buffer_size、indices.memory.min_index_buffer_size和indices.memory.max_index_buffer_size。默认情况下,这个缓冲区最小为48MB且没有上限。

Elasticsearch映射

如前文所述,索引是存储文档的容器,文档在存储前会做文档分析并编入倒排索引。而文档从全文数据到索引的转变由映射(Mapping)定义,这是另一个在Elasticsearch中非常重要的概念。映射介于文档与索引之间,所以一般是在创建索引时指定文档与索引的映射关系。映射的概念比较难理解,想要理解它就得先理解Elasticsearch中的文档概念。

文档

在Elasticsearch中,数据存储和检索的基本单元是文档。Elasticsearch的文档使用JSON格式,这种格式目前几乎已经成为互联网数据交换的标准格式。Elasticsearch对外开放的接口以REST为主,而REST本身也是以JSON为通用数据交换格式。在后续章节中会看到,无论是存储文档、检索文档还是设置索引,请求的基本格式都是JSON。所以从开发和应用的角度来看,JSON格式可以降低学习成本,而且与微服务架构也易于集成。熟悉JSON的读者应该知道,JSON有一些格式规范要求,比如属性名称、数据类型等。所以严格来说,Elasticsearch存储的文档是一种半结构化数据,可以预先定义好属性和数据类型。为了明确概念,本书后续章节称Elasticsearch中文档的JSON属性为字段(Field),即文档字段,以区别在其他领域中使用的JSON属性。
既然Elasticsearch支持全文检索,为什么还要预先定义文档字段和数据类型呢?这可以从以下几个方面理解。首先,全文数据在存储前需要做分析并提取词项,但在文档中并不是所有数据都需要这样做。比如文档创建时间、文档标题、作者等,这些数据本来就是结构化的,没有必要再分析。此外,一些结构化数据在检索时需要做精确匹配,如果做了文档分析并提取词项后,反而做不了精确匹配了。比如,对作者名称“tom smith”做文档分析后,会提取“tom”和“smith”两个词项编入索引,而“tom smith”则不会编入索引,这时通过“tom smith”检索文章就不能匹配到文档了。其次,预先定义好文档字段可以增加数据检索的维度,提升检索质量;而且预先定义好数据类型可以优化存储结构,比如数值类型的保存就没必要保存成字符串了。最后,在Elasticsearch中存储文档也不是一定要预先定义文档字段,Elasticsearch也支持动态映射文档字段。
所以在使用Elasticsearch时,如果清楚地知道文档存在一些结构化特征,预先定义好它们对存储和检索都有好处;而这种预先定义又不会像数据库表结构那样,限制未来可能出现的数据扩展,可以说是兼顾了效率与灵活。在Elasticsearch中,定义文档的字段和数据类型是通过在映射中定义类型来实现。

映射类型

映射类型(Mapping Type)是定义文档与索引映射关系的一种方式。在Elasticsearch版本6之前,一个索引中是可以定义多个映射类型。例如,创建一个shop索引存储网上商城数据,可以包含用户类型users和商品类型products。每个类型都可以有自己的字段,因此users类型可以有name、age、address等字段,而products类型则可以有name、price、description等字段。每新增一个用户,可以以JSON文档的形式存储在users类型下;而每新增一个商品,同样也可以以JSON文档的形式存储在products类型下,如示例2-2所示:
在这里插入图片描述
在上面的示例中,“PUT shop”是创建索引的REST请求,而请求中的mappings参数就是文档到索引的映射关系,它是索引创建接口的一个基本配置参数。mappings中的users和products就是映射类型的名称,而在映射类型的properties参数中,则实际指明了这些映射类型中预定义的字段及其数据类型。
讲到这里再回头看下本节开始时对他们的对比,就会发现这种与关系型数据库的类比并不正确。最主要的就是映射类型并不是文档的物理容器,而只是文档到索引转变的映射关系。事实上,映射类型这个概念的引入使得Elasticsearch的这些概念在整体上都变得混乱,尤其是在它的官方文献中还经常将映射类型简称为类型,这使得初学者更是一头雾水。不光是初学者觉得这些概念难理解,Elasticsearch官方也应该是感觉到这些概念有些混乱了,所以Elasticsearch官方已经开始弱化映射类型的概念。
事实上,Elasticsearch官方正计划逐步取消映射类型的概念,在6.0版本以后映射类型的概念还将延续,但在映射中只能有一个映射类型,而不允许在定义多个映射类型;而在7.0版本以后,映射类型的概念被彻底删除。所以类似上面示例的shop索引中创建多个映射类型的例子,可以将shop这一层的索引取消,直接建立users和products索引,通过索引对他们做逻辑上和物理上的隔离。在6.0–7.0版本的过渡期间,用户在创建索引时还是需要在索引下创建一个映射类型,映射类型名称可以任意定义,但一般可以起名为_doc。但在7.0以后的版本中则不需要再加映射类型,Elasticsearch会为索引创建唯一一种映射类型_doc。所以,在7.0以后的版本中,如果要创建示例2-2中的索引应该按如下方式执行:
在这里插入图片描述
需要说明的是,Elasticsearch官方之所以要删除映射类型的概念,不单纯是因为映射类型容易造成混乱,主要是因为映射类型只是文档在逻辑上的容器,在物理上并没有起到隔离文档的作用。在同一个索引中具有相同名称的字段实际上由相同的Lucence字段支持。以前面shop索引为例,users类型中的name字段与products类型中的name字段共享同一个字段,所以两个name自动必须具有相同的定义。这在一些情况下是合理的,比如两种映射类型存在类似父子继承关系;但在多数情况下,这种共享字段会引发歧义。所以,使用表结构类比映射类型是不合适的,因为表结构在物理上是隔离的。同一个数据库中的两个表结构如果拥有相同字段,他们相互之间不会受到任何影响。但在Elasticsearch中,这是不成立的。正是基于这样的原因,Elasticsearch在高版本中开始弱化映射类型这一概念,为了定义不同映射类型就是创建不同的索引。可以把索引之间类比成表就可以了,索引中的映射就是表中的结构。

文档字段

文档字段(Field)可以理解为文档的一个结构化特征。由于它在实现上是JSON的属性,所以有些文献中也将文档字段称为文档属性。由于Elasticsearch接口的请求参数和返回结果都是JSON格式的,所以为了避免因名称引起混淆,本书对JSON属性的叫法进行一些约定。本书后续章节将统一称文档中的JSON属性为字段,而称请求中的JSON属性为参数。由于接口返回结果中的JSON属性代表的是文档的字段或字段运算的结果,所以出现在返回结果中的JSON属性也统一称为字段。对于其他情况,均称JSON中的属性为属性。在后续章节学习到Logstash和Beats组件时也会面临这个问题,本书会在相应章节再给出新的约定。
由于文档的具体内容都以字段为单元保存,所以字段决定了文档将以什么样的方式存储和索引。索引文档和存储文档是两个不同的概念,索引文档是将文档编入倒排索引,而存储文档则是将文档在物理上保存起来。

字段索引

由于文档中的数据分散在各个字段中,所以索引文档肯定都是针对文档字段进行的。一份文档一般会有多个字段,所以倒排索引一般是多个相互关联的倒排索引。前面所说的索引文档应该是以字段为单位对文档做索引,而并非以整个文档内容做索引。为了叙述上的方便,本书后续章节将无区别的使用索引文档和索引文档字段。
在默认情况下,文档的所有字段都会创建倒排索引。这可以通过字段的index参数来设置,其默认值为true,即字段会被编入索引。
由此也可以看出,尽管在默认情况下所有的字段都会被索引,但是这些字段的原始值是不会被编入索引中的。这意味着用户可以通过某一字段的词项检索到文档,但并不能直接取到这个字段的原始值。因为字段的索引最多只包含上述四项内容,并不包含字段原始值。

字段存储

为什么字段原始值不会被编入索引呢?这显然还是出于对性能与效率的考量。还是以“Elasticsearch is a search engine”这段文本为例,文档分析后会提取出5个词项并编入索引。如果这5个词项都在索引中保留字段的原始值,那么这段文本就要被保留5次。而对于很多文档来说,它们的文本内容要比这大得多,如果都保留下来这对于存储空间的浪费将是十分惊人的。
那么是不是字段的原始值就完全丢失了呢?别担心,尽管单个字段的原始值不会被保存,但索引提供了一个叫_source的字段用于存储整个文档的原始值。_source字段有一个特性,那就是这个字段在默认情况下是不会被索引的,但是每个查询默认都会带着_source字段返回。如果确定不需要使用_source字段保存源文档,也可以在创建索引通过映射类型的_source参数将其关闭,如下图:
在这里插入图片描述
关闭_source字段后,上述功能也将无法使用,所以在考虑关闭_source字段时要权衡清楚。通常关闭_source字段的主要原因是出于节省存储空间,Elastic官方建议如果单纯只是考虑节省存储空间可以通过修改index.codec提高压缩效率,具体请参见第3章中有关索引配置的介绍。
_source字段保存的源文档信息是在索引文档时以JSON形式传递过来的最原始文档,这在查看文档时比较直观方便,但如果需要使用文档中某一字段值做进一步运算时就比较麻烦了。例如在检索出文档后再根据某一字段值进行排序,类似的情况还有聚集查询中的取字段极值、平均值等统计数据,这在第6章中有比较详细的介绍。针对这种情况,Elasticsearch还提供了另外一种机制保存字段值,这就是文档值(Doc Value)机制。文档值机制存储的信息与_source字段基本相同,但它的存储结构是面向列的,类似于传统关系型数据库中的表结构。换句话说,_source字段将源文档揉在一起保存,而文档值则将它们按字段分别保存在不同的列中;_source保存的是最原始的文档信息,而文档值则是经过一定分析处理的数据。所以文档值相当于把文档中的结构化数据以结构化的方式存储起来了,而对于非结构化的文本数据则不能使用文档值机制。所以在默认情况下,所有非text类型的字段都支持文档值机制,并且都是开启的。而对于text类型的字段,由于它本身就不是结构化数据,所以到目前为止还不支持文档值机制。字段的文档值机制可以通过字段的doc_values参数开关,例如在示例2-7中,就将users索引的age属性的文档值关闭了:
在这里插入图片描述
对于text类型的字段来说,Elasticsearch提供了另外一种称为fielddata的机制来处理相似场景的问题。fielddata机制与文档值机制虽然在效果上类似,但在实现上则完全不同。文档值机制的数据结构保存在硬盘中,而fielddata机制则是在内存中构建数据结构,所以使用fielddata机制有可能导致JVM内存溢出。不仅如此,fielddata机制保存的也不是字段原始值,而是通过遍历倒排索引建立文档与它所包含词项的对应关系。具体来说,Elasticsearch会在首次对字段进行聚集、排序等请求时,遍历所有倒排索引并在内存中构建起文档与词项之间的对应关系。在默认情况下,text字段的fielddata机制是关闭的,可以通过在映射字段时修改fielddata参数开启。例如在示例2-6中,address字段的fielddata就被开启了。在开启fielddata机制前要考虑清楚,因为这种机制显然非常消耗资源,而且使用text类型字段做聚集、排序也往往不是合理的需求。即便是真的有这样的需求,也可以通过字段多数据类型来开启文档值机制,而尽量不要使用fielddata机制。
除了使用_source字段、文档值和fielddata机制以外,在字段映射时还可以通过store参数将字段修改为true,以使索引单独保存这个字段。通常情况下,如果文档本身十分庞大,而一些字段又会经常单独使用,那么这样的字段就可以设置为单独存储。例如对于书名和书的内容来说,书的内容要比书名长得多,而书名在许多情况下又需要单独使用,如果每次需要取书名时都需要将书的内容也返回就有点太浪费了。在这种情况下就可以使用store参数,将书名设置为单独存储,然后就可以使用stored_fields单独检索这些字段了。

字段参数

除了前面介绍的type、doc_value、fielddata、store等参数,文档字段还有许多可以使用的配置参数。如下:
在这里插入图片描述
在这里插入图片描述
其中,copy_to参数可以将字段值复制到另外一个字段,这样就可以将相关字段值复制到同一个字段中,而在需要做跨字段检索时就可以使用这个字段了。

元字段

文档字段可以分为两类:一类是元字段(Meta-field);零一类是用户定义的业务字段。元字段不需要用户定义,在任一文档中都存在,例如在前面提及的文件ID字段_id就是一个元字段。在名称上他们有一个显著的特征,就是他们都以下划线“_”开头。在学习这些字段是,要从字段索引和字段存储两个方法理解它们。有些元字段只是为了存储,他们会出现在文档检索的结果中,但却不能通过这个字段本身做检索,比如_source字段。而有些字段只是为了索引,它会创建一个索引出来,用户可以在这个索引上检索文档,但这个字段却不会出现最终的检索结果中,比如_all字段。此外,也并不是索引元字段都是默认开启的,有些元字段是需要在索引中配置开启才可使用。
在这里插入图片描述

第一类,表示相关元字段

这类元字段主要用于标识当前文档,包括_id、_uid、_index、_type。_id和_uid都是文档的标识符,在版本6之前_id仅在映射类型内惟一,而_uid由_type和_id组成并在索引内惟一;但在6.0.0版之后,映射类型在索引内仅有一个,所以_uid已经被废止,而_id则在索引内惟一。_id字段就是第2.2.1节中介绍编入索引信息中的文档ID,它本身也会被索引,所以可以通过_id字段检索到文档。更准确的说,_id应该是在同一索引的同一分片内惟一。

第二类,源文档相关字段

_source字段就是第2.2.2节介绍字段存储时提到的存储源文档的元字段,源文档所有信息都会保存在这个字段中,但这个字段不会被索引。_size字段保存了源文档长度,但需要安装mapper_size插件,并在设置索引映射类型时通过将_size参数设置为true开启这个功能。

第三类,索引相关字段

这类元字段是关于如何创建索引的字段,它们一般只创建索引而不会存储,也不会出现在检索结果中。例如,_all字段是将文档所有字段的词项以空格分隔连接起来创建大索引,这样用户在检索时就不用指明根据哪一个字段检索,这在不知道检索内容位于哪一个字段时非常有用。但在6.0.0版中_all字段已经被废止,而建议使用字段参数copy_to。_field_names字段用于给所有有值的字段名称做索引,这可以用于检索某一字段是否存在。_ignored字段则用于给所有被忽略的字段创建索引,被忽略的字段一般是在字段格式错误而ignore_malformed参数又设置为true时发生。

第四类,路由

在默认情况下,文档会根据_id字段的值将文档路由到不同的分片,通过在添加文档时设置routing参数可以修改文档路由。而_routing字段就是当前文档路由的值,可以在文档检索时通过_routing字段检索文档。

字段限制

在索引中定义太多字段会导致映射爆炸,进而导致内存不足甚至系统崩溃。这个问题在使用动态映射时比较常见,动态映射就是预先不定义索引映射关系,而在添加文档时动态确定字段名称和类型。如果每次文档添加到索引时都包含新字段,这些字段将最终体现在索引的映射中。为了防范这种情况的发生,Elasticsearch引入了一些参数可以限制字段的数量。比如,index.mapping.total_fields.limit参数定义了索引中最大字段数,它限制了字段、对象以及字段别名最大值,默认值是1000;index.mapping.depth.limit参数则定义了嵌套对象的最大深度,默认值是20;index.mapping.nested_fields.limit参数定义了索引中嵌套字段的最大数量,默认值是50。这些限制出于安全角度出发,但在某些特定应用中可能会限制了需求,可以通过创建索引修改这些参数满足需求。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Elasticsearch是一个开源的分布式搜索和分析引擎,它使用倒排索引来实现高效的数据搜索和分析功能。通过使用Elasticsearch,用户可以快速而简便地在大规模数据集中进行全文搜索、聚合分析和实时数据抓取。 Elasticsearch实战是一本介绍如何使用Elasticsearch进行实际开发和应用的实用指南。它通过实际案例和示例代码,详细介绍了Elasticsearch的各种功能和实际应用场景。这本书以实战为导向,从数据建模、索引管理、搜索和分析技术到性能优化和故障排除等方面进行了全面而深入的解析。通过学习这本书,读者将掌握Elasticsearch的使用技巧并能够独立进行项目开发和维护。 另一方面,Elasticsearch原理解析是对Elasticsearch的底层原理进行深入剖析的一本书。它从分布式系统的角度出发,阐述了Elasticsearch的分片和复制机制、搜索和分析的实现原理以及缓存和路由等关键技术。此外,该书还介绍了Elasticsearch的容错机制、数据恢复策略和并发控制等重要概念。通过学习这本书,读者将更加深入地了解Elasticsearch的内部机制,从而能够更好地定制和优化应用程序。 总的来说,Elasticsearch实战和原理解析是帮助读者理解和应用Elasticsearch的重要参考书籍。前者提供了丰富的实例和实践经验,使读者能够快速上手并应用于实际项目中;而后者则深入探讨了Elasticsearch的内部原理和技术细节,使读者能够更深入地理解和运用Elasticsearch的各种功能和特性。无论是初学者还是有经验的开发人员,都可以从中获得实用的知识和技巧,并在工作中更好地应用Elasticsearch

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

融极

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值