Elastic:集群相关知识点总结(三)分片分配感知、强制感知
0.引言
集群中涉及索引分片的相关操作就离不开两个概念:分片分配感知和强制分片感知
1.分片分配感知
文档:Index modules > Index Shard Allocation > Index-level shard allocation filtering
Set up Elasticsearch > Configuration Elasticsearch > Cluster-level shard allocation and routing settings
1.1 什么是分片Shard
分片是ES的数据载体,一个索引可以被分成多个分片,在ES中又有主分片和副本分片之分,每个主分片承担单个索引的一部分数据,每个副本分片又是对应主分片的副本(备份)。每个分片都是Lucene的实例,具有完整的功能
1.1.1 为什么需要分片?
ES的使用场景是针对海量数据,如果没有分片的产生,那么所有的数据都会堆积在一个节点中,当索引数据达到GB,TB级别的时候,单个节点的压力会非常大,也导致访问速度急剧下降。同时单个节点也无法保证高可用,发生单点故障的几率很大。综上,针对分布式场景,为了保证高可用,出现了分片的概念。
1.1.2 索引的数据完整性是什么?
比如索引被分成了3个主分片,每个主分片有1个副本分片,也就是说这个索引数据被分成了3份,那么只要这三份数据存在,无论是主还是副都成为这个索引数据是完整的。比如有主分片p0,p1,p2,副分片r0,r1,r2,当p0,p1丢失,但r0,r1存在,这样r0,r1,p2就可以组成一份完整的索引数据。
1.1.3 当主分片宕机时,副分片会发生什么?
理论应当基于实践,这一点我们通过一个实验来证明
首先我们的集群环境是个节点,先创建一个索引,并且设置3主1从
PUT test
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}
观察分片分配情况
GET _cat/shards?v
结果中可以看到节点1分配了p1,r0,节点2分配了p2,p0,节点3分配了r1,r2
现在我们把节点2关闭,再查看分片情况,发现节点2宕机后,存储在节点1中的r0以及存储在节点3中的r2都转换成主分片了,所以实验得知,当主分片宕机时,副分片会转换为主分片来顶替他的工作
我们插入一条数据再观察分片情况:
会发现6个分片已经重新分配到节点1和节点3上了,为了保证主分片和副分片不在同一节点上的要求,2个节点盛装6分片已经是最小的盛装方案了,节点数再小,就会出现分片未分配的情况了
1.2 分片分配策略
ES会自动在节点上做分片均衡(shard reblance),会尽可能的让分片分配到不同的节点上。
每个主分片和其副本分片不能同时存在于一个节点上,以此保证一个节点宕机,还有另一个分片可用
如果有出现分片未分配的情况,可以通过以下指令查看原因
GET _cluster/allocation/explain
1.3 普通分片分配
假设硬件分布在两个不同的物理机架中,普通的分片分配虽然会将主副分片分配到不同的节点上,但是不能保证这些节点不是在同一个机架下的,因此有可能会将主副分片分布在同一个机架上。如下图所示,my_index的分片分布在两个不同的物理机架rack1,rack2上,总共有主分片p0,p1,副分片r0,r1,假设现在rack1或者rack2宕机了,就会导致分片0或者分片1的主副分片都不存在,从而导致索引不可用,为了避免这种情况引入了分片分配感知
什么是机架?
做运维的同学可能比较清楚,简单来说就是存放服务器的机柜,因为同一个机柜的服务器一般是同一套供电、网络,所以可能存在整个机柜的服务器一起宕机的情况。因此我们往往需要将分片数据放在不同的机架上,这样即使一个宕机了,另一个机架的数据还是完整的,还能提供正常的查询服务。但要实现这一点,我们就需要分片分配感知来帮忙了。
1.4 分片分配感知
分片感知分配:
通过自定义节点属性来实现,比如定义一个属性rack_id,通过该属性来判断是否属于同一个机架,比如当有2个机架时,就会分别在另一个机架中分配自己的副分片,这样就能保证另一台机架宕机后,仍工作的机架上也有之前的机架的副分片,从而保证了数据的完整性。
设置启用分片分配感知后,分片仅分配给已为指定感知属性设置值的节点。如果使用了多个感知属性,那么es在分配分片时会分别考虑每个属性
总的来说,分片分配感知会将任意一个机架上的索引的副分片复制到每个机架中,这样就能确保即使某一个机架宕机了,其他机架上也有自己的备份,从而保证数据的完整性
分片分配感知开启后分片的分配如下,当机架2宕机后,机架1中还有分片1的副本,这时副分片1会转换为主分片1,以此保证集群的可用性。这一点在上述的实验中也以证明。
注意:针对分片分配感知的理解,不要局限于只是用来标识机架的,分片感知可以理解为是用来给节点分组的,哪几个节点按照某一个属性归为一组,所以可能存在开启多个标识,同一个节点属于多个不同的分组
1.4.1 开启分片分配感知
1、机架1中添加配置
node.attr.rack_id: rack_1
2、机架2中添加配置
node.attr.rack_id: rack_2
3、开启分片分配感知
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.awareness.attributes": "rack_id"
}
}
除了使用自定义的属性来实现外,还可以使用节点自带的属性
_name:匹配节点名称
_host_ip: 匹配节点主机IP地址
_publish_ip:匹配节点发布IP地址
_ip:匹配host_ip或者publish_ip
_host:匹配主机名hostname
_id:匹配节点ID
_tier:匹配节点的数据层角色
1.4.2 分片分配感知还能做什么?
1、部署冷热集群
用一个自定义属性来标识哪些节点是热节点,哪些节点是冷节点,以此实现冷热集群,并且配合ILM实现冷热数据的自动流转。具体可参考这篇博客关于ILM的一些试验
使用自定义属性来定义冷热集群需要注意的一点是,在创建索引数据的时候,需要指定一下哪个节点是热节点,虽然你在集群中已经配置了hot的自定义属性,但是这仅仅是你定义的,集群并不知道这个属性代表什么,所以你需要通过指定来告诉它,通过以下指令
# hot_warm_cold是你的自定义属性,data_hot就是你热节点的自定义属性值
"index.routing.allocation.require.hot_warm_cold": "data_hot"
2.强制分片感知
官方文档:文档:Set up Elasticsearch » Configuring Elasticsearch » Cluster-level shard allocation and routing settings
默认情况下,如果一个位置失败,es会将所有丢失的副本分片分配给其他位置。尽管你可能在所有位置上都有足够的资源来承载你的主副分片,但单个位置可能无法承载所有分片
为了防止发生故障时单个位置过载,可以设置cluster.routing.allocaltion.awareness.force,可以使在其他位置的节点可用之前,不分片任何副本。
PUT _cluster/settings
{
"transient": {
"cluster.routing.allocation.awareness.attributes": "my_rack_id",
"cluster.routing.allocation.awareness.force.my_rack_id.values": "rack1,rack2"
}
}
强制分片感知的介绍比较简短,只要记住他的核心作用,防止节点故障时导致的所有副本分片分配到一个节点上而产生过载宕机,配置后可使的在出现节点宕机时,另外的节点中不会分配副本分片
- 点赞
- 收藏
- 关注作者
评论(0)