精确一次和至少一次保证之间的区别
Posted
技术标签:
【中文标题】精确一次和至少一次保证之间的区别【英文标题】:difference between exactly-once and at-least-once guarantees 【发布时间】:2017-10-27 13:09:30 【问题描述】:我在研究分布式系统,参考这个老问题:*** link
我真的无法理解完全一次、至少一次和最多一次保证之间的区别,我也在 Kafka、Flink 和 Storm 以及 Cassandra 中阅读了这些概念。例如有人说 Flink 更好,因为它有完全一次的保证,而 Storm 只有至少一次。
我知道,Exactly-once 模式在延迟方面更好,但同时在容错方面更差,对吧?如果我没有重复,如何恢复流?然后......如果这是一个真正的问题,为什么认为一次性保证比其他保证更好?
谁能给我更好的定义?
【问题讨论】:
看看this section of Kafka documentation,如果这能解决您的疑问,请告诉我们。 【参考方案1】:我找到了一个很棒的网站,其中简洁地讨论了所有(或大部分)Cloud Computing Patterns
。真心推荐给你,看看:http://www.cloudcomputingpatterns.org
一次性交付
对于许多关键系统,重复消息是不可接受的。这 消息传递系统确保每条消息只传递一次 通过自动过滤可能的重复消息。
至少一次交付
如果失败导致消息丢失或花费太长时间 恢复,重新传输消息以确保它们被传递 至少一次。
【讨论】:
【参考方案2】:Flink 使用这些术语来谈论事件对应用程序状态的影响。假设我正在尝试在日常窗口中使用标签 apache-flink 来计算堆栈溢出的帖子。如果我使用 exactly once 保证,那么每个帖子都将只计算一次,我的分析将 100% 正确,即使在此过程中出现故障并且必须重新处理一些数据以使那会发生。 Flink 通过结合全局一致的快照和流重放来实现这一点。 至少一次,那么如果出现故障,一些帖子可能会被计算两次,但我保证每个帖子都会被管道分析。并且最多一次在失败的情况下将没有快照和重播,如果出现问题,这将导致帖子计数不足。
就正确性和容错性而言,Exactly-once 是最佳选择,但代价是会增加一点延迟。
有关此主题的更深入处理,请参阅 data Artisans 的这篇博文 -- High-throughput, low-latency, and exactly-once stream processing with Apache Flink™ -- 和 documentation of Flink's internals。
【讨论】:
【参考方案3】:以下定义引用自Akka文档
最多一次 交付
表示对于传递给机制的每条消息,该消息是 交付零次或一次;用更随意的话来说,这意味着 消息可能会丢失。
至少一次 交付
意味着对于每条潜在地传递给机制的消息 在交付时进行了多次尝试,因此至少有一个 成功;同样,用更随意的术语来说,这意味着消息可能是 重复但未丢失。
一次性 交付
意味着对于传递给该机制的每条消息,只有一个 交付给收件人;消息既不能丢失也不能 重复。
第一个是最便宜的——最高的性能,最少的实现开销——因为它可以以一种即发即弃的方式完成,而无需在发送端或传输机制中保持状态。第二种需要重试以应对传输丢失,这意味着在发送端保持状态并在接收端具有确认机制。第三个是最昂贵的——因此性能最差——因为除了第二个之外,它还需要在接收端保留状态以过滤掉重复的交付
【讨论】:
【参考方案4】:Here 是一篇激进值得一读的文章。
我会尽力回答你的问题:
Exact-once 在大型分布式系统中不能容错, 因为所有系统不可能就每条消息达成一致,如果 一些系统可能会失败。您可以执行一次,但它会 至少一次与您自己昂贵的协调一致。思考 关于在底层 IP 时 TCP 如何确保可靠的数据传输 协议不可靠。 通过在 at-least-once 之上实施exact-once,您将在发生故障时拥有重复项(如果不是确切的一个),您需要进行重复数据删除。 Exact-once 并不被认为更好,因为它的成本很高,而 at-least-once 在大多数情况下就足够了。【讨论】:
以上是关于精确一次和至少一次保证之间的区别的主要内容,如果未能解决你的问题,请参考以下文章