基础编程学习快乐每一天
首页
留言
Siddim.com
当前位置:
首页
>
编程知识库
>
后端开发知识
>
图解ElasticSearch原理,搞懂它,面试再也不用怕被问到了!
图解ElasticSearch原理,搞懂它,面试再也不用怕被问到了!
阅读
1
2020-09-12
:
001
期~
150
期汇总,方便阅读,不断更新中.....
摘要
先自上而下,后自底向上的介绍
ElasticSearch
的底层工作原理,试图回答以下问题:
为什么我的搜索 *
foo
-
bar
* 无法匹配
foo
-
bar
?
为什么增加更多的文件会压缩索引(
Index
)?
为什么
ElasticSearch
占用很多内存?
版本
elasticsearch
版本:
elasticsearch
-
2
.
2
.
0
图解ElasticSearch
云上的集群
集群里的盒子
云里面的每个白色正方形的盒子代表一个节点——
Node
。
节点之间
在一个或者多个节点直接,多个绿色小方块组合在一起形成一个
ElasticSearch
的索引。
索引里的小方块
在一个索引下,分布在多个节点里的绿色小方块称为分片——
Shard
。
Shard=Lucene Index
一个
ElasticSearch
的
Shard
本质上是一个
Lucene
Index
。
Lucene
是一个
Full
Text
搜索库(也有很多其他形式的搜索库),
ElasticSearch
是建立在
Lucene
之上的。接下来的故事要说的大部分内容实际上是
ElasticSearch
如何基于
Lucene
工作的。
图解Lucene
Mini索引——segment
在
Lucene
里面有很多小的
segment
,我们可以把它们看成
Lucene
内部的
mini
-
index
。
Segment内部
有着许多数据结构
Inverted
Index
Stored
Fields
Document
Values
Cache
最最重要的Inverted Index
Inverted
Index
主要包括两部分:
一个有序的数据字典
Dictionary
(包括单词
Term
和它出现的频率)。
与单词
Term
对应的
Postings
(即存在这个单词的文件)。
当我们搜索的时候,首先将搜索的内容分解,然后在字典里找到对应
Term
,从而查找到与搜索相关的文件内容。
查询“the fury”
自动补全(AutoCompletion-Prefix)
如果想要查找以字母“
c
”开头的字母,可以简单的通过二分查找(
Binary
Search
)在
Inverted
Index
表中找到例如“
choice
”、“
coming
”这样的词(
Term
)。
昂贵的查找
如果想要查找所有包含“
our
”字母的单词,那么系统会扫描整个
Inverted
Index
,这是非常昂贵的。
在此种情况下,如果想要做优化,那么我们面对的问题是如何生成合适的
Term
。
问题的转化
对于以上诸如此类的问题,我们可能会有几种可行的解决方案:
*
suffix
-&
gt
;
xiffus
*
如果我们想以后缀作为搜索条件,可以为
Term
做反向处理。
(
60
.
6384
,
6
.
5017
) -&
gt
;
u4u8gyykk
对于
GEO
位置信息,可以将它转换为
GEO
Hash
。
123
-&
gt
; {
1
-
hundreds
,
12
-
tens
,
123
}
对于简单的数字,可以为它生成多重形式的
Term
。
解决拼写错误
一个
Python
库 为单词生成了一个包含错误拼写信息的树形状态机,解决拼写错误的问题。
Stored Field字段查找
当我们想要查找包含某个特定标题内容的文件时,
Inverted
Index
就不能很好的解决这个问题,所以
Lucene
提供了另外一种数据结构
Stored
Fields
来解决这个问题。
本质上,
Stored
Fields
是一个简单的键值对
key
-
value
。默认情况下,
ElasticSearch
会存储整个文件的
JSON
source
。
Document Values为了排序,聚合
即使这样,我们发现以上结构仍然无法解决诸如:排序、聚合、
facet
,因为我们可能会要读取大量不需要的信息。
所以,另一种数据结构解决了此种问题:
Document
Values
。这种结构本质上就是一个列式的存储,它高度优化了具有相同类型的数据的存储结构。
为了提高效率,
ElasticSearch
可以将索引下某一个
Document
Value
全部读取到内存中进行操作,这大大提升访问速度,但是也同时会消耗掉大量的内存空间。
总之,这些数据结构
Inverted
Index
、
Stored
Fields
、
Document
Values
及其缓存,都在
segment
内部。
搜索发生时
搜索时,
Lucene
会搜索所有的
segment
然后将每个
segment
的搜索结果返回,最后合并呈现给客户。
Lucene
的一些特性使得这个过程非常重要:
Segments
是不可变的(
immutable
)
Delete
? 当删除发生时,
Lucene
做的只是将其标志位置为删除,但是文件还是会在它原来的地方,不会发生改变
Update
? 所以对于更新来说,本质上它做的工作是:先删除,然后重新索引(
Re
-
index
)
随处可见的压缩
Lucene
非常擅长压缩数据,基本上所有教科书上的压缩方式,都能在
Lucene
中找到。
缓存所有的所有
Lucene
也会将所有的信息做缓存,这大大提高了它的查询效率。
缓存的故事
当
ElasticSearch
索引一个文件的时候,会为文件建立相应的缓存,并且会定期(每秒)刷新这些数据,然后这些文件就可以被搜索到。
随着时间的增加,我们会有很多
segments
,
所以
ElasticSearch
会将这些
segment
合并,在这个过程中,
segment
会最终被删除掉
这就是为什么增加文件可能会使索引所占空间变小,它会引起
merge
,从而可能会有更多的压缩。
举个栗子
有两个
segment
将会
merge
这两个
segment
最终会被删除,然后合并成一个新的
segment
这时这个新的
segment
在缓存中处于
cold
状态,但是大多数
segment
仍然保持不变,处于
warm
状态。
以上场景经常在
Lucene
Index
内部发生的。
在Shard中搜索
ElasticSearch
从
Shard
中搜索的过程与
Lucene
Segment
中搜索的过程类似。
与在
Lucene
Segment
中搜索不同的是,
Shard
可能是分布在不同
Node
上的,所以在搜索与返回结果时,所有的信息都会通过网络传输。
需要注意的是:
1
次搜索查找
2
个
shard
=
2
次分别搜索
shard
对于日志文件的处理
当我们想搜索特定日期产生的日志时,通过根据时间戳对日志文件进行分块与索引,会极大提高搜索效率。
当我们想要删除旧的数据时也非常方便,只需删除老的索引即可。
在上种情况下,每个
index
有两个
shards
如何Scale
shard
不会进行更进一步的拆分,但是
shard
可能会被转移到不同节点上
所以,如果当集群节点压力增长到一定的程度,我们可能会考虑增加新的节点,这就会要求我们对所有数据进行重新索引,这是我们不太希望看到的,所以我们需要在规划的时候就考虑清楚,如何去平衡足够多的节点与不足节点之间的关系。
节点分配与Shard优化
为更重要的数据索引节点,分配性能更好的机器
确保每个
shard
都有副本信息
replica
路由Routing
每个节点,每个都存留一份路由表,所以当请求到任何一个节点时,
ElasticSearch
都有能力将请求转发到期望节点的
shard
进一步处理。
一个真实的请求
Query
Query
有一个类型
filtered
,以及一个
multi
_
match
的查询
Aggregation
根据作者进行聚合,得到
top10
的
hits
的
top10
作者的信息
往期:
001
期~
150
期汇总,方便阅读,不断更新中.....
请求分发
这个请求可能被分发到集群里的任意一个节点
上帝节点
这时这个节点就成为当前请求的协调者(
Coordinator
),它决定:
根据索引信息,判断请求会被路由到哪个核心节点
以及哪个副本是可用的
等等
路由
在真实搜索之前
ElasticSearch
会将
Query
转换成
Lucene
Query
然后在所有的
segment
中执行计算
对于
Filter
条件本身也会有缓存
但
queries
不会被缓存,所以如果相同的
Query
重复执行,应用程序自己需要做缓存
所以,
filters
可以在任何时候使用
query
只有在需要
score
的时候才使用
返回
搜索结束之后,结果会沿着下行的路径向上逐层返回。
来源:
cnblogs
.
com
/
richaaaard
/
p
/
5226334
.
html
? ~
以上数据来源于网络,如有侵权,请联系删除。
上一篇:
面试官:你对MySQL分区的知识了解多少?
下一篇:
面试官:反射是如何影响性能的,它到底慢在哪里?
评论
(0)
提交
类别
基础编程学习
HTML
PHP
Python
编程知识库
后端开发知识
热门文章
Java并发中的同步容器与并发容器,你了解多少?
Innodb中的事务隔离级别和锁的关系,难倒一半面试者!
SpringBoot + minio实现分片上传、秒传、续传
面试官:你知道消息队列如何保证数据不丢失吗?
JAVA知识 Java8新特性
面试官:谈谈为什么要限流,有哪些限流方案?
说说动态代理与静态代理区别
面试官:思考Tomcat 类加载器为什么要违背双亲委派模型?
boot-admin 基于SpringBoot的后台权限管理系统,可作为脚手架,用于快速搭建项目
SpringBoot+Vue+App+硬件实现智能家居系统项目