sharetwitterlinkedIn

使用 Apache Pulsar 简化智联招聘的活动中心

head img

【智联招聘】(https://www.zhaopin.com/)是中国最大的在线招聘和职业平台之一,拥有超过100+百万用户的用户群和200+百万份简历的数据库。作为双语招聘平台,它提供了中国最大的实时职位空缺选择之一。

支持智联招聘的软件的一个关键部分是我们的活动中心系统。该系统负责智联招聘中的所有服务内消息传递,支持关键任务服务,例如简历提交和求职。活动中心系统在正常情况下每天需要处理超过 10 亿条消息,在招聘高峰期扩展到每天数十亿条消息。

我们之前支持事件中心发布-订阅消息传递和消息队列需求的技术由两个独立的系统组成。我们的工作队列用例是使用 RabbitMQ 实现的,而我们的 pub-sub 消息传递和流式处理用例使用的是 Apache Kafka。

我们在整个微服务架构中使用工作队列作为中间层来解耦前端服务和后端系统,即使在流量高峰的情况下,我们的系统也能可靠地运行。在智联招聘,我们典型的工作队列用例具有以下特点:

  • 每条消息都被多个独立的服务消费。
  • 每个服务必须使用所有消息的完整副本。
  • 每个服务有多个消费者同时消费消息。
  • 应保证每条消息至少发送一次。

需要一种跟踪机制来跟踪关键任务服务的消息生命周期。 例如,当用户提交简历时,处理简历提交的服务将首先将消息排入消息传递系统。 然后所有其他服务(例如数据库更新、发送通知和推荐)将使用来自消息传递系统的消息并处理它们。

workflow

图1:简历提交服务工作流程。

我们的挑战

尽管我们确实拥有支持我们的活动中心系统的技术,但我们看到随着我们的发展,该技术面临着许多日益增长的挑战和限制。

成本和复杂性

我们以前方法的主要问题之一是为了服务不同的用例而同时部署和管理多种消息传递技术的硬件成本和管理负担。 还必须将相同的事件数据发布到双数据管道中,从而产生了几个额外的问题。 首先,相同的数据需要存储在两个独立的系统中,这使我们的存储需求翻了一番。 其次,很难在两个不同的系统中保持副本的一致性。 最后,使用两种不同的技术会带来额外的复杂性,因为我们的开发人员和 DevOps 团队必须熟悉这两种消息传递平台。

缺少重要功能

除了运行两个消息传递系统的运营开销之外,我们之前的每项技术都存在架构缺陷,这使得切换的决定更加引人注目。 虽然 RabbitMQ 很好地支持工作队列用例,但它不能很好地与流行的计算框架集成。 它也有一些限制,例如可扩展性、吞吐量、持久性和消息重放。 我们试图通过实现我们自己的基于 Apache Zookeeper 和 RabbitMQ 的分布式消息队列服务来克服。 然而,我们发现这个决定也带来了我们认为不可持续的巨大持续维护负担。

性能和耐用性不足

在我们的高峰使用期间,如果不增加一些 Kafka 主题的消费者数量,我们就无法满足我们的服务级别 SLA。然而,我们发现 Kafka 中并行消费的能力与给定主题的分区数量紧密相关。因此,为了增加特定主题的消费者数量,我们需要增加分区数量,这对我们来说不是可接受的方法,原因如下: 新创建的分区不包含任何数据,导致消费吞吐量没有真正增加。为了解决这个问题,我们还必须强制对主题进行分区重新分配,以将积压的数据分发到这些新分区上。

这两个步骤都不容易自动化,迫使我们监控积压的主题,并手动纠正问题。 尽管我们已经为我们的发布-订阅消息传递用例部署了 Kafka,但 Kafka 并没有提供数据持久性保证,而这些保证越来越成为我们的关键业务业务服务的必备要求。 出于这些原因,在 2018 年初,我们决定通过选择一种支持我们的工作队列和流用例的技术来简化整个消息传递技术堆栈,从而消除托管单独系统的所有成本和复杂性。

要求

考虑到这一点,我们编制了以下消息平台所需的功能列表:

  • 容错性和强一致性:我们的消息系统中存储的事件用于关键任务在线服务,因此数据必须以一致的方式可靠地存储。 事件在任何情况下都不会丢失,并且必须能够保证至少一次交付。
  • 单一主题消费者可扩展性:我们必须能够通过随着流量模式的变化即时增加主题消费者的数量来轻松扩展单个主题的吞吐量。
  • 单个消息和累积消息确认:消息传递系统应同时支持单个消息的确认,这通常用于工作队列用例,以及消息的累积确认,这是大多数流用例所必需的。
  • 消息保留和回退:我们需要能够使用不同的保留策略配置不同的主题,无论是基于时间的还是基于大小的。 消费者应该能够将他们的消费倒回到某个时间。 基于这些要求,我们开始调查市场上可用的开源技术。 在我们最初的研究中,我们无法找到任何满足我们所有要求的开源消息传递产品,尤其是在无数据丢失和强一致性方面。

在我们所知道的技术中找不到更好的解决方案,我们最初的计划是在强一致性分布式日志存储平台[Apache BookKeeper](https://bookkeeper.apache.org/)之上构建我们自己的平台, 它提供了出色的日志存储 API,并已被 Twitter、Yahoo 和 Salesforce 部署在互联网规模。 然而,在与 BookKeeper 社区取得联系后,他们向我们推荐了 Apache Pulsar——基于 BookKeeper 构建的下一代发布-订阅消息系统。

为什么选择 Apache Pulsar?

在与 Pulsar 社区密切合作并深入研究 Pulsar 之后,我们决定采用 Pulsar 作为智联招聘的活动中心系统的基础,原因如下:

  • 通过使用 BookKeeper 作为其存储层,它提供了强大的持久性和一致性,保证了零数据丢失。
  • 它提供了一个非常灵活的复制方案,允许用户为每个主题选择不同的复制设置,以满足他们对吞吐量、延迟和数据可用性的要求。
  • Pulsar 采用以段为中心的设计,将消息服务与消息存储分开,允许各自独立扩展。 这种分层架构提供了更好的弹性,并避免了机器崩溃或集群扩展时复杂的数据重新平衡。
  • Pulsar 提供非常好的 I/O 隔离,适用于消息传递和流式工作负载。
  • 它提供了一个简单灵活的消息模型,统一了队列和流。 因此它可以用于工作队列和发布-订阅消息传递用例,从而使我们能够消除对双消息传递系统和所有相关问题的需求。

pub-sub

图 2:Pulsar 支持 Pub-Sub 消息传递和消息队列

除了这些关键的架构特性之外,Apache Pulsar 还提供了许多不同的企业级特性,这些特性对于支持我们的业务关键型应用程序至关重要,例如多租户、异地复制、内置模式支持和分层存储。 . 例如使用 Pulsar Functions 和 Pulsar SQL 的无服务器计算对于在智联招聘构建事件驱动的微服务至关重要

总结

我们对选择 Pulsar 及其提供的性能和可靠性感到非常满意,并致力于为 Apache Pulsar 社区贡献许多出色的功能,例如死信主题、客户端拦截器和延迟消息等等..

如果您运行多个消息传递平台只是为了服务不同的用例,您应该考虑用 Apache Pulsar 替换它们,以将您的消息传递基础设施整合到一个能够同时支持队列和发布/订阅的系统中。

我们很高兴将于 12 月 15 日在我们上海的办公室举办下一次 Apache Pulsar 聚会。请停下来听听我们@Zhaopin_com 的工程师关于他们在生产环境中运行 Pulsar 和使用 Pulsar + @ApacheFlink 的经验和最佳实践为他们的推荐系统提供动力。更多信息:buff.ly/2BFYrBy

我们要特别感谢 Apache Pulsar 项目的所有提交者,以及我们从其庞大且不断发展的社区成员那里获得的技术支持。

© 北京原流科技有限公司Apache、Apache Pulsar、Apache BookKeeper、Apache Flink 及相关开源项目名称均为 Apache 软件基金会商标。条款隐私