文章目录
ElasticSearch 分布式特性
es不需要集成第三方服务就可以完成分布式特性。
一、ES节点介绍
1.ES分布式特性
1) ES支持集群模式,是一个分布式系统,其好处主要有两个:
- 增大系统容量,如内存,磁盘,使得es集群可以支持PB级的数据
- 提高系统可用性,即使部分节点停止服务,整个集群依然可以正常服务
2)ES集群由多个es实例组成
- 不同集群通过集群名字来区分,可通过cluster.name来进行修改,默认为elasticsearch
- 每个es实例本质上是一个JVM进程,且有自己的名字,可以通过node.name来进行修改
2.节点启动
运行如下命令可以快速启动一个es节点的实例,集群是通过集群名来保证节点是属于哪一个集群的。改变下面的node.name,path.data,http.port就可以在一台机器启动多个节点。
bin/elasticsearch
-Ecluster.name=my_cluster -Epath.data=my_cluster_node1 -Enode.name=node1
-Ehttp.port=5100 -d
# -d 表示以后台进程的方式运行
3.Cluster state
es 集群相关的数据称为 cluster state,主要记录如下信息:
- 节点信息,比如节点名称、链接地址等
- 索引信息,比如索引名称、配置等
- …
4.Master Node
- 1、可以修改cluster state的节点称为master节点,一个集群只能有一个
- 2、cluster state存储在每个节点上,master维护最新版本并同步给其他节点
- 3、master 节点是通过集群中所有节点选取产生的,可以被选举的节点称为master-eligible节点,相关配置:node.master: true
如下图中,实心的五角心就是master节点,空心的就其他节点。
5. Coordinating节点
处理请求的节点称为coordinating节点,该节点为所有节点的默认角色,不能取消;路由请求到正确的节点处理,比如创建索引的请求到master节点。
6.数据节点 Data Node
存储数据的节点称为 data节点,默认节点都是data类型,相关配置:node.data: true
7.单点问题
如果集群只有一个节点停止服务,该节点停止,集群就停止服务。但是如果集群有多个节点,一个节点挂了;会重新生成新的master节点。
二、副本和分片
分片就是把一条数据切分成几片,所以分片可以提供扩容,但并不是分的越多越好,要看具体情况分片。
1.概念介绍
如何将数据分布到所有节点上?
引入分片(Shard)解决问题
分片是ES支持PB级数据的基石,特点:
- 分片存储了部分数据,可以分布于任意节点上
- **分片数在索引创建时指定且后续不允许再更改,默认为5个**
- 分片有主分片和副本分片之分,以实现数据的高可用
- 副本分片的数据由主分片同步,可以有多个,从而提高读取的吞吐量
归纳:一个索引分片建立好了就不能更改,但是后期可以增加节点,增加节点没有办法提高已经建立好索引数据容量(分片已经定了),不过可以提高该索引的吞吐量。
如下红色圈表示的,实线表示主分片,虚线表示副分片;一一对应;如下建了book,index_01连个索引;book索引是5个shards分片(分成2份),一个replica副本,所以一共十个分片;index_01有3个shards分片(三份),一个replica副本,所以一共6个分片;
新建索引指定分片和副本
2. 节点问题
问题解决:
分片数的设定非常重要,需要提前规划好
- 分片数太少,导致后续无法通过增加节点实现水平扩容
- 分片数过大,导致一个节点上分布多个分片,造成资源浪费,同时会影响查询性能
三、集群状态 Cluster Health
1.集群状态
通过如下api可以查看集群健康状况,包括以下三种:
- green 健康状态,指所有主副分片都正常分配
- yellow 指所有主分片都正常分配,但是有副本分片未正常分配
- red 有主分片未分配
三种状态只是代表分片的工作状态,并不是代表整个es集群是否能够对外提供服务
Rest api获取状态:GET _cluster/health
2.故障转移
图1
图2
图3
图4
四、脑裂问题 split-brain
脑裂问题,英文为split-brain,是分布式系统中的经典网络问题,如下图所示:
- node2与node3会重新选举master,比如node2成为了新master,此时会更新cluster state
- node1自己组成集群后,也会更新cluster state
- 同一个集群有两个master,而维护不同的cluster state,网络恢复后无法选择正确的master
解决方案:
解决方案为仅在可选举master-eligible节点数据大于等于quorum时才可以进行master选举
quorum = master-eligible 节点数/2 + 1,例如 3个master-eligible节点时,quorum为2。
解决:设置config/elasticsearch.yml参数配置 discovery.zen.mininum_master_nodes为quorum即可避免脑裂
五、分布式存储
1.文档存储算法
doc1 是如何存储到分片P1的呢?选择P1的依据是什么呢?
需要文档到分片的映射算法
目的:
使得文档均匀分布在所有分片上,以充分利用资源
算法:
随机选择或者round-robin算法
不可取:因为维护文档到分片的映射关系,成本巨大
ES的分布式文档存储方案: hash算法
2.文档创建流程
3.文档读取流程
六、查询存储原理和分析
1.倒排索引生成不能更改
2.文档搜索实时性
如上倒排索引不能更改,如果重新再替换实时性受到影响。所以新文档直接生成新的倒排索引文件,查询的时候同时查询所有的倒排文件,然后对查询结果做汇总计算即可。
2.1 Lucene 中的segment
- Lucene采用了这种方案,它构建的单个倒排索引称为segment,合在一起称为Index(Lucene中的名称),
- 与ES中的Index概念不同,ES中的一个Shard对应一个Lucene Index。
- Lucene会有一个专门的文件来记录所有的segment信息,称为 Commit Point
2.2 refresh - 缓存
利用缓存来提升查询实时性。
2.3 translog - 缓存备份
处理缓存易丢失的情况
2.3 flush -持久化缓存中的segment
2.4 refresh 和 flush 发生的时机
refresh发生的时机主要有以下几种情况:
- 间隔时间达到时,通过index.settings.refresh_interval来设定,默认是1秒
- index.buffer占满时,其大小通过indices.memory.index_buffer_size设置, 默认为jvm heap的10%
- flush发生时也会发生refresh
flush发生的时机主要有以下几种情况:
- 间隔时间达到时,默认是30分钟,5.x之前可以通index.translog.flush_threshold_period修改;之后发布的版本无法设置
- translog占满时,其大小可以通过index.translog.flush_threshold_size控制,默认是512MB;每个index有自己的translog
2.5 删除和更新
2.6 Segment Merge
随着segment的增多,由于一次查询的segment数增多,查询速度会变慢
es会定时在后台进行segment merge的操作,减少segment的 数量
通过force_merge api可以手动强制做segment merge的操作
2.7 Search的运行机制
Search执行的时候实际分两个步骤运行的 Query阶段,Fetch阶段
1)Query阶段
- 1.node3在接收到用户的search请求后,先会进行Query阶段(此时Coordinating Node角色)
- 2.node3在6个主副分片中随机选择3个分片,发送search request
- 3.被选中的3个分片会分别执行查询并排序,返回from+size个文档Id和排序值
2)Fetch阶段
node3根据Query阶段获取到文档Id列表对应的shard上获取文档详情数据
- 1、node3向相关的分片发送multi_get请求
- 2、3个分片返回文档详细数据
- 3、node3拼接返回的结果并返回给用户
2.8 相关性算法问题
例子:
你通过关键字“hello”查询,含有这个字母的文档;如果有多个分片,返回结果的排序也许并不是按照你想要的排序结果排序,因为不同分片在Query阶段对于这个hello会生成不同的评分值,然后按照评分制排序。
评分因素:
1)text类型 单词出现频率越高 评分越高
2)匹配度完整度越高评分越高
七、分片和节点设计
记住几点:
- 分片数:决定了后面的数据扩容
- 节点数:吞吐量
解决index的扩容问题使用ES的:reindenx;即重新创建一个index, 再把原来数据导入到新的index,然后删掉老的index,ES内部提供方案解决。