八.全文检索ElasticSearch经典入门-深入理解ElasticSearch核心原理

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 八.全文检索ElasticSearch经典入门-深入理解ElasticSearch核心原理

前言

前面我们讲了ElasticSearch从认识到安装,到基本CRUD和SpringBoot整合ES实战,相信你学完之后就可以把ES融入到企业级项目开发了。本篇文章我们将深入了解一下ElasticSearch原理性的东西,我会以面试题总结的方式来展开。

常见面试题

为什么要选择全文搜索引擎,而不直接用like

可能你会觉得问这个问题的面试官有点傻,但是真有人这么问,为什么要使用全文检索引擎而不直接使用Mysql的like进行关键字检索。不一样能达到效果吗?

实际上当你的数据量不是特别庞大的时候,使用like进行模糊查询是完全没有问题的,您可以在你自己的电脑上做一个测试,只要你CPU,内存不是很差,几十万的数据使用 like进行模糊查询其实还是蛮快的,但是数据量再大一点就不好说了,数据库肯定遭不住。所以我们在做技术选型的时候需要进行评估,你的业务数据会不会增长特别快,比如:2年内预估会上百万或是千万或是更大,如果是这种情况可以直接上搜索引擎。很多企业前期还是不会投入太多技术成本,而是等到后期数据量上来再做技术转型和优化。

为什么用ES做全文检索比数据库使用 like 快

我们都知道使用 like的话会进行全文扫描,数据库会带着搜索的关键字去长文本中进行逐一匹配,当你数据量达到一定程度,那么这个扫描是非常非常耗时的。这个时间消耗往往是我们无法承担的,所以要思考优化,ElasticSearch(ES)全文检索引擎是一个不错的选择。为什么ES可以做到很快的检索呢?

这个要提到我们之前有介绍过的《ES倒排索引原理》,在ES中通过分词器把我们的数据源(文本)分词后,再进行一系列的处理形成一个有序的倒排索引文档。有序的数据结构就可以使用算法比如二分查找进行快速搜索。所以ES的搜索是对倒排索引的快速查找,而不是对全文本的逐一扫描,当然比like快。

创建索引的过程
在这里插入图片描述
搜索索引的过程
在这里插入图片描述

ES的数据分片机制你了解吗

ES本身是分布式架构,一个ES集群由多个Node节点组成,在ES中的一个index索引由多个shard分片组成,分布在多台Node服务器上存储,数据分片的目的一是为了方便横向扩展,二是可以让搜索工作分布在多台及其上去执行,有效提升整体吞吐量。

而为了防止shard宕机达到高可用的目的,每个Shard又可以有多个Replica 副本。就有了primary shard和replica shard主从的概念。

比如一个ES集群中有三个Node,索引被设置为3个主shard,1个备shard,如下:
在这里插入图片描述
这里的P代表主分片,R代表背分片。一对主备分片是不允许分配在一台Node机器上的。这里的备分片既可以做故障转移(主down机了,备自动提升为主),也可以分担读的压力,备分片的数据是从主分片复制而来的。

在ES中默认是5主1备,可以在创建索引的时候设置主备分片数量,但是主分片数量一旦设置好就不可更改,备分片的数量可以动态修改。

另外,当我们增加或者减少Node机器时,分片也会自动的在Node中进行负载均衡(重新分配)

了解ES的节点类型吗

默认情况下,elasticsearch集群中每个节点都有成为主节点的资格,也都存储数据,还可以提供查询服务。在生产环境下,如果不修改elasticsearch节点的角色信息,在高数据量,高并发的场景下集群容易出现脑裂等问题。这些功能是由两个属性控制的。node.master 和 node.data 默认情况下这两个属性的值都是true。

主节点master

node.master=true,代表该节点有成为主资格,主节点的主要职责是和集群操作相关的内容,如创建或删除索引,跟踪哪些节点是群集的一部分,并决定哪些分片分配给相关的节点。一般会把主节点和数据节点分开,node.master=true , node.data=false

数据节点data

node.data=true,数据节点主要是存储索引数据的节点,主要对文档进行增删改查操作,聚合操作等,数据节点对CPU,IO,内存要求较高,优化节点的时候需要做状态监控,资源不够时要做节点扩充。配置:mode.master=false,mode.data=true

负载均衡节点client

当主节点和数据节点配置都设置为false的时候,该节点只能处理路由请求,处理搜索,分发索引操作等,从本质上来说该客户节点表现为智能负载平衡器。配置:mode.master=false,mode.data=false

最佳实践

在一个生产集群中我们可以对这些节点的职责进行划分,建议集群中设置3台以上的节点作为master节点,这些节点只负责成为主节点,维护整个集群的状态。再根据数据量设置一批data节点,这些节点只负责存储数据,后期提供建立索引和查询索引的服务,这样的话如果用户请求比较频繁,这些节点的压力也会比较大,所以在集群中建议再设置一批client节点(node.master: false node.data: false),这些节点只负责处理用户请求,实现请求转发,负载均衡等功能。

描述一下ES添加文档的过程

这个问题是有些深度了,如果你不了解ES的分片机制你根本就答不对。

  1. 首先,客户端的请求会到达一个协调节点coordinating node。
  2. 协调节点根据算法选择一个primary shard: 算法 hash(document_id) % (num_of_primary_shards)
  3. 然后把数据发送给对应的primary shard, 所在节点保存完数据后,将数据同步到replica node备节点。
  4. 协调节点coordinating node 发现 primary node 和所有 replica node 都搞定之后返回结果给客户端

数据节点存储数据详细流程

当分片所在的节点接收到来自协调节点的请求后,会将请求写入到Memory Buffer,然后定时(默认是每隔1秒,所以ES是近实时,写到读有1s延迟)写入到Filesystem Cache,这个从Momery Buffer到Filesystem Cache的过程就叫做refresh

当然在某些情况下,存在Momery Buffer和Filesystem Cache的数据可能会丢失,ES是通过translog的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到translog中,当Filesystem cache中的数据写入到磁盘中时,才会清除掉,这个过程叫做flush;

在flush过程中,内存中的缓冲将被清除,内容被写入一个新段,段的fsync将创建一个新的提交点,并将内容刷新到磁盘,旧的translog将被删除并开始一个新的translog。flush触发的时机是定时触发(默认30分钟)或者translog变得太大(默认为512M)时;

详细描述一下Elasticsearch获取文档的过程

  1. 客户端请求一个协调节点coordinating node
  2. coordinate node 根据算法hash(document_id) % (num_of_primary_shards),将请求转发到对应的 node,此时会使用 round-robin随机轮询算法,在 primary shard 以及其所有 replica 中随机选择一个,让读请求负载均衡
  3. 接收到请求的 node 返回 document 给调节点 coordinate node。
  4. coordinate node 返回 document 给客户端。

    搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch;

详细描述一下Elasticsearch搜索过程

  1. 在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)。
  2. 每个分片在本地执行搜索并构建一个匹配文档的大小为 from + size 的优先队列。PS:在搜索的时候是会查询Filesystem Cache的,但是有部分数据还在Memory Buffer,所以搜索是近实时的。
  3. 每个分片返回各自优先队列中所有文档的 ID 和排序值给协调节点,协调节点它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
  4. 接下来就是 取回阶段,协调节点辨别出哪些文档需要被取回并向相关的分片提交多个 GET 请求。每个分片加载并 丰富 文档,如果有需要的话,接着返回文档给协调节点。一旦所有的文档都被取回了,协调节点返回结果给客户端。

详细描述一下Elasticsearch更新和删除文档的过程

删除和更新也都是写操作,但是Elasticsearch中的文档是不可变的,因此不能被删除或者改动以展示其变更; 磁盘上的每个段都有一个相应的.del文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在.del文件中被标记为删除的文档将不会被写入新段。

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

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
存储 搜索推荐 数据挖掘
ElasticSearch架构介绍及原理解析
ElasticSearch架构介绍及原理解析
114 0
|
4月前
|
安全 Linux 开发工具
Elasticsearch 搜索入门技术之一
Elasticsearch 搜索入门技术之一
227 1
|
4月前
|
自然语言处理 API 索引
Elasticsearch Analyzer原理分析并实现中文分词
Elasticsearch Analyzer原理分析并实现中文分词
74 0
|
5月前
|
JSON 自然语言处理 数据库
数据库-ElasticSearch入门(索引、文档、查询)
数据库-ElasticSearch入门(索引、文档、查询)
295 0
|
7月前
|
存储 关系型数据库 数据库
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
|
13天前
|
运维 监控 Java
探索Elasticsearch在Java环境下的全文检索应用实践
【4月更文挑战第17天】本文介绍了在Java环境下使用Elasticsearch实现全文检索的步骤。首先,简述了Elasticsearch的功能和安装配置。接着,通过Maven添加`elasticsearch-rest-high-level-client`依赖,创建`RestHighLevelClient`实例连接Elasticsearch。内容包括:创建/删除索引,插入/查询文档。还探讨了高级全文检索功能、性能优化和故障排查技巧。通过Elasticsearch,开发者能高效处理非结构化数据,提升应用程序价值。
|
17天前
|
监控 搜索推荐 安全
面经:Elasticsearch全文搜索引擎原理与实战
【4月更文挑战第10天】本文是关于Elasticsearch面试准备的博客,重点讨论了四个核心主题:Elasticsearch的分布式架构和数据模型、CRUD操作与查询DSL、集群管理与性能优化,以及安全与插件扩展。文中通过代码示例介绍了如何进行文档操作、查询以及集群管理,并强调理解Elasticsearch的底层原理和优化策略对面试和实际工作的重要性。
31 6
|
3月前
|
存储 关系型数据库 MySQL
ElasticSearch 入门
【2月更文挑战第7天】ElasticSearch 入门 简介 ElasticSearch 的基本概念 ElasticSearch 的查询流程 ElasticSearch 的更新流程
37 2
|
3月前
|
存储 自然语言处理 搜索推荐
ElasticSearch入门篇
ElasticSearch入门篇
|
7月前
|
存储 JSON 定位技术
Elasticsearch入门
Elasticsearch入门

热门文章

最新文章