通知转发(至 Zaqar 等系统)

https://blueprints.launchpad.net/searchlight/+spec/notification-forwarding

此功能增加了将 Searchlight 消耗的索引通知转发到外部提供商(如 Zaqar[1])的能力,通过一个简单的驱动程序接口实现。 这将包括 Searchlight 在简单的 OpenStack 通知之上提供的的数据丰富。

问题描述

OpenStack 内部和外部的项目都有许多用例需要知道 OpenStack 资源何时发生更改。 OpenStack 提供了一个通知总线,用于接收服务发布的通知,但存在一些限制

  • 出于安全考虑,OpenStack 消息总线通常不直接暴露给外部消费者。

  • 通知通常仅包含关于特定资源的数据子集,这些数据是不完整的、不够丰富的

  • 通知数据与 API 结果看起来不一样

  • 通知总线不支持所需的所有消息订阅语义或机制,例如每个订阅者的过滤或 WebSockets/hooks

Searchlight 处理了上述许多问题,并将继续随着 OpenStack 的发展而演进,以便随着通知的更改/丰富,它也会随之演进。 它通过从 OpenStack 服务的各种位置索引数据(包括监听通知)来实现这一点。 它以多种方式丰富了基础通知提供的数据,这使得可以直接使用索引代替 API [2]。 后者还具有减少各种服务上 API 调用压力的额外优势。

Searchlight 增强的搜索能力 [3] 和性能 [4] 优于典型的 API 响应,因此它已被集成到 horizon[5][6][7] 和其他地方。

当前的 Searchlight 用户仍然需要使用轮询机制来获取来自 Searchlight 的更新信息。 许多 Searchlight 消费者需要一种异步方式来及时了解 OpenStack 资源的变化,例如可用性和状态。 他们还需要一种确保他们收到的状态更新与索引到 Searchlight 的资源的状态一致的方法。

1. 今天 Horizon 的一个痛点是,尽管 Searchlight 及其从更丰富的通知和弹性搜索中获得的诸多好处可用,但 Horizon 仍然需要定期轮询 Searchlight 以获取更新。(如果 Searchlight 未处理通知,则需要直接调用 OpenStack 服务 API。 然而,越来越多的 OpenStack 项目正在与 Searchlight 集成。)提供按发生方式提供更新的通知服务将很有吸引力。 例如,考虑一个 VM 启动请求。 在理想情况下,Horizon UI 会自动更新以显示虚拟机启动过程中的各个阶段。 今天,Horizon 在后台通过频繁轮询 Searchlight 和/或其它 OpenStack API 服务来实现这一点。

2. 具有苛刻的服务正常运行时间要求和对服务延迟的低容忍度的电信供应商也寻求资源更改通知。 他们通常会有一个管理层/应用程序,该层/应用程序寻求了解资源更新情况。 例如,用户、VM、glance 镜像、flavor 或其它资源的 CRUD 操作。 例如,新用户的到来可能需要触发一个工作流程,例如欢迎消息、提供服务等。 Searchlight 今天检测到这些事件并对其进行索引,但无法近乎实时地将其推送到电信管理层。

3. 对于第三方应用程序,通常有兴趣了解监控工具,这些工具希望了解资源及其可用性。 这些可能涵盖 flavor、实例、存储、镜像等及其状态。 通常,这些第三方监控系统将由于安全原因而无法访问 OpenStack 消息总线。 例如,内容提供商希望在将新电影上传到 Swift 时向其客户群进行广告宣传。 另一个例子可能是当安全补丁上传到 Glance 时触发升级操作。

提议的变更

我们建议 Searchlight 添加转发通知的能力。 此外,支持转发实体管道的转发基础设施将提供最大的灵活性。 例如,考虑 paste 管道,以及在 paste.ini 文件中指定的顺序和实体。 请注意,从某种意义上说,Searchlight 是通知管道中的第一个元素,它将 OpenStack 消息总线中的主要通知作为输入并对其进行丰富,同时对其进行索引。

一个通知消费者可能是 Zaqar,OpenStack 消息即服务项目,甚至是更简单的消息转发机制,例如 WebSockets,甚至是一个简单的记录器。

通知消费者需要足够快,以免拖慢 Searchlight 的通知推送子系统。 此外,需要达成共识。 例如,如果 Searchlight 无法联系到已注册的通知消费者,应该怎么办? 请参阅 bug [8]。 记录错误并忘记它? 应该在尝试之间经过预配置的等待间隔,重新尝试预配置的次数吗? 应该在成功发送之前保留通知吗? 后一种解决方案对于 Searchlight 来说可能要求过高,尤其是在有多个已注册的消费者时。

我们的解决方案策略是为 Searchlight 的每个消费者定义一个消费者插件。 如果 Zaqar 是消费者,那么 Searchlight 中有一个 Zaqar 插件。 可以将连接失败时的错误处理的复杂性留给 Zaqar 插件,可以进一步处理从 Searchlight 到 Zaqar 实际传输的通知的过滤。 将错误处理留给插件是有意义的,因为有些消费者可能关心丢失的通知,而另一些消费者则不然。 例如,邮件程序会按到达顺序显示消息,但有时 VPN 会中断,或者没有无线连接或其他问题。 然后邮件阅读器可以在重新连接时只发出邮件同步。 正是在这种精神下,我们将通知处理留给插件及其消费者及其最终用户 API。 基本上,重试行为、重新同步行为都留给插件-消费者对。

主要的通知/消息流如下所示:OS 内部服务 —> Searchlight —> Zaqar-plugin —> Zaqar —> 外部应用程序

对于每个 Searchlight 插件,它可能有一个配置的通知转发器。 在 Searchlight 接收到通知、执行任何数据丰富并将其索引到 ElasticSearch 后,它将通过其插件将丰富的数据发送到配置的通知转发器。

通知转发器将支持过滤转发字段

  • 不可搜索的字段(已由 Searchlight 配置)

  • 仅管理员字段

  • 通过正则表达式(类似于 Glance 属性保护)

Searchlight 可以通过将上述功能重构为通用实用程序来简化插件开发。 相应的插件可能希望将过滤作为可配置参数或硬编码参数。 这完全取决于插件-消费者对。

这样,当资源通过通知更新时,更新的资源将被发送到 Zaqar 等消息系统。 Zaqar 消息体将包含来自 Searchlight 的完整资源数据。

备选方案

另一种选择是引入一个全新的服务,从 ceilometer 中分离出来,以监听通知,但这将存在以下缺点。

要么没有,要么必须重建 Searchlight 丰富数据和了解敏感数据的能力。

从监听通知和定期重新同步中解决缓存一致性问题仍然是一个问题。 理想情况下,不应强制任何消费者处理由另一个消费者启动操作导致的通知洪流。 例如,考虑 Horizon 表格视图,例如列出所有实例的实例表。 如果 Horizon 只是消耗通知数据来显示可用时的新实例,它可以调用 Nova API 来补充当前显示的实例列表。 然而,用户看到的结果来自搜索/Searchlight(参见引用的 Horizon 蓝图)是不同的。 同样,如果更改搜索条件,结果也会有所不同。 通过将 Searchlight 作为通知管道中的第一跳,我们可以确保用户对所有通知都有一致的视图,除非用户启动任何重新同步。