支持高可用性、高吞吐量部署

包含您的 Launchpad 蓝图的 URL

https://blueprints.launchpad.net/congress/+spec/high-availability-design

某些应用程序需要 Congress 具有高可用性 (HA)。某些应用程序需要 Congress 策略引擎能够处理大量的查询 (高吞吐量 - HT)。本提案描述了如何支持几种满足多种 HA 和 HT 需求的部署方案。

问题描述

本规范旨在解决三个主要问题

  1. Congress 目前无法提供高查询吞吐量,因为所有查询都由单个、单线程的策略引擎实例处理。

  2. 当其策略引擎不可用时,Congress 目前无法快速故障转移。

  3. 如果策略引擎和推送数据源驱动程序都崩溃,Congress 目前无法在重启或故障转移后恢复最新的数据状态。

提议的变更

实施所需的代码更改,并为以下参考部署创建部署指南。

所有 Congress 组件在单进程中的热备

  • 停机时间:~1 分钟(启动新的 Congress 实例并从头开始导入数据)

  • 可靠性:在停机期间,操作执行可能会丢失。

  • 性能考虑:单进程查询吞吐量

  • 代码更改:最少

活动-活动 PE 复制,DSDs 热备

以活动-活动配置运行 N 个 Congress 策略引擎实例。每个物理数据源发布的数据都通过 oslo-messaging 发送到所有策略引擎。

+-------------------------------------+      +--------------+
|       Load Balancer (eg. HAProxy)   | <----+ Push client  |
+----+-------------+-------------+----+      +--------------+
     |             |             |
PE   |        PE   |        PE   |        all+DSDs node
+---------+   +---------+   +---------+   +-----------------+
| +-----+ |   | +-----+ |   | +-----+ |   | +-----+ +-----+ |
| | API | |   | | API | |   | | API | |   | | DSD | | DSD | |
| +-----+ |   | +-----+ |   | +-----+ |   | +-----+ +-----+ |
| +-----+ |   | +-----+ |   | +-----+ |   | +-----+ +-----+ |
| | PE  | |   | | PE  | |   | | PE  | |   | | DSD | | DSD | |
| +-----+ |   | +-----+ |   | +-----+ |   | +-----+ +-----+ |
+---------+   +---------+   +---------+   +--------+--------+
     |             |             |                 |
     |             |             |                 |
     +--+----------+-------------+--------+--------+
        |                                 |
        |                                 |
+-------+----+   +------------------------+-----------------+
|  Oslo Msg  |   | DBs (policy, config, push data, exec log)|
+------------+   +------------------------------------------+
  • 停机时间:查询 < 1s,响应式执行 ~2s

  • 部署考虑事项

    • 集群管理器(例如 Pacemaker + Corosync)可用于管理热备

    • 不需要全局领导者选举

  • 性能考虑

    • 多进程、多节点查询吞吐量

    • 没有冗余的数据拉取负载到数据源

    • DSDs 节点与 PE 分离,允许高负载 DSDs 更平稳地运行,并避免影响 PE 性能。

    • PE 节点在配置上是对称的,使其易于均匀地负载均衡。

  • 代码更改

    • 新的同步器和框架,以支持两种不同的节点类型:API+PE 节点和所有 DSDs 节点

详情

  • 数据源驱动程序 (DSDs)

    • 每个物理数据源一个数据源驱动程序。

    • 所有 DSDs 运行在单个 DSE 节点(进程)中

    • 推送 DSDs:可选地将数据持久化在推送数据 DB 中,以便在需要时可以获得新的快照。

  • 策略引擎 (PE)

    • 以活动-活动配置复制策略引擎。

    • 策略通过策略 DB 在 PE 实例之间同步

    • 每个实例都订阅 oslo-messaging 上的相同数据。

    • 响应式执行:所有 PE 实例都会启动响应式策略操作,但每个 DSD 本地选择一个“领导者”来“监听”。DSD 忽略由所有其他 PE 实例发起的执行请求。

      • 每个 PE 实例计算所需的响应式执行操作,并通过 oslo-messaging 发起相应的执行请求。

      • 每个 DSD 本地选择 PE 实例作为领导者(例如,DSD 听到的第一个实例,或者在对称节点部署中与 DSD 在同一节点上的 PE 实例),并且仅执行来自该 PE 的请求。

      • 如果与领导者的心跳联系丢失,DSD 会选择新的领导者。

      • 每个 PE 实例不知道自己是否是“领导者”

  • API

    • 每个节点都有一个活动的 API 服务

    • 每个 API 服务将 PE 的请求路由到其关联的节点内 PE

    • 对任何其他服务的请求(例如,获取数据源状态)路由到 DSE2,该服务将由某个节点上的某个活动的实例提供。

    • 详细信息:- 在 API 模型中,用条件替换每个 invoke_rpc

      • 如果目标是策略引擎,则目标同节点 PE,例如::self.invoke_rpc( caller, ‘get_row_data’, args, server=self.node.pe.rpc_server)

      • 否则,invoke_rpc 保持不变,路由到 DSE2,例如::self.invoke_rpc(caller, ‘get_row_data’, args)

  • 负载均衡器

    • 第 7 层负载均衡器(例如 HAProxy)在节点之间分配传入的 API 调用(每个节点运行 API 服务)。

    • 负载均衡器可以选择配置为使用粘性会话,将每个 API 调用者固定到特定节点。此配置避免了回到过去体验。

  • 可以使用标准解决方案(例如集群 LB、Galera MySQL 集群、HA rabbitMQ)使外部组件(负载均衡器、DB 和 oslo 消息总线)具有高可用性

处理故障转移期间丢失的操作

当领导者失败(全局或局部)时,需要时间来检测故障并任命新的领导者。在故障转移期间,预期要触发的响应式执行操作可能会丢失。讨论了以下四种提议的方法。

  • 容忍故障转移期间丢失的操作:对于某些应用程序,在故障转移期间丢失操作是可以接受的。

  • 在故障转移后重新执行最近的操作

    • 每个 PE 实例都记住其最近的操作请求(包括从属 PE 计算但未发送的请求)

    • 在故障转移时,DSD 从新的领导者请求最近的操作请求并执行它们(在某个时间窗口内)

    • 在故障转移时预计会重复执行。

  • 在故障转移后重新执行最近的不匹配操作(可能的未来工作)

    • 我们可以尝试将新的领导者的最近操作请求与已经执行的请求进行匹配,并仅额外执行那些不匹配的操作,从而减少故障转移时重复执行的次数。

    • DSD 将所有最近成功执行的操作请求记录在 DB 中

    • 请求匹配可以通过以下信息的组合来完成

      • 请求的操作

      • 请求的时间戳

      • 触发操作的数据更新的序列号

      • 触发操作的完整派生树

    • 匹配不完美,但仍然有帮助

  • 记录和重放数据更新(可能的未来工作)

    • 记录来自每个数据源的每个数据更新,并让新的领导者重放之前领导者停止的地方的更新,以生成所需的动作请求。

    • 传输可以直接支持日志记录,也可以通过额外的 DB 支持

      • kafka 天然支持这种模式

      • 直接使用 oslo-messaging + RabbitMQ 很难实现

  • 无领导者去重(可能的未来工作)

    • 如果为故障转移后重新执行最近的不匹配操作实现了非常好的匹配方法,那么就可以进一步操作,并始终以这种模式运行。

    • 每个传入的操作请求都与所有最近执行的操作请求进行匹配。

      • 如果匹配,则丢弃。

      • 如果不匹配,则执行。

    • 消除了选择领导者(全局或局部)的需要,并提高了故障转移速度

我们建议首先支持前两种选项(部署者选择)。更复杂的方法可以在未来的工作中实现和支持。

备选方案

我们首先讨论在详细介绍几种替代部署之前的主要决策点。

对于 PE 的活动-活动复制,以下是主要决策点

  1. 节点配置

  • 选项

    1. 单节点类型(每个节点都有 API+PE+DSDs)。

    2. 两种节点类型(API+PE 节点,所有 DSDs 节点)。[提议的目标]

    3. 多种节点类型(API+PE 节点,所有 DSDs 在单独的节点中)。

  • 讨论:多种节点类型配置最灵活,对高负载 DSDs 的支持最好,但它也需要最多的开发和部署工作。我们建议以两种节点类型配置为目标,因为它为高负载 DSDs 提供了合理的支持,同时保持了开发和部署的复杂性较低。

  1. 操作执行的全局与局部领导者

  • 选项

    1. 全局领导者:Pacemaker 在 PE 实例中任命一个全局领导者;只有领导者发送操作执行请求。

    2. 局部领导者:每个 PE 实例都发送操作执行请求,但每个接收 DSD 本地选择一个“领导者”来监听。[提议的目标]

  • 讨论:由于对于给定的数据源只有一个活动的 DSD,因此在 PE 实例发送响应式执行操作执行请求时,在 DSD 中本地选择“领导者”是自然的选择。我们建议以局部领导者风格为目标,因为它避免了与全局领导者选举相关的开发和部署复杂性。此外,由于所有 PE 实例都执行响应式执行并发送操作执行请求,因此冗余性在 PE 实例发生故障时为响应式执行提供零中断的可能性。

  1. DSD 冗余

  • 选项

    1. 热备:在给定时间只有一个 DSD 集合正在运行;备份实例准备启动。

    2. 热备:多个实例正在运行,但只有一组是活动的。

    3. 活动-活动:多个实例处于活动状态。

  • 讨论

    • 对于拉取 DSDs,我们建议以热备为目标,因为热启动时间很短(秒),相对于数据拉取的频率而言。

    • 对于推送 DSDs,热备通常就足够了,除非在故障转移期间需要亚秒级延迟的用例。这些用例需要推送 DSDs 的活动-活动复制。但是,即使对推送 DSDs 进行活动-活动复制,操作执行中未解决的问题也阻止我们提供故障转移期间亚秒级的端到端延迟(推送数据到触发的操作执行)。由于我们目前无法实现推送 DSDs 的活动-活动复制的好处,因此我们建议以热备部署为目标,将活动-活动复制作为潜在的未来工作。

活动-活动 PE 复制,DSDs 热备,所有组件在单个节点中

运行 N 个单进程 Congress 实例。

由 Pacemaker 选择一个实例作为领导者。只有领导者具有活动的数据源驱动程序(拉取数据、接受推送数据和接受来自 API 服务的 RPC 调用),但所有实例都订阅并处理 oslo-messaging 上的数据。查询在实例之间负载均衡。

+-----------------------------------------------------------------------+
|                     Load Balancer (eg. HAProxy)                       |
+----+------------------------+------------------------+----------------+
     |                        |                        |
     |           leader       |         follower       |         follower
+---------------------+  +---------------------+  +---------------------+
| +-----+ +---------+ |  | +-----+ +---------+ |  | +-----+ +---------+ |
| | API | |DSD (on) | |  | | API | |DSD (off)| |  | | API | |DSD (off)| |
| +-----+ +---------+ |  | +-----+ +---------+ |  | +-----+ +---------+ |
| +-----+ +---------+ |  | +-----+ +---------+ |  | +-----+ +---------+ |
| | PE  | |DSD (on) | |  | | PE  | |DSD (off)| |  | | PE  | |DSD (off)| |
| +-----+ +---------+ |  | +-----+ +---------+ |  | +-----+ +---------+ |
+---------------------+  +---------------------+  +---------------------+
     |                        |                        |
     |                        |                        |
     +---------+--------------+-------------------+----+
               |                                  |
               |                                  |
+--------------+-----------+ +--------------------+---------------------+
|         Oslo Msg         | | DBs (policy, config, push data, exec log)|
+--------------------------+ +------------------------------------------+
  • 停机时间:查询 < 1s,响应策略 ~2s

  • 部署考虑事项

    • 需要集群管理器(Pacemaker)和集群消息传递(Corosync)

    • 相对简单的 Pacemaker 部署,因为每个节点都是相同的

    • 需要领导者选举(由 Pacemaker+Corosync 处理)

    • 易于启动新的 DSD(进行 API 调用,所有实例通过 DB 同步)

  • 性能考虑

    • [优点] 多进程查询吞吐量

    • [优点] 没有冗余的数据拉取负载到数据源

    • [缺点] 如果某些数据源驱动程序需求量很大(例如遥测数据),则性能可能会受到影响,如果部署在与 Congress 其他组件相同的 python 进程中。

    • [缺点] 由于领导者具有活动 DSDs 的额外负载,PE 性能可能会降低,从而使在实例之间均匀负载均衡更加困难。

  • 代码更改

    • 添加 API 调用以指定节点为领导者或从属者

    • 自定义资源代理,允许 Pacemaker 启动、停止、提升和降级 Congress 实例

详细信息
  • 拉取数据源驱动程序(拉取 DSD)

    • 每个物理数据源一个活动的数据源驱动程序。

    • 只有领导者节点具有活动的 DSDs(活动轮询循环和活动 RPC 服务器)

    • 节点发生故障时,新的领导者节点激活 DSDs。

  • 推送数据源驱动程序(推送 DSD)

    • 每个物理数据源一个活动的数据源驱动程序。

    • 只有领导者节点具有活动的 DSDs(活动 RPC 服务器)

    • 节点发生故障时,新的领导者节点激活 DSDs。

    • 将数据持久化在推送数据 DB 中,以便可以获得新的快照。

  • 策略引擎 (PE)

    • 以活动-活动配置复制策略引擎。

    • 策略通过策略 DB 在 PE 实例之间同步

    • 每个实例都订阅 oslo-messaging 上的相同数据。

    • 响应式执行:请参阅后面的“活动-活动部署的响应式执行架构”

  • API

    • 添加新的 API 调用以指定接收节点为领导者或从属者。调用必须在返回之前完成所有任务(例如,启动/停止 RPC)

    • 每个节点都有一个活动的 API 服务

    • 每个 API 服务将 PE 的请求路由到其关联的节点内 PE,绕过 DSE2。

    • 对任何其他服务的请求(例如,获取数据源状态)路由到 DSE2,该服务将由某个节点上的某个活动的实例提供。

    • 详细信息:- 在 API 模型中,用条件替换每个 invoke_rpc

      • 如果目标是策略引擎,则目标同节点 PE,例如::self.invoke_rpc( caller, ‘get_row_data’, args, server=self.node.pe.rpc_server)

      • 否则,invoke_rpc 保持不变,路由到 DSE2,例如::self.invoke_rpc(caller, ‘get_row_data’, args)

  • 负载均衡器

    • 第 7 层负载均衡器(例如 HAProxy)在节点之间分配传入的 API 调用(每个节点运行 API 服务)。

    • 负载均衡器可以选择配置为使用粘性会话,将每个 API 调用者固定到特定节点。此配置避免了回到过去体验。

  • 每个 DseNode 由集群管理器(例如 Pacemaker)监控和管理

  • 可以使用标准解决方案(例如集群 LB、Galera MySQL 集群、HA rabbitMQ)使外部组件(负载均衡器、DB 和 oslo 消息总线)具有高可用性

  • 使用 Pacemaker 进行全局领导者选举

    • 资源代理包含告诉 Congress 实例它是领导者还是从属者的脚本。

    • Pacemaker 决定将哪个 Congress 实例提升为领导者(主节点)。

    • Pacemaker 通过资源代理提升(降级)适当的 Congress 实例为领导者(从属者)。

    • 围栏

      • 如果领导者节点停止响应,并且新的节点被提升为领导者,则有可能未响应的节点仍在执行工作(例如,监听 oslo-messaging,发出操作请求)。

      • 如果一段时间内有多个 Congress 节点执行领导者工作,通常不是灾难。(潜在影响可能包括:重复的操作请求和冗余的数据源拉取)

      • Pacemaker 可以配置为使用严格的围栏和 STONITH 进行需要它的部署。(部署者选择) http://clusterlabs.org/doc/en-US/Pacemaker/1.1/html-single/Pacemaker_Explained/#_what_is_stonith

    • 在网络分区的情况下

活动-活动 PE 复制,DSDs 热备,每个 DSD 在自己的节点中

以活动-活动配置运行 N 个 Congress 策略引擎实例。每个物理数据源发布的数据都通过 oslo-messaging 发送到所有策略引擎。

+-------------------------------------+
|       Load Balancer (eg. HAProxy)   |
+----+-------------+-------------+----+
    |             |             |
    |             |             |
+---------+   +---------+   +---------+
| +-----+ |   | +-----+ |   | +-----+ |
| | API | |   | | API | |   | | API | |
| +-----+ |   | +-----+ |   | +-----+ |
| +-----+ |   | +-----+ |   | +-----+ |
| | PE  | |   | | PE  | |   | | PE  | |
| +-----+ |   | +-----+ |   | +-----+ |
+---------+   +---------+   +---------+
    |             |             |
    |             |             |
    +------------------------------------------+-----------------+
    |             |             |              |                 |
    |             |             |              |                 |
+----+-------------+-------------+---+  +-------+--------+  +-----+-----+
|              Oslo Msg              |  |  Push Data DB  |  |    DBs    |
+----+-------------+-------------+---+  ++---------------+  +-----------+
    |             |             |       |      (DBs may be combined)
+----------+   +----------+     +----------+
| +------+ |   | +------+ |     | +------+ |
| | Poll | |   | | Poll | |     | | Push | |
| | Drv  | |   | | Drv  | |     | | Drv  | |
| | DS 1 | |   | | DS 2 | |     | | DS 3 | |
| +------+ |   | +------+ |     | +------+ |
+----------+   +----------+     +----------+
    |             |                 |
+---+--+      +---+--+          +---+--+
|      |      |      |          |      |
| DS 1 |      | DS 2 |          | DS 3 |
|      |      |      |          |      |
+------+      +------+          +------+
  • 停机时间:查询 < 1s,响应策略 ~2s

  • 部署考虑事项

    • 需要集群管理器(Pacemaker)和集群消息传递(Corosync)

    • 更复杂的 Pacemaker 部署,因为有很多不同类型的节点

    • 不需要全局领导者选举(但这并不是一个很大的节省,如果我们正在运行 Pacemaker+Corosync 无论如何)

  • 性能考虑

    • [优点] 多进程查询吞吐量

    • [优点] 没有冗余的数据拉取负载到数据源

    • [优点] 每个 DSD 可以在自己的节点上运行,允许高负载 DSDs 更平稳地运行,并避免影响 PE 性能。

    • [优点] PE 节点在配置上是对称的,使其易于均匀地负载均衡。

  • 代码更改

    • 新的同步器和框架和 DB 模式,以支持每个节点的配置

所有组件在单进程中的热备

运行 N 个单进程 Congress 实例,如以下建议:https://blueprints.launchpad.net/congress/+spec/basic-high-availability

一个浮动 IP 指向主实例,该实例处理所有查询和请求,并在主实例关闭时故障转移。所有实例都导入和处理数据以保持最新状态。

+---------------+
|  Floating IP  | - - - - - - + - - - - - - - - - - - -+
+----+----------+             |                        |
     |
     |                        |                        |
+---------------------+  +---------------------+  +---------------------+
| +-----+ +---------+ |  | +-----+ +---------+ |  | +-----+ +---------+ |
| | API | |   DSD   | |  | | API | |   DSD   | |  | | API | |   DSD   | |
| +-----+ +---------+ |  | +-----+ +---------+ |  | +-----+ +---------+ |
| +-----+ +---------+ |  | +-----+ +---------+ |  | +-----+ +---------+ |
| | PE  | |   DSD   | |  | | PE  | |   DSD   | |  | | PE  | |   DSD   | |
| +-----+ +---------+ |  | +-----+ +---------+ |  | +-----+ +---------+ |
| +-----------------+ |  | +-----------------+ |  | +-----------------+ |
| |     Oslo Msg    | |  | |     Oslo Msg    | |  | |     Oslo Msg    | |
| +-----------------+ |  | +-----------------+ |  | +-----------------+ |
+---------------------+  +---------------------+  +---------------------+
           |                        |                      |
           |                        |                      |
+----------+------------------------+----------------------+------------+
|                             Databases                                 |
+-----------------------------------------------------------------------+
  • 停机时间:查询 < 1s,响应策略 ~2s

  • 功能限制

    • 对操作执行的有限支持:每次操作执行都会触发 N 次)

    • 对推送驱动程序的有限支持:推送更新仅主实例(可选的 DB 同步到非主实例)

  • 部署考虑事项

    • 非常容易部署。无需集群管理器。只需启动 N 个独立的 Congress 实例(进程内消息传递)并设置浮动 IP。

  • 性能考虑

    • 性能特征与单实例 Congress 相似

    • [缺点] 单进程查询吞吐量(可选负载均衡器可以添加到实例之间的查询之间)

    • [缺点] 由于重复的数据源驱动程序拉取相同的数据 N 次,因此数据源上的额外负载

  • 代码更改

    • (可选) 推送数据到非主实例的 DB 同步

策略

不适用

策略动作

不适用

数据源

不适用

数据模型影响

无影响

REST API 影响

无影响

安全影响

与非 HA 分布式部署相比,没有发现重大的安全影响。

通知影响

无影响

其他最终用户影响

提议的更改通常对最终用户是透明的。一些例外情况

  • 不同的 PE 实例在数据和策略上可能不同步(最终一致性)。通常通过使每个用户坚持特定的 PE 实例来使问题对最终用户透明。但是,如果 PE 实例关闭,最终用户会到达不同的实例,并且可能会遇到不同步的伪影。

性能影响

  • 在单节点部署中,通常没有性能影响。

  • 由于多节点部署所需的网络通信而增加的延迟

  • 为了更平滑的故障转移,如果动作执行被持续记录,可能会增加反应式强制执行的延迟

  • PE 复制可以实现更高的查询吞吐量

其他部署者影响

  • 新的配置设置

    • 将 DSE 节点类型设置为以下之一

      • PE+API 节点

      • 一个 DSDs 节点

      • 一体化节点(向后兼容的默认设置)

    • 设置反应式强制执行故障转移策略

      • 不要尝试恢复丢失的动作(向后兼容的默认设置)

      • 故障转移后,重复最近的动作请求

      • 故障转移后,重复最近的动作请求,这些请求未与记录的执行匹配

  • 提议的更改对现有的单节点部署没有影响。预计 100% 向后兼容。

  • 只有当部署者选择设置具有适当配置的多节点部署时,更改才会生效。

开发者影响

未发现重大影响。

实现

负责人

工作将被分配并通过 launchpad 进行跟踪。

工作项

具有顺序依赖性的项目

  1. API 路由。更改 API 路由以支持主动-主动 PE 复制,将 PE 绑定的 RPC 路由到与接收 API 服务器相同的节点上的 PE 实例。预计更改将限制在 congress/api/* 中

  2. 反应式强制执行。更改 datasource_driver.py:ExecutionDriver 类以处理来自复制的 PE 节点的动作执行请求(本地选择要遵循的领导者)

  3. (低优先级)缓解丢失的动作。

    • 实施更改以缓解 DSD 故障转移期间丢失的动作

    • 实施更改以缓解 PE 故障转移期间丢失的动作

没有依赖性的项目

  • 推送数据持久化。更改 datasource_driver.py:PushedDataSourceDriver 类以支持推送数据的持久化。还需要相应的数据库更改。

  • (潜在)动作执行请求的无领导者去重。

  • HA 指南。创建 HA 指南,概述不同部署类型的属性和权衡。

  • 部署指南。为主动-主动 PE 复制创建部署指南

依赖项

测试

我们建议为以下场景添加 tempest 测试:- 杀死最多 (N - 1) 个 PE 节点 - 之前杀死的 PE 节点重新加入。 - 杀死并重启 DSDs 节点,可能在杀死 PE 节点的同时。

可以手动测试脑裂场景。

文档影响

为每个支持的参考部署添加部署指南。对现有文档没有影响。