Charms 中的服务重启控制¶
Openstack charms 会持续响应来自相关应用程序的钩子事件,这些事件经常导致配置更改和随后的服务重启。 在这些应用程序大规模部署的情况下,这些服务同时重启可能会导致 (a) 服务中断和 (b) 对外部应用程序(例如数据库或 rabbitmq 服务器)造成过大的负载。 为了缓解这些影响,我们希望引入一种机制,允许 charms 应用可控的模式来控制它们重启服务的方式。
问题描述¶
一个出现这种行为问题的示例场景是,我们有大量,例如 1000 个,nova-compute 单位都连接到同一个 rabbitmq 服务器。 如果我们进行配置更改,例如在该应用程序上启用调试日志记录,这将导致所有 nova-* 服务在每个计算主机上同时重启,进而会在 rabbit 服务器上产生巨大的负载峰值,并使所有计算操作阻塞,直到这些服务恢复。 这显然也可能对依赖 rabbitmq 的其他应用程序产生其他连锁影响。
我们可以采用多种方法来解决这个问题,但对于这个提案,我们选择简单的方法,即尝试使用应用程序单位已经可用的所有信息,再加上一些用户配置,让单位决定如何最好地执行这些操作。
应用程序的每个单位已经可以访问一些描述其相对于其环境的信息,例如,每个单位都有一个唯一的 ID,并且一些应用程序具有对等关系,可以为其提供有关其邻居的信息。 使用这些信息,再加上 charm 上的额外配置选项来调整时间,我们可以让操作员能够使用基本的数学运算和不使用 juju api 调用来控制跨单位的服务重启。
例如,假设一个应用程序单位知道它的 ID 是 215,并且用户通过配置提供了两个选项:模数 2 和偏移量 10。 我们可以这样做
time.sleep((215 % 2) * 10)
当应用于所有单位时,这将导致集群的 50% 在其余单位重启服务后的 10 秒钟重启其服务。 这应该可以减轻集群范围内的同步重启造成的压力,确保集群的一部分始终处于响应状态,并使重启发生得更快。
如上所述,我们将需要为支持此逻辑的任何 charm 提供两个新的配置选项
service-restart-offset(默认值为 10)
- service-restart-modulo(默认值为 1,以便默认行为与
之前相同)
重启逻辑将跳过任何未实现这些选项的 charms。
随着时间的推移,一些单位可能会从集群中删除并重新添加回来,从而导致非连续的单位 ID。 虽然对于大规模部署的应用程序,这可能不会产生显著影响,因为后续的添加和删除将相互抵消,但它仍然可能是一个问题,因此我们将检查应用程序上是否存在对等关系,如果存在,我们将使用该关系中的信息来规范化单位 ID,然后再计算延迟。
最后,我们必须考虑当 charm 用于升级 Openstack 服务时如何行为,无论是直接使用配置(“大爆炸”)还是使用在 charm 上定义的动作。 对于一次升级所有服务的情况,我们将让操作员设置/取消设置偏移参数。 对于使用动作的情况,并且可能只有一部分单位正在升级,我们将忽略控制设置,即不会使用延迟。
提议的变更¶
为了实现此更改,我们将扩展 Openstack charms 中实现的 restart_on_change() 装饰器,以便在停止/启动或重启服务时,它将包含 time.sleep(delay),其中延迟是从单位 ID 与两个新的配置选项结合计算得出的:service-restart-offset 和 service-restart-modulo。 此计算将在 contrib.openstack 中实现的新函数中完成,其输出将传递到 restart_on_changed() 装饰器。
由于使用了装饰器,我们无需担心同一服务的多次重启。 但是,我们需要考虑如何在手动执行停止/启动和重启时应用偏移量,例如在由动作管理的升级处理程序中。
备选方案¶
无
实现¶
负责人¶
- 主要负责人
hopem
Gerrit Topic¶
对于与此规范相关的补丁,请使用 Gerrit 主题“controlled-service-restarts”。
git-review -t controlled-service-restarts
工作项¶
实现 charmhelpers 的更改
同步到 openstack charms 并添加新的配置选项
仓库¶
无
文档¶
这些新设置将在 charm 的 config.yaml 中以及在 charm 部署指南中得到适当的记录。
安全性¶
无
测试¶
将在 charm-helpers 中提供单元测试,并将更新功能测试以包含启用此功能的配置。还需要进行规模测试以证明有效性并确定最佳默认值。
依赖项¶
无