为啥 Kafka 是基于拉的而不是基于推的?
Posted
技术标签:
【中文标题】为啥 Kafka 是基于拉的而不是基于推的?【英文标题】:Why is Kafka pull-based instead of push-based?为什么 Kafka 是基于拉的而不是基于推的? 【发布时间】:2017-01-27 22:30:46 【问题描述】:为什么 Kafka 是基于拉的而不是基于推的?我同意 Kafka 提供了高吞吐量,正如我所经历的那样,但我看不出 Kafka 的吞吐量会如何下降,如果它是基于推送的。关于基于推送如何降低性能的任何想法?
【问题讨论】:
【参考方案1】:在我们设计此类系统(拉式与推式)时,可扩展性是主要驱动因素。卡夫卡是非常可扩展的。 Kafka 的主要优势之一是可以非常轻松地添加大量消费者,而不会影响性能和停机时间。
Kafka 可以以每秒 100k+ 的速率处理来自生产者的事件。 因为Kafka消费者从主题中拉取数据,所以不同消费者可以以不同的速度消费消息。 Kafka还支持不同的消费模型。您可以让一个消费者实时处理消息,而另一个消费者以批处理模式处理消息。
另一个原因可能是 Kafka 不仅是为像 Hadoop 这样的单一消费者而设计的。不同的消费者可能有不同的需求和能力。
基于拉取的系统存在一些缺陷,例如由于定期轮询而浪费资源。 Kafka 支持“长轮询”等待模式,直到真实数据通过以缓解此缺点。
【讨论】:
了解基于推送的优势会很有趣。 Kafka 还支持 pub-sub 模型,我认为这不是基于 pull 的。 @YugSingh OP专门指的是主题消费者负责获取(拉取)消息的事实;而不是代理负责将它们推送给连接的消费者。【参考方案2】:请参阅详细说明特定设计决策的 Kafka 文档:Push vs pull
支持拉取的要点是:
-
Pull 更适合处理多样化的消费者(无需代理确定所有消费者的数据传输速率);
消费者可以更有效地控制个人消费率;
更简单、更优化的批处理实施。
基于拉取的系统(消费者在没有可用数据时轮询数据)的缺点通过“长轮询”等待模式直到数据到达而有所缓解。
【讨论】:
你完全倒退了。来自文档:“但是,基于推送的系统难以处理多样化的消费者......” 糟糕,这是一个错字,我应该更加小心,。已更正,非常感谢您的通知。 基于拉取的系统的另一个缺点是延迟会更大,这是由于轮询请求之间的暂停,数据显示和等待拉取。 只是好奇。第1点和第2点不一样吗?拉动的好处是不同的消费者有不同的消费率?不是母语人士,所以我只是对第 1 点和第 2 点感到困惑,为什么它们是分开的而不是在一个点/句子中? 支持加入官方链接【参考方案3】:其他人已经根据 Kafka 的文档提供了答案,但有时产品文档应该作为绝对的技术参考而有所保留。例如:
许多基于推送的消息传递系统支持在 不同的速率,通常通过它们的会话管理原语。 当您建立/恢复一个活动的应用层会话时 想要消费和暂停会话(例如,根本不 响应小于 keepalive 窗口且大于飞行中窗口...或使用显式消息)当您想要时 停止/暂停。例如,MQTT 和 AMQP 都提供此功能 (在 MQTT 的情况下,自 90 年代后期以来)。鉴于没有任何动作 需要暂停消费(根据定义),并且更少的流量是 需要在稳定的稳定状态下(无要求),很难 看看 Kafka 的 pull-based 模型如何更高效。 推送消息与拉消息相比的一个关键优势是 没有请求流量随着潜在的数量而扩展 活跃话题增加。如果你有一百万潜在活跃 主题,您必须对所有这些主题发出查询。这 关注在规模上变得尤为重要。 拉式消息与推送消息相比的关键优势在于可重玩性。这在很大程度上决定了下游系统是否可以提供有关处理的保证(例如,它们可能会在这样做之前失败并必须重新启动,或者例如无法以可恢复的方式写入消息)。 拉式消息与推送消息相比的另一个关键优势是缓冲区分配。消费进程可以明确地请求尽可能多的数据,因为它们可以在预分配的缓冲区中容纳,而不必一遍又一遍地分配缓冲区。与来自查询扩展的推送消息相比,这可以弥补一些吞吐量损失(但不多)。但是,如果您的邮件大小变化很大(例如,几 KB->几百 MB),这里的影响是可以衡量的。 认为拉式消息传递比推送式消息传递具有结构上的可扩展性优势是错误的。分区通常用于在消息传递应用程序中提供规模,而不管消费模型如何。有一些推送消息系统在硬连线本地集群上运行良好,超过 300M msgs/sec...125K msgs/sec 甚至不能购买该节目的入场券。事实上,从定义上讲,拉式消息传递具有劣 好的吞吐量,而像 Kafka 这样的系统通常最终需要更多硬件来达到相同的性能水平。上面提到的好处通常可能使其物有所值。我不知道有人在高频交易中使用 Kafka 进行消息传递,例如,微秒很重要。有趣的是,在 1990 年代后期开发了各种推拉式消息传递系统,作为优化吞吐量的一种方式。结果从未令人震惊,系统复杂性和其他因素通常超过这种优化。我相信这是 Jay 关于真实数据中心网络的实际性能的总体观点,更不用说开放互联网之类的东西了。
【讨论】:
“推送消息与拉取消息相比的一个关键优势是,没有请求流量随着潜在活动主题数量的增加而扩展。如果您有一百万个潜在活动主题,您必须发出查询所有这些主题。这种担忧在规模上变得尤为重要。 -- 如果你有大量的消费者,Push 模型必须跟踪和管理所有的消费者信息。此外,如果消费者不能按照经纪人推动的速度消费怎么办?所以这两个问题在 Push 模型中也大规模存在。 @user1870400 不,这并不完全正确。我相信您认为的“路由表元数据”可以直接嵌入到传播层次结构中。例如:semanticscholar.org/paper/… 您无法将路由表维护与请求开销进行比较。唯一的快捷请求开销是批处理请求。路由有许多捷径(例如:使客户端会话建立原子化,预先支付路由表更改的成本)。 @user1870400 你还会注意到我在原始帖子中非常清楚地解决了可变消费率的问题:)。这在两种模型中都不是问题。 “路由表元数据”可以直接嵌入到传播层次结构中”。所以你在谈论像 Kademlia 这样的东西,其中代理多播给一组消费者而不是所有消费者,然后是组中的每个成员做同样的事情?那你不需要把所有这些逻辑放到消费者身上吗? @user1870400 比拉取请求更具可扩展性,是的。传播层次结构通常是树,因此您可以控制扇出,它会以完全延迟换取吞吐量。它的可扩展性要大得多。使用 Kafka 之类的东西,您所能期望的最好的结果就是将读取均匀地分布在副本中。以上是关于为啥 Kafka 是基于拉的而不是基于推的?的主要内容,如果未能解决你的问题,请参考以下文章
Kafka核心技术与实战——13 | Java生产者是如何管理TCP连接的?