事件流平台Kafka、Pulsar和RabbitMQ比较 - Picnic


让我们首先将事件定义为机器可读数据,当发生某些事情时,设备或服务会发出该数据,例如,客户在应用程序中单击。事件流是单个事件或小批量事件从生产者到消费者的代理和传输过程。事件流平台正在接收、即时转换事件(尽管这是可选的),然后将事件暴露给消费者。事件流平台区别于消息队列系统的一个重要特性是,当事件存在于流中时,许多消费者应该能够多次读取同一事件。此外,平台应该是可靠的,并遵循至少一次语义(或者甚至更好——恰好一次)以避免任何数据丢失。
根据这个定义,我们可以看到像经典 RabbitMQ 这样的技术不在列表中,因为多个消费者不能多次读取相同的消息(但我们将讨论 RabbitMQ Streams!)。虽然我们进行了内部比较,但如果我们放弃事件流平台并转向消息队列,那么没有可重播性的弊大于已采用 RabbitMQ 的利弊。
此外,像 Apache Spark 或 Apache Flink 这样的技术更多地是关于事件处理而不是流;他们实际上并没有为多个消费者保留消息。关注点的分离和这些系统的分类之间的界限非常模糊。例如,事件流平台 Apache Kafka 支持 KStreams 和 KSQL,以实现聚合和联接等流内处理。然而,最重要的分类是其核心:要么是接收、保存和提供数据给消费者,要么是处理和修改数据。因此,我们今天将讨论流优先技术而不是处理优先
 
Apache Kafka
它充当分布式持久日志,对保留时间或大小没有(理论上)限制。主题是 Kafka 中的语义单元,通常为每个数据模式创建一个主题。数据的消费者可以组合在一起,同时从一个主题中读取数据。它们将主题偏移量存储在 Kafka 本身中,明确它们的位置,并使它们能够适应重启。一个主题由作为并行单元的分区组成:它们限制了一个组内(但不是跨组)并行工作的消费者的数量。
在 Apache Kafka 3.0 之前,Kafka 由 2 个核心基础设施组件组成:Kafka brokers 和 Apache Zookeeper。前者处理消费者、生产者和数据存储,后者用于代理和配置存储的编排。值得一提的是,很快 Apache Zookeeper 将在 Kafka 3.0 中被删除,并且 Kafka 代理将能够通过仲裁控制器自行建立共识。这不仅简化了自托管系统的管理,而且还应该带来显着的性能改进并扩展对每个集群分区数量的软上限。
除了作为一项在全球拥有庞大社区的体面技术外,Apache Kafka 通过围绕它引入一个蓬勃发展的数据工程生态系统,在骨头上长出了很多肉。Apache Kafka Connect 是一个通过使用连接器从 Kafka 获取和接收数据的系统。其他 Apache 项目,如 Apache Camel,也制作适配器以进一步丰富 Apache Kafka Connect 功能。大多数连接器只需简单的配置即可工作,但当然,您可以修改代码,或者更好的是,编写自己的转换和验证函数来对传递的数据进行单个消息转换。
在 Picnic 中,我们严重依赖 Snowflake 连接器将数据直接传送到我们的数据仓库,但也依赖 RabbitMQ 连接器从我们的内部服务传播数据。
Apache Kafka Connect 并不是唯一的闪亮宝石。KSQL 允许您在流上运行复杂的 SQL 查询,包括连接以完成流内数据分析。如果您需要,Apache Kafka 还提供一次性保证,并准备为性能付出代价(但对于某些用例,这是必须的)。
当然,没有什么是免费的。Apache Kafka 以其复杂的配置而闻名,它可以有效地处理大规模数据。选择正确数量的分区来处理数据流中的杂散也很困难。
在 Picnic,我们通过使用Confluent Cloud管理 Apache Kafka 解决方案解决了第一个问题。通过取消维护并将配置时间减少到几乎为零,它给我们的团队带来了极大的安慰。通过为 Apache Kafka Connect 和 KSQL DB 提供托管的 Snowflake 连接器,它还大大加快了开发和集成的速度。至于第二个问题,我们目前过度配置了分区数量,并一直在思考可能的最佳解决方案。
我们在 AWS Kinesis 降级前后开始了对 Apache Kafka 的评估。第一步是技术和架构审查。之后,我们使用 docker-compose 构建了一个小型 PoC,以查看我们的 Snowplow 管道和 Apache Kafka Connect 是否可以在我们的环境下正常工作。然后我们可以填写一份适当的提案并评估此次迁移的风险和影响。第二年,我们忙于建立健全的试验流程。我们:

  1. 使用 Kafka 为我们的生产环境之一构建了额外的管道。
  2. 彻底验证数据完整性,检查是否发生任何数据丢失(反过来,它确实发生了,但它是什么以及我们如何修复它是另一篇文章)。
  3. 围绕新管道创建监控设置。
  4. 准备了一组我们需要的脚本来简化进一步的工作。

试用过程花了我们半年时间,包括尝试新的 Apache Kafka 生态系统功能、解决我们设置中的任何问题以及与所有利益相关者沟通。之后,我们完全采用了 Apache Kafka,并开始了在所有市场环境中进行全面部署的旅程。

 
Apache Pulsar
Apache Pulsar 是一个相对较新的分布式消息系统和事件流平台。它涵盖了这两个领域,看起来好像 Apache Kafka 中添加了一些 RabbitMQ 功能以及它自己的特殊津贴。从消息队列的角度来看,Apache Pulsar 可以在代理级别通过 AMQP 协议工作,并使用类似于 RabbitMQ 的直接或扇出策略(但不是主题策略,即路由键并不真正存在)。因此,有人可能会争辩说它遵循基本的发布/订阅模式,而不是成熟的消息队列。它的事件流功能很广泛,符合我们的定义,而且它支持从主题中随机访问读取,假设消息 ID 是已知的。
Apache Pulsar 架构由 3 个组件组成:Pulsar brokers、Apache Zookeeper 和 Apache BookKeeper。这种分离中的一件有趣的事情是 Pulsar 代理是无状态的,它们的主要目标是为入站和出站消息和请求提供服务,而 Apache BookKeeper 提供事件数据的持久性。它允许独立扩展这两个层,提供更大的灵活性。
我们将密切关注 Apache Pulsar,但目前 Apache Kafka 正在赢得我们的芳心,原因有以下几个:

  • 与 Apache Pulsar I/O 相比,Apache Kafka Connect 具有更多种类的源和接收器。特别是,对我们来说,缺少Snowflake连接器是一个缺点。
  • KStreams 和 KSQL 非常强大,Apache Pulsar 中的下一个最接近的等价物是 Pulsar Functions。但是,在我们看来,它更类似于功能稍微丰富的 Apache Kafka Connect 单消息转换,不足以满足我们对流内数据分析的需求。
  • Apache Pulsar 的社区规模在不断增长,但与 Apache Kafka 相比仍然相形见绌。

 
RabbitMQ Streams
RabbitMQ Streams 是事件流平台领域的一个全新参与者,于 2021 年 7 月宣布。这项新功能允许用户通过提供正确的标头集,通过 AMQP 协议创建类似日志的流,就像 Lazy Queues 将 RabbitMQ 移动到超出主内存持久性的领域。总的来说,核心功能集非常枯燥,完全符合我们的定义,最大的优势是如果你有 RabbitMQ 3.9,你可以免费获得它,你的所有应用程序都可以通过 AMQP 将数据发送到流。消费者需要使用新的 API,但它与现有 API 非常接近。
目前,我们将 RabbitMQ Streams 添加到我们的雷达中,并将等待更多新闻、功能和基准测试来采取下一步行动。