SolrCloud Autoscaling 自动添加副本
前言 问题描述
起因是这样的,我在本地调试 Solr 源码(版本 7.7.3),用 IDEA 以 solrcloud 方式启动了 2 个 Solr 服务,如下所示:
上图的启动参数 VM Options 如下:
-DzkHost=127.0.0.1:2181/solr7 -Djetty.port=8985 -Duser.timezone=UTC -Djetty.home=/Workspace/source-code/solr/solr/server -Dsolr.solr.home=/Workspace/Solr/Solr7_SolrHome_8985 -Dsolr.install.dir=/Workspace/source-code/solr/solr -Dsolr.log.dir=/Workspace/Solr/Solr7_SolrHome_8985/logs -Dsolr.log=/Workspace/Solr/Solr7_SolrHome_8985/logs/solr.log
solrcloud_8986 启动参数和上面的类似,只需更改端口号
之后我在本地创建了一个 MOVIE
的 Collection,创建的时候表单内容如下:
上面的页面是我们自己的搜索中台创建 Collection 的表单页面,当时我没注意到 autoAddReplicas 参数设置了 true,当创建好 Collection 后,系统会自动分配好 shard 和 副本到对应的 Solr 节点上,如下所示:
之后我把 Shard1 和 Shard2 对应的副本全部删除,在8985端口的Solr节点上创建这两个 Shard 的 TLOG 类型副本,之后在 8986 节点上创建 Shard1 的 PULL 类型副本,如下所示:
起初我本来想调试查看 PULL 副本同步 TLOG 副本数据的代码,结果当我断点调试的时候发现 PULL 类型的副本没了,系统自动的在 8985 端口的 Solr 节点创建了一个 NRT 类型的副本。遇到这种情况我就比较纳闷,于是我重复上面的步骤,把 8986 端口的 Solr 节点 down 掉,观察后面的现象。当我关闭 8986 端口后,节点状态的变化如下:
可以看到此时 8986 端口的 Solr 节点状态已变成 down
,之后耐心等待~。大约 2 min 左右,Shard 副本信息变成了如下结果:
我们可以看到此时原先的 PULL 副本没有了,取而代之的新增了一个 NRT 副本,而且该副本创建在 8985 端口的 Solr 节点上。
后来我仔细审视整个流程并调试源码,发现是我创建 Solr Collection 的时候无意将 autoAddReplica
设置了 true,这个参数默认应该是 false,那么这个参数有什么作用,为什么会发生这个现象,这里就要提到 SolrCloud 的 Autoscaling 自动添加副本的功能了。
SolrCloud Autoscaling 自动添加副本
官方文档地址:https://solr.apache.org/guide/7_7/solrcloud-autoscaling-auto-add-replicas.html#the-autoaddreplicas-parameter
Solr 提供了一种方法,当活动副本( active replicas )数量低于创建集合时指定的复制因子(replicationFactor
)时,自动为集合添加副本。
这里就要说到之前我创建 Collection 时,填写的 replicationFactor
为 2,这个参数的意思如下:
Solr 官方文档地址:https://solr.apache.org/guide/7_7/collections-api.html
这个参数默认是 1,而且其默认创建的就是 NRT 类型副本,而我观察到的现象是如果我的一个 Shard 有多副本,当其他机器的副本不可用时,会扩展出一个新的副本来,而没有创建过其他副本的 Shard2 并不会拓展出来新的副本。发生这个现象的原因就是我在创建 Collection 的时候将 addAutoReplicas
参数设置成了 true,其官文文档如下:
后面我又创建了一个新的 Collection 并将 autoAddReplicas
设置成了 false,重复之前的操作的步骤,等待 2 min 后,IDEA 中的 8985 端口的 Solr 节点打印出了如下日志:
中台页面可以看到:
原 PULL 类型的副本没有消失,而且也没有创建出新的副本。
autoAddReplicas 参数
在创建 Collection 的时候将布尔值 autoAddReplicas
参数传递给 Collection API 的 CREATE 命令,就会开启SolrCloud Autoscaling 自动添加副本的功能。接口如下:
创建启用 autoAddReplicas 的集合:
http://localhost:8983/solr/admin/collections?action=CREATE&name=my_collection&numShards=1&replicationFactor=5&autoAddReplicas=true
MODIFYCOLLECTION 命令可用于为任何集合启用或禁用此功能,接口如下:
修改集合以禁用 autoAddReplicas
http://localhost:8983/solr/admin/collections?action=MODIFYCOLLECTION&collection=my_collection&autoAddReplicas=false
在 ZooKeeper 中,如下节点可以看到集合的状态信息:
比如上图 autoAddReplicas
为 false,当我请求:http://localhost:8985/solr/admin/collections?action=MODIFYCOLLECTION&collection=MOVIE&autoAddReplicas=true
接口的时候,其值就会变为 true:
.autoAddReplicas 触发器
在上面的场景中,每次 8986 端口 Solr 节点 down 掉后再过 2 min 之后才会触发新增副本的操作,这个时间又是在哪里配置的?
在 Solr 中,当任何集合启用 autoAddReplicas 功能时,将自动创建名为 .autoAddReplicas 的触发器。
一个触发器就足以服务于所有启用此功能的集合。.autoAddReplicas 触发器监控从集群中丢失的节点,并使用默认的触发器动作来创建新的副本,以替换那些由丢失节点托管的副本。如果旧节点重新上线,它会卸载被移动的副本,该节点将根据需要自由托管其他副本。
由于该触发器为所有集合提供 autoAddReplicas 功能,因此可以使用挂起触发器和恢复触发器的自动扩展 API 命令,通过一次 API 调用为所有集合禁用和启用此功能。
为所有集合挂起 autoAddReplicas 功能
{"suspend-trigger": {"name" : ".autoAddReplicas"}
}
为所有集合恢复 autoAddReplicas 功能
{"resume-trigger": {"name" : ".autoAddReplicas"}
}
请求的 url 为:
curl -X POST -H "Content-Type: application/json" -d '{"suspend-trigger": {"name": ".auto_add_replicas"}
}' "http://localhost:8985/solr/admin/autoscaling"# 响应如下:
{"responseHeader":{"status":0,"QTime":236},"changed":[".auto_add_replicas"],"result":"success","WARNING":"This response format is experimental. It is likely to change in the future."}---curl -X POST -H "Content-Type: application/json" -d '{"resume-trigger": {"name" : ".auto_add_replicas"}
}' "http://localhost:8985/solr/admin/autoscaling"# 响应如下:
{"responseHeader":{"status":0,"QTime":121},"changed":[".auto_add_replicas"],"result":"success","WARNING":"This response format is experimental. It is likely to change in the future."}
在 ZooKeeper 中的 autoscaling.json 也可以看到更改,如下所示:
上面截图可以看到 waitFor
被设置成了 120(单位是秒),这也是为什么节点 down 掉 2min 后才会新增副本,关于 autoscaling.json 的解释如下:
在 SolrCloud 中,autoscaling.json
是一个配置文件,用于定义如何自动扩展集群资源以应对不同的事件。内容如下:
{"triggers": {".auto_add_replicas": {"name": ".auto_add_replicas","event": "nodeLost","waitFor": 120,"enabled": "true","actions": [{"name": "auto_add_replicas_plan","class": "solr.AutoAddReplicasPlanAction"},{"name": "execute_plan","class": "solr.ExecutePlanAction"}]},".scheduled_maintenance": {"name": ".scheduled_maintenance","event": "scheduled","startTime": "NOW","every": "+1DAY","enabled": true,"actions": [{"name": "inactive_shard_plan","class": "solr.InactiveShardPlanAction"},{"name": "inactive_markers_plan","class": "solr.InactiveMarkersPlanAction"},{"name": "execute_plan","class": "solr.ExecutePlanAction"}]}},"listeners": {".auto_add_replicas.system": {"beforeAction": [],"afterAction": [],"stage": ["STARTED","ABORTED","SUCCEEDED","FAILED","BEFORE_ACTION","AFTER_ACTION","IGNORED"],"trigger": ".auto_add_replicas","class": "org.apache.solr.cloud.autoscaling.SystemLogListener"},".scheduled_maintenance.system": {"beforeAction": [],"afterAction": [],"stage": ["STARTED","ABORTED","SUCCEEDED","FAILED","BEFORE_ACTION","AFTER_ACTION","IGNORED"],"trigger": ".scheduled_maintenance","class": "org.apache.solr.cloud.autoscaling.SystemLogListener"}},"properties": {}
}
Triggers 部分
.auto_add_replicas 触发器
- name:触发器的名称,.auto_add_replicas。
- event:触发这个触发器的事件类型,这里是 nodeLost,意味着当集群中的节点丢失时触发。
- waitFor:在执行任何操作前等待的时间(秒),这里设置为 120 秒,以便在节点可能只是暂时不可达而非永久丢失的情况下,给予系统一定的恢复时间。
- enabled:指示触发器是否启用。
- actions:
- auto_add_replicas_plan:定义了当触发器被触发时要执行的具体行动,使用 solr.AutoAddReplicasPlanAction 类,这个动作负责计划在其他节点上创建丢失节点上副本的替代副本。
- execute_plan:执行上一步计划的动作,使用
solr.ExecutePlanAction
类。
.scheduled_maintenance 触发器
- name:触发器的名称,.scheduled_maintenance。
- event:事件类型为 scheduled,表示这是一个根据计划进行的定期任务。
- startTime:计划任务开始的时间,这里设置为 NOW,表示立即开始。
- every:触发频率,这里是 +1DAY,表示每天执行一次。
- enabled:此触发器是否启用。
- actions:
- inactive_shard_plan:使用
solr.InactiveShardPlanAction
类,可能涉及对某些 shard 进行维护或使其暂时不活跃。 - inactive_markers_plan:使用
solr.InactiveMarkersPlanAction
类,处理与维护相关的标记。 - execute_plan:执行上述计划的动作。
- inactive_shard_plan:使用
Listeners 部分
.auto_add_replicas.system 和 .scheduled_maintenance.system 监听器
这些监听器用于记录系统日志,并在特定的阶段对触发器活动进行反应。
- beforeAction 和 afterAction:分别在动作执行前后的监听器响应,这里没有具体的动作定义。
- stage:定义监听器应响应的各种阶段,如 STARTED, ABORTED, SUCCEEDED, FAILED 等,这有助于跟踪每个操作的生命周期。
- trigger:关联的触发器名称。
- class:处理监听事件的类,这里是 org.apache.solr.cloud.autoscaling.SystemLogListener,用于将自动扩展事件记录到系统日志。
properties 部分
通常这个部分可以用来定义一些全局属性或默认值。
参考文档:https://solr.apache.org/guide/7_7/solrcloud-autoscaling-auto-add-replicas.html
部分断点截图: