改进 Pulsar 消费者基于正则表达式的订阅方式 本文翻译自 StreamNative 博客《Improving Regular Expression-Based Subscriptions in Pulsar Consumers》。
译者简介
钟颖群,微信大数据团队成员,从事大数据基础架构服务建设。
深入研究基于正则表达式的订阅
目前,Pulsar 客户端有两种方式来创建消费者:
1.指定需要消费的主题列表,该列表通常只包含一个主题名称,但也不是强制规定。
2.指定正则表达式作为主题样式。一开始,这种方式相当于列出所有正则匹配的主题。随着时间推移,会创建一些新的主题,同时可能会删除部分主题。基于正则表达式的消费者具有自动发现机制。消费者会在后台定期询问 Broker 当前的主题列表。当消费者发现正则匹配的主题名称集合中有变化时,它将订阅新主题。你可以在创建消费者时设置检查主题列表是否更新的时间间隔。默认情况下,将每隔一分钟执行一次检查。
消费者和 Broker 间典型的交互方式如下图所示:
图 1. 主题发现
当前实现的效率问题
如上一章节所述,消费者会请求主题的完整列表。尽管一个模式不能覆盖多个命名空间,但命名空间的主题列表个数可以多达上千个。即使主题名称信息中不包含消费者所关注的内容,但这些数据仍然会每分钟通过网络传输。
可以通过设置更长的自动发现间隔来降低网络负载,但这也意味着感知到新主题的速度会变慢,同时导致对主题消息的处理产生分钟级延迟。
优化基于正则表达式的订阅
针对以上问题,我们对 消费者 和 Broker 提出[1]了一些修改意见:
-
• 模式匹配逻辑调整到 Broker。
-
• Broker 具备响应 “无变化” 的能力。
-
• 增加从 Broker 到客户端基于实时发现的通知机制。
Broker 端的模式匹配
消费者可以在请求主题列表时将模式信息添加到请求中。同时 Broker 支持按模式过滤主题列表并只返回匹配的主题的能力。在多数情况下,这种过滤方法会显著降低响应数据量。
图 2. Broker 返回过滤后的请求响应
无变化时跳过更新
针对大多数后续的请求,Broker 返回的请求响应没有变化。原因是这期间没有创建新主题或者创建的新主题和请求模式不匹配。在这种情况下,响应返回主题列表没有任何意义;Broker 应该指明请求结果没有任何变化,这样消费者在消费的时候就可以不更新主题列表。启用该响应的一种方式是让 Broker 对特定消费者的最新一次响应进行跟踪记录。然而,这种方式会给 Broker 带来不必要的负担,因此我们考虑让消费者来跟踪最新一次响应。具体来说,Broker 会基于匹配到的主题列表计算哈希值并在请求响应中包含该值,消费者在下一次请求主题列表时,将在请求中携带该哈希值。如果 Broker 发现当前哈希值与请求中的哈希值相同,它会发送一个带有标记而不是主题名称的响应,以表明消费者当前的主题列表仍然是最新的。
图 3. Broker 返回无变化响应
更快的发现通知
上述功能解决了不必要的网络流量问题,但无助于更早地发现新主题并避免消费滞后。为此,我们引入了主题列表观察器。
如图 4 所示,消费者向 Broker 注册了观察器。开始阶段的交互类似于在上面部分中讨论的内容。不同之处在于 Broker 会追踪观察器。每当新主题创建(可能通过另一个 Broker )时,Broker 都会从元数据存储中获取通知,并立即向与该新主题名称模式匹配的消费者发送通知。这样,消费者可以在几秒钟内感知新创建的主题。
图 4. 主题列表观察器的生命周期
并行轮询通知
上述的主题列表更新过程涉及多个服务和步骤。例如,元数据存储服务需要通知每个 Broker,Broker 需要对此处理并通知与对新增主题名称匹配的消费者。在此过程中,Broker 服务可能在主题创建后就出现问题。在这种情况下,即使主题已成功创建,也无法通知对应的消费者。简言之,创建主题和发送通知不是原子操作。因此,消费者不能完全依赖 Broker 的通知,必须使用轮询机制来获取没有及时收到的通知。值得一提的是,丢失通知并不会导致消费者消费出现错误或者数据不一致;直到消费者下一次成功轮询到匹配的主题前,丢失通知仅会导致对新主题的消息延迟处理。
总结
上述增强功能将在 Apache Pulsar 2.11.0 版本发布。这将解决大量 Pulsar 用户在使用基于正则表达式订阅功能时遇到的问题。首先,在 Broker 端实现主题模式匹配并在大多数情况下采用省略更新的方式将显著降低网络开销。其次,观察器提供了一种针对新创建主题的高效且迅速的发现机制,从而解决了处理这些新创建主题消息的滞后问题。
引用链接
[1]
提出: https://github.com/apache/pulsar/issues/14505