本套技术专栏作者(秦凯新)专注于大数据及容器云核心技术解密,具备5年工业级IOT大数据云平台建设经验,可提供全栈的大数据+云原生平台咨询方案,请持续关注本套博客。QQ邮箱地址:1120746959@qq.com,如有任何学术交流,可随时联系。
1. disk-based shard allocation 参数优化
- es在进行shard allocation的时候,会充分考虑每一个node的可用磁盘空间。
- cluster.routing.allocation.disk.threshold_enabled:默认是true,如果是false会禁用基于disk的考虑
- cluster.routing.allocation.disk.watermark.low:控制磁盘使用率的低水位,默认是85%,如果一个节点的磁盘空间使用率已经超过了85%,那么就不会分配shard给这个node了
- cluster.routing.allocation.disk.watermark.high:控制磁盘使用率的高水位,默认是90%,如果一个节点的磁盘空间使用率已经超过90%了,那么就会将这个node上的部分shard移动走
- cluster.info.update.interval:es检查集群中每个node的磁盘使用率的时间间隔,默认是30s
- cluster.routing.allocation.disk.include_relocations:默认是true,意味着es在计算一个node的磁盘使用率的时候,会考虑正在分配给这个node的shard。
2. shard allocation awareness参数优化
2.1 基本配置
- 如果在一个物理机上运行多个虚拟机,并且在多个虚拟机中运行了多个es节点,或者在多个机架上,多个机房,都有可能有多个es节点在相同的物理机上,或者在相同的机架上,或者在相同的机房里,那么这些节点就可能会因为物理机,机架,机房的问题,一起崩溃。
- 如果es可以感知到硬件的物理布局,就可以确保说,priamry shard和replica shard一定是分配到不同的物理机,或者物理机架,或者不同的机房,这样可以最小化物理机,机架,机房崩溃的风险
- shard allocation awareness可以告诉es我们的硬件架构,
./bin/elasticsearch -Enode.attr.rack_id=rack_one,也可以在elasticsearch.yml中设置这个机架id
cluster.routing.allocation.awareness.attributes: rack_id
node.attr.rack_id=rack_one
- 上面的两行设置里,第一行是设置机架id的属性名称,第二行是用那个机架id属性名称设置具体的机架id。如果启动两个node,都在一个机架上,此时创建一个有5个primary shard和5个replica shard的索引,此时shards会被分配到两个节点上。
- 如果再启动两个node,设置为另外一个机架,此时es会将shard移动到新的node上,去确保说,不会让primary shard和其replica shard在同一个机架上。但是如果机架2故障了,为了恢复集群,那么还是会在恢复的时候,将shards全部在机架1上分配的
- prefer local shard机制:在执行search或者get请求的时候,如果启用了shard awareness特性,那么es会尽量使用local shard来执行请求,也就是在同一个awareness group中的shard来执行请求,也就是说尽量用一个机架或者一个机房中的shard来执行请求,而不要跨机架或者跨机房来执行请求
可以指定多个awareness属性,比如机架id和机房名称,类似下面:
cluster.routing.allocation.awareness.attributes: rack_id,zone
2.2 强制性的感知
- 如果现在我们有两个机房,并且有足够的硬件资源来容纳所有的shard,但是可能每个机房的硬件只能容纳一半shard,不能容纳所有的shard。如果仅仅使用原始的感知特性,如果一个机房故障了,那么es会将需要恢复的shard全部分配给剩下的一个机房,但是剩下的那个机房的硬件资源并不足以容纳所有的shard。
- 强制感知特性会解决这个问题,因为这个特性会绝对不允许在一个机房内分配所有的shard
比如说,有一个感知属性叫做zone,有两个机房,zone1和zone2,看看下面的配置:
cluster.routing.allocation.awareness.attributes: zone
cluster.routing.allocation.awareness.force.zone.values: zone1,zone2
那么此时如果将2个node分配给zone1机房,然后创建一个索引,5个primary shard和5个replica shard,
但是此时只会在zone1机房分配5个primary shard,只有我们启动一批node在zone2机房,才会分配replica shard
2.4 shard allocation filtering
- shard allocation filtering可以让我们允许或者不允许某些index的shard分配给一些特殊的节点,典型的用途,就是如果我们要下线一些node,就可以用这个feature禁止shard分配给这些即将下线的node,而且我们还可以将这些即将下线的节点的shard移动到其他节点。
- 用下面的命令可以下线一个节点,因为就不允许将shard分配给这个节点了
PUT _cluster/settings
{
"transient" : {
"cluster.routing.allocation.exclude._ip" : "10.0.0.1"
}
}
2.5 node下线时的shard延迟分配
- 如果从集群中下线一个节点,master会做下面这些事情,这些操作可以保护集群不会丢失数据,因为会对每个shard都复制充足的replica shard
(1)如果那个节点上有primary shard,那么master会将那些primary shard在其他节点上的replica shard提升为primary shard
(2)分配新的replica shard来保证replica数量充足
(3)在剩下的各个node上进行shard rebalance,确保负载均衡
- 但是这个过程,可能会导致集群中出现很重的负载,包括网络负载和磁盘IO负载,如果那个下线的节点只是因为故障被下线,马上就会有新的节点来顶替它,那么这种立即执行的shard recovery过程是不需要的,考虑下面的场景:
(1)某个node跟集群丢失了网络连接
(2)master node将那个node上的primary shard对应的其他节点上的replica shard提升为primary shard
(3)master node分配新的replica shard到其他节点上
(4)每个新的replica shard都会通过网络传输一份primary shard的完整的副本数据
(5)很多shard都被移动到其他的node来让集群rebalance
(6)但是几分钟以后,那个丢失了网络连接的node又重新连接到了集群中
(7)master节点又要再次进行rebalance操作,因为需要将一些shard分配给那个node
- 其实如果master node也许只要等待几分钟,那么丢失的那个node自己会回来,丢失的shard也会自动恢复过来,因为数据都在节点的本地,不需要重新拷贝数据以及网络传输,这个过程是非常快速的
- index.unassigned.node_left.delayed_timeout,这个参数可以设置某个节点下线之后, 对应的replica shard被重新复制和分配的时间等待期,默认是1m,可以通过下面的命令来修改:
PUT _all/_settings
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "5m"
}
}
- 如果启用了delayed allocation之后,那么就会看到下面的场景:
(1)某个node丢失了网络连接
(2)master将那个node上的一些primary shard对应的其他node上的replica shard提升为primary shard
(3)master记录下来一条消息日志,这个primary shard的replica shard还没有重新分配和开始,被delayed了,会等待1m
(4)cluster会保持yellow状态,因为没有足够的replica shard
(5)那个丢失了的node在几分钟之后,如果回到了集群中
(6)缺失的那些replica shard会直接分配给那个node,使用其本地的数据即可
- 如果某个node确定了肯定不会再回到集群中,那么可以通过下面的命令,手动设置一下,直接不等待那个节点回来了
PUT _all/_settings
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "0"
}
}
2.6 索引恢复的优先级
- 没有被分配的shard都是按照优先级来分配的,有下面几个优先级,index.priority,索引的创建日期,索引名称
PUT index_3
{
"settings": {
"index.priority": 10
}
2.7 每个节点的shard数量
cluster.routing.allocation.total_shards_per_node,设置每个节点最多承载的shard数量,默认是无限制的
3 总结
生产部署还有很多工作要做,本文从初级思路切入,进行了问题的整合。
本套技术专栏作者(秦凯新)专注于大数据及容器云核心技术解密,具备5年工业级IOT大数据云平台建设经验,可提供全栈的大数据+云原生平台咨询方案,请持续关注本套博客。QQ邮箱地址:1120746959@qq.com,如有任何学术交流,可随时联系
秦凯新
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。