05.ES集群原理常识原理
Elasticsearch (ES) 是一种分布式搜索引擎,具备去中心化架构和分布式集群特性。
ES 通过动态选举主节点来避免单点故障。
集群中的每个节点负责不同任务,包括主节点、数据节点、协调节点等。
数据通过分片和副本机制进行分布式存储和高可用性保证。主分片处理写操作,副本分片提供数据冗余和读操作支持。
ES 采用路由机制根据文档的 ID 选择目标分片,并且能够通过水平扩容和故障转移保证系统性能和可靠性
# 01.ES分布式集群架构特性
# 1、集群
- 在一个ES集群中,通过多个ES实例组成,其中有一个为主节点(master)
- ES是去中心化的,所以主节点是动态选举出来的,不是单点故障
- 你与任何一个节点通信和与整个ES集群通信结果是一样的
- 节点通信
- 在同一个子网中,只需要在每个节点上设置相同的集群名,ES就自动把这些几圈名相同的节点组成一个集群
- 节点与节点间通信以及节点之间的数据分配和平衡完全由ES自动管理
- 一个ES集群建议数量不要超过100个节点
# 2、节点
每个运行ES实例称为一个节点,每一个ES运行实例(服务器进程)既可以在同一个机器上,也可以在不同机器上
在测试环境中,可以在一台服务器上运行多个服务器进程
在生产环境中,建议每一台服务器运行一个服务器进程
ES7中节点(node)主要有4中类型
- 主节点(Master)
- 数据节点(data)
- 协调节点(Coordinating)
- 预处理节点
# 3、master选举
选举策略
- 如果集群中存在master,认可该master,加入集群
- 如果集群中不存在master,从具有master资格的节点中
选id最小的节点作为master
选举时机
- 集群启动:后台启动线程去ping集群中的节点,按照上述策略从具有master资格的节点中选举出master
- 现有的master离开集群:后台一直有一个线程定时ping master节点,超过一定次数没有ping成功之后,重新进行master的选举
避免脑裂
- 脑裂问题是采用master-slave模式的分布式集群普遍需要关注的问题
- 脑裂一旦出现,会导致集群的状态出现不一致,导致数据错误甚至丢失
- ES避免脑裂的策略:过半原则,可以在ES的集群配置中添加一下配置,避免脑裂的发生
# 02.ES集群架构
# 0、架构介绍
- 真实环境中需要至少 9 台机器
# 1、ES 主节点(Master)
- ES主节点作用(Master)
- 主节点主要负责集群中的轻量级操作,负责
创建索引,删除索引
,追踪集群中的节点状态
等工作 - 集群中的大脑,非常重要(不存储数据)
- 集群中如果某一个主节点挂掉,从节点会重新选择主节点
生产环境master部署建议
- 使用独立节点,尽量与data分开
- 数据节点达到3个,主节点至少三台
- 采用低配的服务器资源即可
- 主节点主要负责集群中的轻量级操作,负责
# 2、ES数据节点(Data)
- 数据节点
- 数据节点
存储
了所有的分配,文档,索引数据
- 主要
处理数据
相关的操作,CRUD、搜索和聚合
- 数据节点需要大量的空间来存储数据,索引和搜索等数据操作对CPU、内存、IO密集型的消耗非常大
- 需要大量的磁盘空间来存储数据
生产环境Data节点建议
- 单节点处理数据量5TB内
- 采用高配置的服务器资源(内存不建议超过64G,高速硬盘)
- 数据节点
# 3、协调节点(Coordinating)
- 路由索引请求
- 聚合搜索结果集
- 分发批量索引请求
- 协调节点主要用来负载均衡,
把客户端的请求转发分配给最合适的节点来处理
,降低主节点和数据节点负载
- 在校集群中,协调节点的功能可以有主节点或数据节点来完成
- 生产环境建议
- 大型集群中协调节点知识3个
- 采用中高配置的服务器资源
# 4、其他概念
0)预处理节点(Ingest)
- ES支持在将数据写入索引之前对数据进行预处理,内容富华等操作
- Ingest节点的功能抽象为:大数据处理环节的ETL(抽取、转换、加载)
- 所有的节点都是默认支持ingest的,任何节点都可以处理ingest请求
- 注意:监控数需要走ingest node进入集群,所以不建议关闭ingest功能
1)Recovery
数据恢复或者叫做数据重新分布
在ES集群中当前节点加入或退出时他会根据机器的负载均衡对索引分片进行重新分配
当挂掉的节点再次重新启动的时候也会进行数据恢复
2)River
- ES river 代表的是一个数据源,这也是从其他数据库同步数据到ES的方法
3)gateway
- 代表ES索引的持久化存储方式,ES默认是先把索引存放到内存中去
- 当内存满了的时候再持久化到硬盘里,当ES集群关闭或者再次重新启动时就会从gateway中读取索引数据
4)Transport
- Transport代表ES内部的节点或者集群与客户端之间的交互方式
- 默认的内部是使用tcp协议(如9300端口)来进行交互的,同时也支持http协议等多种传输协议
# 03.ES分布式集群特性
# 1、分片(shards)
ES会把
一个索引分解成多个小索引,每个小的索引就叫做分片
再把
各个分片分配到不同的节点中去
过多的分片数量会照成较大的管理压力,ES7.x 默认分片为1
注:
类似MySQL的分库分表
生产环境建议
- 搜索场景下一个分片大小建议不要操作30G索引
- 整个集群的分片数量建议不超过10万个
- 分片越多,单分片数据就约少,约分散,但是管理压力会更大
# 2、副本(replicas)
ES的每一个分片都可以有0~N个副本,而每个副本也都
是分片的完整拷贝
作用:故障转移/集群恢复,通过副本进行负载均衡
ES的某一个节点数据损坏或者服务器不可用的时候,那么这个时候就可以用其他节点来替换坏掉的节点,已到达高可用的目的
当主分片异常时,副本可以提供数据的查询等操作
对文档的新建、索引和删除请求都是写操作,必须在主分片上完成之后才能被复制到相关的副本分片
生产环境建议
- 副本数(replicas)最低为1
- 副本越多消耗约大,但也越保险
副本存储过程
- 客户端中存储一个数据时,先进行分片,这里分成六个片
- 分别是:Node1(P0、P4)、Node2(P1、P3)、Node2(P2、P5)
- 然后对于每个分片,在其他节点上创建了一个副本
- 比如:node1中的P0的副本就在node2的R0中
- 副本实质上就是对分片的备份,保证数据不会丢失
# 3、水平扩容
- Node 1 和 Node 2 上各有一个分片被迁移到了新的 Node 3 节点
- 现在每个节点上都拥有2个分片,而不是之前的3个
我们这个拥有6个分片(3个主分片和3个副本分片)的索引可以最大扩容到6个节点
P0,P1,P2是主分片只能有一个,R0,R1,R2是副本可以有多个
- 主分片的数目在索引创建时就已经确定了下来
- 这个数目定义了这个索引能够 存储 的最大数据量
- 读操作——搜索和返回数据——可以同时被主分片 或 副本分片所处理
- 所以当你拥有越多的副本分片时,也将拥有越高的吞吐量
让我们把副本数从默认的 1 增加到 2,R0,R1,R2副本就会变成两个
# 4、故障转移
- 如果我们关闭第一个节点,这时集群的状态为
我们关闭的节点是一个主节点,而集群必须拥有一个主节点来保证正常工作
所以发生的第一件事情就是选举一个新的主节点: Node 2
在我们关闭 Node 1 的同时也失去了主分片 1 和 2 ,并且在缺失主分片的时候索引也不能正常工作
如果此时来检查集群的状况,我们看到的状态将会为 red :不是所有主分片都在正常工作
幸运的是,在其它节点上存在着这两个主分片的完整副本
所以新的主节点立即将这些分片在 Node 2 和 Node 3 上对应的副本分片提升为主分片
# 04.ES分布式集群路由机制
# 0、集群启动过程
A. 首先启动第一个节点fgNode1
第一个节点的一定是主节点
,主节点存储的是集群的元数据信息
B. 然后
启动第二个节点fgNode2
- 启动之前会配置集群的名称Cluster-name:fgescluster1
- 然后配置可以作为主节点的IP地址信息 [“192.168.56.11”,“192.168.56.21”]
- 配置自己的ip地址network.host:192.168.56.12
C. fgNode2启动的过程
- fgNode2启动的过程中会去
找到主节点fgNode1
,告诉fgNode1我要加入到集群
- 主节点fgNode1接受到请求后看看fgNode2是否满足加入集群的条件
- 如果满足就把fgNode2的ip地址加入的元信息里面,然后
广播给集群中的其他节点
- 主节点会把最新的元信息
发送给其他的节点中更新
- fgNode2启动的过程中会去
# 1、创建索引
# 1)创建索引
1)转发请求到 master
客户端请求到fgNode3节点创建索引
fgNode3节点把请求
转发给master主节点
2)master记录源信息并广播给集群其他节点
- 其他节点接收到新集群状态后,开始在本地为新索引创建主分片和副本分片
- 建索引的决策是在主节点上做出的,但实际索引是在集群中的数据节点上创建
- 主节点只是负责管理和协调,不会存储数据
3)返回结构给客户端
创建节点会向master主节点反馈结果
master主节点向fgNode3反馈结果
fgNode3节点响应客户端请求
4)将索引信息广播给所有从节点
master主节点将元信息广播给所有从节点
# 2)源信息
ES的
主节点主要负责管理集群的元数据
(管理和协调源信息的存储的整个流程)这包括
索引的名称、索引的设置
(例如分片数量和副本数量
)、字段的映射信息
等主节点并不直接存储文档数据或源信息
master 记录源信息意思指什么?
- 当我们说主节点"记录"源信息,实际上是指主节点在创建或更新索引时
- 会把索引的映射信息(也就是字段的名称、类型、分析器等设置)
更新到集群状态中
当你从Elasticsearch获取或搜索文档时,实际的数据是从存储这些文档的数据节点上读取的
ES
集群状态
是什么意思?
- 集群状态(Cluster State)是一个重要的概念,它包含了集群的全局信息
- 例如当前的索引、映射、分片位置等,集群状态由集群中的主节点管理和维护
- 更新到集群状态,本质就是
把索引映射信息等广播给集群中的所有其他节点
- 这样整个集群都能够知道了这些 集群的全局信息
# 2、创建文档
# 1)创建文档
1)找到主分片
- 客户端请求fgNode3,
fgNode3计算文档路由值
并得到文档存放的主分片P1
(主分片才能写入)
- 客户端请求fgNode3,
2)转发给主分片
- fgNode3将
文档转发给主分片P1
,主分片节点在fgNode2上
- fgNode3将
3)主分片同步到副本
- fgNode2索引文档,
同步给副本(R1)
节点fgNode1索引文档
- fgNode2索引文档,
4)返回结果给客户端
fgNode2向fgNode3反馈结果
,fgNode3做出相应
# 2)路由机制
ES的路由机制
是用来确定一个文档应该被存储在哪个主分片中
插入文档时,ES根据文档_id或提供的路由值来计算一个哈希值,来选择一个主分片
这就保证同一个文档总是会被存储在同一个主分片中,无论这个分片是否被移动到新的节点
计算公式如下
_routing
: 文档的_id(是一个可选的路由值,可以自己指定)num_primary_shards
: 是在创建索引时指定的主分片数量
- 注: 一般_id 是固定不变的,所以
shard 的计算结果也是一个固定值
shard = hash(routing) % number_of_primary_shards
- eg: 假设我们创建了一个名为my_index的索引,这个索引有5个主分片
# 然后,我们插入一个文档,文档的_id是my_doc,
# 假设hash('my_doc')的结果是2,那么这个文档就会被存储在编号为2的分片中
shard_num = hash('my_doc') % 5
2
3
# 3、搜索文档
Elasticsearch的"搜索文档"和"分布式检索"是相关但不完全相同的概念
1)搜索文档是一个 功能
- "搜索文档"是指在Elasticsearch中执行查询操作,以找到满足特定条件的文档
- 查询可以非常简单,例如查找包含某个词的文档,也可以非常复杂,包括多个字段的复杂逻辑组合,或者包括聚合操作
- 搜索文档是Elasticsearch的核心功能之一
2)分布式检索是实现这个功能的 方法
搜索文档时,如果数据分布在多个节点上,那么就需要执行分布式检索
搜索请求时,ES在多个节点上并行地执行搜索,然后合并结果(这就是分布式检索)
# 1)搜索文档
1)查询分发给副本节点
客户端搜索索引 fgindex,并请求 fgNode3
fgNode3将查询发给索引 fgindex 的 分片/副本节点(P0~P5 R0~R5)
2)各个副本并行查询返回结果(需要进行结果合并)
各个节点执行查询,将结果给 fgNode3
fgNode3合并结果,响应客户端
- 举例:
- 所以
fgindex 中有6个分片
,每个分片有1个副本,共12个分片
- 一
次搜索请求会由6个分片来完成
,他们可能是主分片也可能是副本分片
【如:P0,P1,P2,R3,R4,R5】 - 所以一次搜索请求智慧命中所有分片副本中的一个(分片/副本),所以增加副本数不会因并行查询而变快
- 但是在某些场景下多个副本,可能会选择出一个当前集群状态写能快速响应的副本,从而加快速度
- 所以
# 2)分布式搜索
- 执行一个搜索请求时,ES在多个节点上并行地执行,然后将结果合并并返回,这就是分布式检索
1)查询阶段
搜索请求会被发送到集群中的一个节点,这个节点可以叫做协调节点(任意节点都可以)
节点会将搜索请求转发给存储这个索引的所有分片所在的节点(主分片或副本但是不重复)
每个节点负责搜索它本地的一个分片,并将结果返回给协调节点
注:这个过程是并行的,也就是说,所有的节点会同时开始搜索,并尽快返回结果
2)取回阶段
协调节点收集到所有结果后,会对结果进行合并和排序
然后,根据请求中的size参数,协调节点会从所有结果中挑选出最相关的几个结果返回给客户端
如果请求中包含了聚合,协调节点还需要对每个节点返回的聚合结果进行合并,以生成最终的聚合结果
通过这种方式,ES可以在大量数据上实现快速的全文搜索和复杂的数据聚合
# 4、更新文档
1)请求转发给主分片
客户端向 Node 1 发送更新请求
Node1将请求转发到主分片所在的 Node 3
2)主节点修改文档
Node 3 从主分片检索文档,修改 _source 字段中的 JSON ,并且尝试重新索引主分片的文档
如果文档已经被另一个进程修改,它会重试步骤 3 ,超过 retry_on_conflict 次后放弃
3)同步新文档到副本
- 如果 Node 3 成功地更新文档,它将新版本的文档并行转发到 Node 1 和 Node 2 上的副本分片,重新建立索引
- 一旦所有副本分片都返回成功, Node 3 向协调节点也返回成功,协调节点向客户端返回成功