一、ES 分布式架构原理
ES
设计的理念是分布式搜索引擎,底层实现基于Lucene
,核心思想是在多台机器上启动多个ES
进程实例,组成一个ES
集群。
概念描述
- 接近实时:
ES
是一个接近实时的搜索平台,这就意味着,从存入一个文档直到文档能够被搜索到有一个轻微的延迟
- 集群(cluster):一个集群由多个节点(服务器)组成,所有节点一起保存全部数据,每一个集群有一个唯一的名称标识
- 节点(node):一个节点是一个单一的服务器,是集群的一部分,它存储数据并且参与集群的搜索功能,一个节点可以通过配置特定的名称来加入特定的集群,在一个集群中,你想启动多少个节点就可以启动多少个节点
- 索引(index) :一个索引是含有某些共有特性的文档的集合,一个索引被一个名称唯一的标识,通过这个名称去文档中进行搜索、更新和删除操作
- 类型(type):一个
index
里可以有多个type
,一个type
就相当于数据库中的一张表(type
在6.0.0
版本已经不赞成使用)
- 文档(document) :一个文档是一个基本的搜索单元
- 做个小总结:
ES
中存储数据的基本单位是索引,比如说ES
中存储了一些订单系统的销售数据,就应该在ES
中创建一个索引order_index
,所有的销售数据都会写到这个索引里面去,一个索引就像一个数据库,而type
就相当于库里的表,一个index
里面可以有多个type
,而mapping
就相当于表的结构定义,定义了字段的类型等,往index
的一个type
里添加一行数据,这行数据就叫做一个document
,每个document
有多个filed
,每一个filed
就代表这个document
的一个字段的值。
- 分片(shards):在一个搜索引擎里存储的数据,潜在的情况下可能会超过单个节点的硬件存储限制,为了解决这个问题,
ES
便提供了分片的功能,它可以将索引划分为多个分片,当创建一个索引的时候,可以简单的定义你想要的分片的数量,每一个分片本身是一个全功能的完全独立的索引,每个分片可以部署到集群中的任何一个节点。分片的主要原因:- 它允许水平切分你的内容卷
- 它允许通过分片和并行操作来应对日益增长的执行量
- 复制(replica):在一个网络情况下,故障可
七墨博客 能随时会发生,有一个故障恢复机制是必须的,为了达到这个目的言七墨 ,ES
允许你制作一个或多个拷贝放入一个叫做复制分片或短暂的复制品中。复制带来的好处:- 高可用:它可以防止分片或者节点宕机,为此,需要注意绝对不要将一个分片的拷贝放在跟这个分片相同的机器上
- 高并发:它允许你的分片可以提供超出自身吞吐量的搜索能力,搜索行为可以在所有的分片拷贝中并行执行
- 总之,一个完整的流程:
ES
客户端将一份数据写入primary shard
,然后将数据同步到replica shard
中去。ES
客户端取数据的时候就会在replica
或primary
的shard
中去读。ES
集群有多个节点,会自动选举一个节点为master
节点,这个master
节点干一些管理类的操作,比如维护元数据,负责切换primary shard
和replica shard
的身份,要是master
节点宕机了,那么就会重新选举下一个节点为master
为节点。如果primary shard
所在的节点宕机了,那么就会由master
节点将那个宕机的节点上的primary shard
的身份转移到replica shard
上,如果修复了宕机的那台机器,重启之后,master
节点就会将缺失的replica shard
分配过去,同步后续的修改工作,让集群恢复正常。
二、ES写入数据的过七墨博客 程

- 客户端发送任何一个请求到任意一个
node
,这个节点就成为协调节点(coordinate node
) - 协调节点对
document
(可以手动设置doc id
,也可以由系统分配)进行hash
路由,将请求转发给对应的node
-
node
上的primary shard
处理请求,然后将数据同步到replica node
- 协调节点如果发现
primary shard
所在的node
和所有的replica shard
所对应的node
都搞定之后,就会将请求返回给客户端
三、ES读数据过程

可以通过doc id
来查询,根据doc id
进行hash
,判断当时写这个document
时是分配到哪个shard
上去了,然后就去那个shard
上查询。
- 客户端发送任何一个请求到任意一个
node
,这个节点就成为协调节点(c
)七墨博客 oordinate node - 协调节点对
doc id
进行hash
路由,将请求转发到对应的node
,此时会使用round-robin
随机轮询算法,在primary shard
以及所有的replica shard
中随机选择一个,让读请求负载均衡 - 接受请求的
node
,返回document
给协调节点 - 协调节点再将数据返回给客户端
四、ES搜索数据过程

- 客户端发送一个请求给协调节点(
coordinate node
) - 协调节点将搜索的请求转发给所有
shard
对言七墨 应的primary shard
或replica shard
- query phase:每一个
shard
将自己搜索的结果(其实也就是一些唯一标识),返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最后的结果 - fetch phase :接着由协调节点,根据唯一标识去各个节点进行拉取数据,最总返回给客户端
五、ES写入数据的底层原理

六、倒排索引
倒排索引:建立分词与文档之间的映射关系,在倒排索引中,数据是面向分词的而不是面向文档的
。
在搜索引擎中,每个文档都有一个对应的文档ID
(即doc id
),文档内容被表示为一系列关键词的集合。例如,文档1
经过分词,提取了20
个关键词,每个关键词都会记录它在文档中出现的次数和出现的位置。
IDF(inverse document frequency):包含这个关键词的所有文档(document
)的数量
TF(term frequency):这个关键词在每个文档(document
)中出现的次数
那么,倒排索引就是关键词
(word
)到文档ID
的映射,每个关键词
都对应着一系列的文档
。
- 举个栗子:
文档:
对文档进行分词之后,得到以下倒排索引
:
word id | word | doc id 列表 |
1 | 七墨 | 1,2,3,4,5 |
2 | 博客 | 1,2,3,4,5 |
3 | Java开发 | 1,2,5 |
4 | 个人 | 3,5 |
5 | 专注 | 1,2,5 |
6 | 技术 | 3,5 |
… | … | … |
那么,有了倒排索引,搜索引擎可以很方便地响应用户的查询。比如用户查询七墨
,搜索引擎查找倒排索引,从中读出包含这个单词的文档,这些文档就是提供给用户的搜索结果。
倒排索引不可变的优缺点:
- 优点:
- 不需要锁、提升并发能力,避免锁的问题
- 可以一直保存在
os cache
中,只要cache
内存足够 -
filter cache
可以一直驻留在内存中 - 可以压缩,节省
cpu
和io
- 缺点:
- 每次都要重新构建整个索引
七、在海量数据中提高效率的几个手段
- filesystem cache:
ES
的搜索引擎严重依赖底层的filesystem cache
,如果给filesystem cache
更多的内存,尽量让内存可以容纳所有的index segment file
索引数据文件 - 数据预热:对于那些你觉得比较热的数据,即经常会有人访问的数据,最好做一个专门的缓存预热子系统,对于热数据,每隔一段时间,系统本身就提前访问一下,让数据进入
filesystem cache
里面去,这样下次访问的时候,性能会更好一些。 - 冷热分离:
- 冷数据索引:查询频率低,基本无写入,一般为当天或最近
2
天以前的数据索引,这种数据可以存储在机械硬盘HDD
中 - 热数据索引:查询频率高,写入压力大,一般为当天的数据索引,这种数据可以存储在
SSD
中
- 冷数据索引:查询频率低,基本无写入,一般为当天或最近
- document的模型设计:不要在搜索的时候去执行各种复杂的操作,尽量在
document
模型设计和数据写入的时候就将复杂操作处理掉 - 分页性能优化:翻页的时候,翻得越深,每个
shard
返回的数据越多,而且协调节点处理的时间越长,此时,要用scroll
,scroll
会一次性的生成所有数据的快照,然后每次翻页都是通过移动游标来完成