我正在研究分布式系统并参考这个老问题:stackoverflow link
我真的无法理解恰好一次,至少一次和最多一次保证之间的区别,我也在Kafka,Flink和Storm以及Cassandra中阅读了这些概念。例如,有人说 Flink 更好,因为有恰好一次的保证,而 Storm 只有至少一次的保证。
我知道恰好一次模式对延迟更好,但同时对容错更差,对吧?如果我没有重复,如何恢复流?然后。。。如果这是一个真正的问题,为什么精确一次保证被认为比其他保证更好?
有人可以给我更好的定义吗?
以下定义引用自 Akka 文档
最多一次 交付
意味着对于传递给机制的每条消息,该消息是 交付零次或一次;用更随意的术语来说,这意味着 消息可能会丢失。
至少一次 交货
意味着对于传递给机制的每条消息可能 多次尝试交付它,以便至少一次 成功;同样,用更随意的术语来说,这意味着消息可能是 重复但不丢失。
恰好一次 交货
意味着对于传递给机制的每条消息正好有一个 交付给收件人;消息既不会丢失也不会丢失 重复。
第一个是最便宜的 — 最高的性能,最少的实现开销 — 因为它可以一劳永逸的方式完成,而无需在发送端或传输机制中保持状态。第二个需要重试来抵消传输损失,这意味着在发送端保持状态并在接收端具有确认机制。第三个是最昂贵的,因此性能最差,因为除了第二个之外,它还要求将状态保留在接收端,以便过滤掉重复的交付。
这是一篇值得一读的激进文章。
我会尽力回答你的问题:
- 精确一次在大型分布式系统中不是容错的, 因为所有系统都不可能就每条消息达成一致,如果 某些系统可能会出现故障。您可以精确实现一次,但它会 至少一次与你自己昂贵的协调有关。想 关于 TCP 如何在底层 IP 时确保可靠的数据传输 协议不可靠。
- 通过在至少一次之上实施精确一次,您将在发生故障时拥有重复项(如果不是完全相同的重复项),并且您需要的是消除重复数据。
- 精确一次并不被认为是更好的,因为它的成本很高,而在大多数情况下,至少一次就足够了。
Flink 使用这些术语来讨论事件对应用程序状态的影响。假设我正在尝试在日常窗口中使用标签 apache-flink 计算要堆叠溢出的帖子。如果我只使用一次保证,那么每个帖子将被精确计算一次,我的分析将是 100% 正确的,即使在此过程中出现故障并且必须重新处理一些数据才能实现这一目标。Flink 通过结合全局一致的快照和流回放来实现这一点。至少一次,那么如果失败,某些帖子可能会被计算两次,但我保证每个帖子都会被管道分析。最多一次,发生故障时不会有快照和重播,如果出现问题,这将导致帖子计数不足。
在正确性和容错性方面,精确一次是最佳的,但代价是增加了一点延迟。
有关此主题的更深入的处理,请参阅Data Artisans的这篇博客文章 - 使用Apache Flink进行高吞吐量,低延迟和恰好一次的流处理 - 以及Flink™内部的文档。
我找到了一个很棒的网站,其中简洁地讨论了所有(或大多数)Cloud Computing Patterns
。我真的推荐给你,看看:http://www.cloudcomputingpatterns.org
恰好一次交货
对于许多关键系统,重复的消息是不可接受的。这 消息传递系统确保每条消息只传递一次 通过自动过滤可能的消息重复项。
至少一次交货
如果发生故障导致消息丢失或花费太长时间从中恢复,重新传输消息以确保它们被传递 至少一次。