【ElasticSearch从入门到放弃系列 九】Elasticsearch原理机制探索

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【ElasticSearch从入门到放弃系列 九】Elasticsearch原理机制探索

在之前的学习中一直只是从使用层面上去玩儿Lucene和ES,并没有深入的去探究索引的读写方式和机制。在工作中其实能遇到为什么读取ES1秒延迟现象之类的问题,但是都没有从核心机制方面去深究。正如上篇【ElasticSearch从入门到放弃系列 八】Elasticsearch集群深度探讨的讨论学习后,本篇对索引的读写机制等原理性的机制进行学习和探索,追求恍然大悟的感觉。

基础内容回顾

【ElasticSearch从入门到放弃系列 三】Lucene的基本概念和使用中我们了解了Lucene的基本使用,在【ElasticSearch从入门到放弃系列 四】ElasticSearch的基本概念和使用我们了解了ElasticSearch的基本使用,其实大同小异

级别 概念 对应lucene概念
索引 index 一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。实际上对应于**** 索引
类型 type 在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。比如说,我们假设你运营一个博客平台并且将你所有的数据存储到一个索引中。在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一个类型,当然,也可以为评论数据定义另一个类型。
字段Field 相当于是数据表的字段,对文档数据根据不同属性进行的分类标识 字段域
映射 mapping mapping是处理数据的方式和规则方面做一些限制,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置的,其它就是处理es里面数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。一般每个type都需要一个mapping信息 字段域的一些属性配置
文档 document 一个文档是一个可被索引的基础信息单元。比如,你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON(Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。在一个index/type里面,你可以存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type 文档

在之前的blog里都是通过Postman或者Java代码去操作索引信息,但是并不知道一条数据被发布到哪个分片上,以及更新的时候如何去从哪个分片读取数据,这些原理性的知识都是之前未解的盲区。它们内部是如何运行的?主分片和副本分片是如何同步的?创建索引的流程是什么样的?ES如何将索引数据分配到不同的分片上的?以及这些索引数据是如何存储的?为什么说ES是近实时搜索引擎而文档的 CRUD (创建-读取-更新-删除) 操作是实时的?以及Elasticsearch 是怎样保证更新被持久化在断电时也不丢失数据?还有为什么删除文档不会立刻释放空间?本篇blog就是对这部分的原理进行学习和扫盲。

索引CRSUD原理

以下内容来自于 https://www.cnblogs.com/jajian/p/11223992.html

下图描述了3个节点的集群,共拥有12个分片,其中有4个主分片(S0、S1、S2、S3)和8个副本分片(R0、R1、R2、R3),每个主分片对应两个副本分片,节点1是主节点(Master节点)负责整个集群的状态

路由规则

写索引是只能写在主分片上,然后同步到副本分片。这里有四个主分片,一条数据ES是根据什么规则写到特定分片上的呢?这个过程是根据下面这个公式决定的:

shard = hash(routing) % number_of_primary_shards
  • routing 是一个可变值,默认是文档的 _id ,也可以设置成一个自定义的值【例如租户ID】。 routing 通过 hash 函数生成一个数字,然后这个数字再除以 number_of_primary_shards (主分片的数量)后得到余数 。这个在 0 到 number_of_primary_shards-1 之间的余数,就是我们所寻求的文档所在分片的位置
  • 如果是自定义的_routing,在查询时,一定要指定_routing进行查询,否则是查询不到文档的。这并不是局限性,恰恰相反,指定_routing的查询,性能上会好很多,因为指定_routing意味着直接去存储数据的shard上搜索,而不会搜索所有shard
  • 公式解释了为什么要在创建索引的时候就确定好主分片的数量并且永远不会改变这个数量:因为如果数量变化了,那么所有之前路由的值都会无效,文档也再也找不到了

以上就是整个路由规则

写操作流程

每个节点都有处理读写请求的能力。在一个写请求被发送到某个节点后,该节点即为上篇blog提到的协调节点,协调节点会根据路由公式计算出需要写到哪个分片上,再将请求转发到该分片的主分片节点上。假如此时数据通过路由计算公式取余后得到的值是 shard = hash(routing) % 4 = 0,则具体流程如下:

  1. 客户端向ES1节点(协调节点)发送写请求,通过路由计算公式得到值为0,则当前数据应被写到主分片S0上。
  2. ES1节点将请求转发到S0主分片所在的节点ES3,ES3接受请求并写入到磁盘。
  3. 并发将数据复制到两个副本分片R0上,其中通过乐观并发控制数据的冲突。
  4. 一旦所有的副本分片都报告成功,则节点ES3将向协调节点报告成功,协调节点向客户端报告成功。

以上就是整个写索引的流程。

读操作流程

同写操作一样,GET某一条数据的流程也会计算路由,当写入了某个document后,这个document会自动给你分配一个全局唯一的id,doc id,同时也是根据doc id进行hash路由到对应的primary shard上面去。例如我们就获取上边写入的文档:

  1. 客户端发送请求到ES1节点,该节点成为协调节点
  2. 协调节点对document进行路由,路由规则同上,将请求转发到路由主分片ES3的节点,此时会使用round-robin【这个轮询算法在我的Kafka相关blog介绍过】随机轮询算法,在ES3_S0以及其所有replica【ES1_R0、ES2_R0】中随机选择一个,让读请求负载均衡
  3. 接收请求的节点【ES3_S0、ES1_R0、ES2_R0中随机的一个】返回document给coordinate node【ES1】
  4. 协调节点向客户端报告成功,返回document给客户端

以上就是通过一个具体的文档Id读数据的流程,当然其实ES我们更多用到的是它的搜索。

搜索操作流程

其实我们在ES的大多数使用场景都是检索,那么检索的原理是什么呢?这里举个例子,例如我有三条数据,分别叫:ES1_S3tml超级帅、ES1_S2tml很丑、ES3_S0tml其实挺帅的。第一条存储在节点ES1的S3分片上、第二条数据存储在节点ES1的S2分片上,第三条数据存储在节点ES3的S0分片上。我们搜索【帅】这个关键字:

  1. 客户端发送请求到ES1节点,该节点成为协调节点
  2. 协调节点将请求转发到所有分片上【主分片或副本分片,采取随机轮询的方式】,假设这里都是主分片处理请求,那么请求被转发到了ES1和ES3两个节点
  3. query phase:每个分片将自己的搜索结果(其实就是一些doc id),返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果,这里【帅】命中了两条数据:ES1的S3分片上【ES1_S3tml超级帅】,ES3的S0分片上【ES3_S0tml其实挺帅的】,这两条数据的doc id被返回给协调节点ES1
  4. fetch phase:协调节点ES1根据doc id去各个节点上拉取实际的document数据,最终返回给客户端

这里需要注意,第一次只检索数据id返回给协调节点,并不是真正的取数据,整合之后再取数据。

删除操作流程

删除的话其实是假删除,先进行标记删除,然后在段合并的时候再进行彻底删除,删除时其实是给定了文档id的,这样按照我们的流程,要删除文档【ES1_S3tml超级帅】

  1. 客户端发送请求到ES1节点,该节点成为协调节点
  2. 协调节点对document id进行路由,路由规则同上,将请求转发到路由主分片ES1的节点,此时不直接删除文档,而是把文档id标记到.del的删除文件
  3. 将删除请求路由到所有副本节点执行同样的操作
  4. 协调节点向客户端报告成功

下面会讲到,只有在进行段合并的时候才会真正的删除文件,其它时候只是检索到后将结果集过滤了一遍.del文件。

更新操作流程

更新的话其实是一次删除加一次写入,已标记删除的V1版本,在检索时可能会被检索到,然后在结果集里被过滤掉,所以.del文件可能还需要记录文档的版本。

  1. 客户端发送请求到ES1节点,该节点成为协调节点
  2. 协调节点对document id进行路由,路由规则同上,将请求转发到路由主分片ES1的节点,此时不直接删除文档,而是把文档id标记到.del的删除文件,然后索引一个文档的新版本
  3. 将更新请求路由到所有副本节点执行同样的操作
  4. 协调节点向客户端报告成功

那么在具体的更新流程中,版本合并如何处理呢?在下边的更新版本合并策略中介绍到。

存储原理

上面介绍了在ES内部索引的CRSUD处理流程,这个流程是在ES的内存中执行的,数据被分配到特定的分片和副本上之后,最终是存储到磁盘上的,这样在断电的时候就不会丢失数据。具体的存储路径可在配置文件…/config/elasticsearch.yml中进行设置,默认存储在安装目录的data文件夹下。建议不要使用默认值,因为若ES进行了升级,则有可能导致数据全部丢失

path.data: /path/to/data  //索引数据
path.logs: /path/to/logs  //日志记录

分段存储

索引文档以段的形式存储在磁盘上,索引文件被拆分为多个子文件,则每个子文件叫作段【其实和Kafka将Partion切分为段类似】, 每一个段本身都是一个倒排索引,并且段具有不变性,一旦索引的数据被写入硬盘,就不可再修改。在底层采用了分段的存储模式,使它在读写时几乎完全避免了锁的出现,大大提升了读写性能。

段在不同存储模式下拥有不同的读写能力,可以避免使用锁的开销,提升读写性能

  • 当索引在内存中时,就只有写的权限,而不具备读数据的权限,意味着不能被检索。只有当被刷到文件缓存系统里成为段之后才能被检索【只能读不能写】。
  • 段被写入到磁盘后会生成一个提交点,提交点是一个用来记录所有提交后段信息的文件。一个段一旦拥有了提交点,就说明这个段只有读的权限,失去了写的权限

为什么要有段呢?段的概念提出主要是因为:在早期全文检索中为整个文档集合建立了一个很大的倒排索引,并将其写入磁盘中。如果索引有更新,就需要重新全量创建一个索引来替换原来的索引。这种方式在数据量很大时效率很低,并且由于创建一次索引的成本很高,所以对数据的更新不能过于频繁,也就不能保证时效性,索引文件分段存储并且不可修改,那么新增、更新和删除如何处理呢?

  • 新增,新增很好处理,由于数据是新的,所以只需要对当前文档新增一个段就可以了。
  • 删除,由于不可修改,所以对于删除操作,不会把文档从旧的段中移除而是通过新增一个.del文件,文件中会列出这些被删除文档的段信息。这个被标记删除的文档仍然可以被查询匹配到, 但它会在最终结果被返回前从结果集中移除
  • 更新,不能修改旧的段来进行反映文档的更新,其实更新相当于是删除和新增这两个动作组成。会将旧的文档在.del文件中标记删除,然后文档的新版本被索引到一个新的段中。可能两个版本的文档都会被一个查询匹配到,但被删除的那个旧版本文档在结果集返回前就会被移除

段被设定为不可修改具有一定的优势也有一定的缺点。

段不变性的优势

段不变性的优势主要体现在:

  • 不需要锁。如果不更新索引,就不需要担心多进程同时修改数据的问题,也就是单纯读写时不会有锁的问题
  • 一旦索引被读入内核的文件系统缓存,便会留在哪里,由于其不变性。只要文件系统缓存中还有足够的空间,那么大部分读请求会直接请求文件系统缓存【内存】,而不会命中磁盘。这提供了很大的性能提升。
  • 其它缓存(像filter缓存),在索引的生命周期内始终有效。它们不需要在每次数据改变时被重建,因为数据不会变化。
  • 写入单个大的倒排索引允许数据被压缩,减少磁盘 I/O 和 需要被缓存到内存的索引的使用量。

总结而言就是不需要考虑读写的并发,以及高性能的读数据和压缩数据能力。

段不变性的缺点

段的不变性的缺点如下:

  • 新增时:每次新增数据时都需要新增一个段来存储数据。当段的数量太多时,对服务器的资源例如文件句柄的消耗会非常大。
  • 删除时:当对旧数据进行删除时,旧数据不会马上被删除,而是在.del文件中被标记为删除。而旧数据只能等到段更新时才能被移除,这样会造成大量的空间浪费。
  • 更新时:若有一条数据频繁的更新,每次更新都是新增新的标记旧的,则会有大量的空间浪费。
  • 查询时:在查询的结果中包含所有的结果集,需要排除被标记删除的旧数据,这增加了查询的负担

我们说没有任何一种结构或算法是万能的,空间和时间一定有其平衡性,段其实就是牺牲了空间成就了时间。

索引操作策略

在介绍了索引的CRSUD以及ES的存储结构后我们来看看在CRSUD过程中,结合存储,有什么策略让索引的使用更高效呢?

延迟写策略

如果是直接写入到磁盘上,磁盘的I/O消耗上会严重影响性能,那么当写数据量大的时候会造成ES停顿卡死,查询也无法做到快速响应。如果真是这样ES也就不会称之为近实时全文搜索引擎了,为了提升写的性能,ES并没有每新增一条数据就增加一个段到磁盘上,而是采用延迟写的策略:

  • 写入内存:每当有新增的数据时,就将其先写入到内存中,在内存和磁盘之间是文件系统缓存。这里的内存使用的是ES的JVM内存,新的数据会继续的被写入内存,但内存中的数据并不是以段的形式存储的,因此不能提供检索功能
  • 写入文件系统缓存:当达到默认的时间(1秒钟)或者内存的数据达到一定量时,会触发一次刷新(Refresh),将内存中的数据生成到一个新的段上并缓存到文件缓存系统 上,文件缓存系统使用的是操作系统的内存,由内存刷新到文件缓存系统的时候会生成了新的段,并将段打开以供搜索使用,而不需要等到被刷新到磁盘
  • 写入磁盘:稍后再被刷新到磁盘中并生成提交点。

在 Elasticsearch 中,写入和打开一个新段的轻量的过程叫做 refresh (即内存刷新到文件缓存系统)。 默认情况下每个分片会每秒自动刷新一次。这就是为什么我们说 Elasticsearch 是近实时搜索,因为文档的变化并不是立即对搜索可见,但会在一秒之内变为可见。我们也可以手动触发 refresh,POST /_refresh 刷新所有索引,POST /nba/_refresh刷新指定的索引。

虽然通过延时写的策略可以减少数据往磁盘上写的次数提升了整体的写入能力,但是我们知道文件缓存系统也是内存空间,属于操作系统的内存,只要是内存都存在断电或异常情况下丢失数据的危险。为了避免丢失数据,Elasticsearch添加了事务日志(Translog),事务日志记录了所有还没有持久化到磁盘的数据。添加了事务日志后整个写索引的流程如下图所示:

添加了事务日志后的优化流程如下:

  • 写入内存及事务日志:一个新文档被索引之后,先被写入到内存中,但是为了防止数据的丢失,会追加一份数据到事务日志中。不断有新的文档被写入到内存,同时也都会记录到事务日志【存储在os cache,默认每隔5秒刷一次到磁盘中】中。这时新数据还不能被检索和查询。需要注意的是:当Elasticsearch作为NoSQL数据库时,查询方式是GetById,这种查询可以直接从TransLog中查询,这时候就成了RT(Real Time)实时系统
  • 写入文件系统缓存(os cache):当达到默认的刷新时间或内存中的数据达到一定量后,会触发一次 refresh,将内存中的数据以一个新段形式刷新到文件缓存系统中并清空内存。这时虽然新段未被提交到磁盘,但是可以提供文档的检索功能且不能被修改
  • 写入磁盘并删除事务日志:随着新文档索引不断被写入,当日志数据大小超过512M或者时间超过30分钟时,会触发一次 flush。内存中的数据被写入到一个新段同时被写入到文件缓存系统,文件系统缓存中数据通过 fsync 刷新到磁盘中,生成提交点,日志文件被删除,创建一个空的新日志。

通过这种方式当断电或需要重启时,ES不仅要根据提交点去加载已经持久化过的段,还需要工具Translog里的记录,把未持久化的数据重新持久化到磁盘上,避免了数据丢失的可能。到这里,其实ES1秒延迟的问题有两个不成熟的解决方案

  • 可以通过es的restful api或者java api,在写入内存后,手动执行一次refresh操作,就是手动将buffer中的数据刷入os cache中,让数据立马就可以被搜索到
  • 查询方式是GetById时,直接从TransLog中查询

当然这肯定会牺牲性能,所以并不是完备的解决方案,但其实是解决问题的入口。

更新版本合并策略

上文我们提到了索引的更新流程,那么它的文档合并流程是怎么样的呢?

  1. 收到Update请求后,从Segment或者TransLog中读取同id的完整Doc,记录版本号为V1
  2. 将版本V1的全量Doc和请求中的部分字段Doc合并为一个完整的Doc——同时更新内存中的VersionMap。获取到完整Doc后,Update请求就变成了Index请求
  3. 加锁
  4. 再次从versionMap中读取该id的最大版本号V2,如果versionMap中没有,则从Segment或者TransLog中读取,这里基本都会从versionMap中获取到。
  5. 检查版本是否冲突(V2==V2),如果冲突,则回退到开始的“Update doc”阶段,重新执行。如果不冲突,则执行最新的Add请求。
  6. 在Index Doc阶段,首先将Version + 1得到V3,再将Doc加入到Lucene中去,Lucene中会先删同id下的已存在doc id,然后再增加新Doc。写入Lucene成功后,将当前V3更新到versionMap中。
  7. 释放锁,部分更新的流程就结束了

所以其实更新的时候还是需要锁的。

段合并策略

由于自动刷新流程每秒会创建一个新的段 ,这样会导致短时间内的段数量暴增。而段数目太多会带来较大的麻烦。 每一个段都会消耗文件句柄、内存和cpu运行周期。更重要的是,每个搜索请求都必须轮流检查每个段然后合并查询结果,所以段越多,搜索也就越慢。

Elasticsearch通过在后台定期进行段合并来解决这个问题。小的段被合并到大的段,然后这些大的段再被合并到更大的段

  • 段合并的时候会将那些旧的已删除文档从文件系统中清除。被删除的文档不会被拷贝到新的大段中
  • 合并的过程中不会中断索引和搜索

这可以解决段不可变带来的空间占用问题

  1. 段合并在进行索引和搜索时会自动进行,合并进程选择一小部分大小相似的段,并且在后台将它们合并到更大的段中
  2. 待合并的段既可以是未提交的也可以是已提交【文件操作系统缓存里的或磁盘里的】的。合并结束后老的段会被删除,新的段被 flush 到磁盘,同时写入一个包含新段(已排除旧的被合并的段)的新提交点
  3. 新的段被打开可以用来搜索

段合并的计算量庞大, 而且还要吃掉大量磁盘 I/O,段合并会拖累写入速率,如果任其发展会影响搜索性能。Elasticsearch在默认情况下会对合并流程进行资源限制,所以搜索仍然有足够的资源很好地执行

以上:关于索引的CRSUD以及存储和索引策略,总结汇聚为下图,来源于

https://blog.csdn.net/yinni11/article/details/92831436

性能优化

性能优化分别从存储设备、索引策略、调参和JVM调优四个方面讨论,以下内容均转自

https://www.cnblogs.com/jajian/p/11223992.html

存储设备

磁盘在现代服务器上通常都是瓶颈。Elasticsearch 重度使用磁盘,你的磁盘能处理的吞吐量越大,你的节点就越稳定。这里有一些优化磁盘 I/O 的技巧:

  • 使用 SSD。就像其他地方提过的, 他们比机械磁盘优秀多了。
  • 使用 RAID 。条带化 RAID 会提高磁盘 I/O,代价显然就是当一块硬盘故障时整个就故障了。不要使用镜像或者奇偶校验 RAID 因为副本已经提供了这个功能。
  • 使用多块硬盘,并允许 Elasticsearch 通过多个 path.data 目录配置把数据条带化分配到它们上面。
  • 不要使用远程挂载的存储,比如 NFS 或者 SMB/CIFS。这个引入的延迟对性能来说完全是背道而驰的。

如果你用的是 EC2,当心 EBS。即便是基于 SSD 的 EBS,通常也比本地实例的存储要慢。

索引策略

Elasticsearch为了能快速找到某个term,先将所有的term排个序,然后根据二分法查找term,时间复杂度为logN,就像通过字典查找一样,这就是Term Dictionary。现在再看起来,似乎和传统数据库通过B-Tree的方式类似。

但是如果term太多,term dictionary也会很大,放内存不现实,于是有了Term Index,就像字典里的索引页一样,A开头的有哪些term,分别在哪页,可以理解term index是一颗树。这棵树不会包含所有的term,它包含的是term的一些前缀。通过term index可以快速地定位到term dictionary的某个offset,然后从这个位置再往后顺序查找。

在内存中用FST方式压缩term index,FST以字节的方式存储所有的term,这种压缩方式可以有效的缩减存储空间,使得term index足以放进内存,但这种方式也会导致查找时需要更多的CPU资源。

参数配置

参数调优的实用性可能更强一些:

  • 给每个文档指定有序的具有压缩良好的序列模式ID,避免随机的UUID-4 这样的 ID,这样的ID压缩比很低,会明显拖慢 Lucene。
  • 对于那些不需要聚合和排序的索引字段禁用Doc values。Doc Values是有序的基于document => field value的映射列表;
  • 不需要做模糊检索的字段使用 keyword类型代替 text 类型,这样可以避免在建立索引前对这些文本进行分词。
  • 如果你的搜索结果不需要近实时的准确度,考虑把每个索引的 index.refresh_interval 改到 30s 。如果你是在做大批量导入,导入期间你可以通过设置这个值为 -1 关掉刷新,还可以通过设置 index.number_of_replicas: 0关闭副本。别忘记在完工的时候重新开启它。
  • 避免深度分页查询建议使用Scroll进行分页查询。普通分页查询时,会创建一个from + size的空优先队列,每个分片会返回from + size 条数据,默认只包含文档id和得分score给协调节点,如果有n个分片,则协调节点再对(from + size)× n 条数据进行二次排序,然后选择需要被取回的文档。当from很大时,排序过程会变得很沉重占用CPU资源严重。
  • 减少映射字段,只提供需要检索,聚合或排序的字段。其他字段可存在其他存储设备上,例如CAS,在ES中得到结果后再去CAS查询这些字段。
  • 创建索引和查询时指定路由routing值,这样可以精确到具体的分片查询,提升查询效率。路由的选择需要注意数据的分布均衡。

目前我司使用CAS存储数据,使用租户id指定路由,使用Scroll进行分页查询

JVM调优

JVM调优指的是对ES的内存进行调优,因为毕竟是基于Java实现的:

  • 确保堆内存最小值( Xms )与最大值( Xmx )的大小是相同的,防止程序在运行时改变堆内存大小。
    Elasticsearch 默认安装后设置的堆内存是 1 GB。可通过…/config/jvm.option文件进行配置,但是最好不要超过物理内存的50%和超过32GB。
  • GC 默认采用CMS的方式,并发但是有STW的问题,可以考虑使用G1收集器。
  • ES非常依赖文件系统缓存(OS Cache),快速搜索。一般来说,应该至少确保物理上有一半的可用内存分配到文件系统缓存。

以上就是需要注意的参数设置

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
1月前
|
存储 Java API
Elasticsearch 7.8.0从入门到精通
这篇文章详细介绍了Elasticsearch 7.8.0的安装、核心概念(如正排索引和倒排索引)、RESTful风格、各种索引和文档操作、条件查询、聚合查询以及在Spring Boot中整合Elasticsearch的步骤和示例。
117 1
Elasticsearch 7.8.0从入门到精通
|
2月前
|
数据可视化 Java Windows
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
本文介绍了如何在Windows环境下安装Elasticsearch(ES)、Elasticsearch Head可视化插件和Kibana,以及如何配置ES的跨域问题,确保Kibana能够连接到ES集群,并提供了安装过程中可能遇到的问题及其解决方案。
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
|
2月前
|
存储 关系型数据库 MySQL
浅谈Elasticsearch的入门与实践
本文主要围绕ES核心特性:分布式存储特性和分析检索能力,介绍了概念、原理与实践案例,希望让读者快速理解ES的核心特性与应用场景。
|
3月前
|
JSON 搜索推荐 数据挖掘
ElasticSearch的简单介绍与使用【入门篇】
这篇文章是Elasticsearch的入门介绍,涵盖了Elasticsearch的基本概念、特点、安装方法以及如何进行基本的数据操作,包括索引文档、查询、更新、删除和使用bulk API进行批量操作。
ElasticSearch的简单介绍与使用【入门篇】
|
2月前
|
JSON 监控 Java
Elasticsearch 入门:搭建高性能搜索集群
【9月更文第2天】Elasticsearch 是一个分布式的、RESTful 风格的搜索和分析引擎,基于 Apache Lucene 构建。它能够处理大量的数据,提供快速的搜索响应。本教程将指导你如何从零开始搭建一个基本的 Elasticsearch 集群,并演示如何进行简单的索引和查询操作。
208 3
|
3月前
|
JSON 测试技术 API
黑马商城 Elasticsearch从入门到部署 RestClient操作文档
这篇文章详细介绍了如何使用Java的RestHighLevelClient客户端与Elasticsearch进行文档操作,包括新增、查询、删除、修改文档以及批量导入文档的方法,并提供了相应的代码示例和操作步骤。
|
3月前
|
JSON 自然语言处理 Java
Elasticsearch从入门到部署 文档操作 RestAPI
这篇文章详细介绍了Elasticsearch中文档的增删改查操作,并通过Java的RestHighLevelClient客户端演示了如何通过REST API与Elasticsearch进行交云,包括初始化客户端、索引库的创建、删除和存在性判断等操作。
|
3月前
|
JSON 自然语言处理 数据库
Elasticsearch从入门到项目部署 安装 分词器 索引库操作
这篇文章详细介绍了Elasticsearch的基本概念、倒排索引原理、安装部署、IK分词器的使用,以及如何在Elasticsearch中进行索引库的CRUD操作,旨在帮助读者从入门到项目部署全面掌握Elasticsearch的使用。
|
4月前
|
存储 数据采集 数据处理
数据处理神器Elasticsearch_Pipeline:原理、配置与实战指南
数据处理神器Elasticsearch_Pipeline:原理、配置与实战指南
175 12
|
5月前
|
存储 缓存 负载均衡
elasticsearch写入流程和请求检索流程原理全方位解析
elasticsearch写入流程和请求检索流程原理全方位解析