我正在研究分布式系统并参考这个老问题:stackoverflow link
我真的无法理解完全一次,至少一次和最多一次保证之间的区别,我在Kafka,Flink和Storm以及Cassandra中也读到了这些概念。例如有人说Flink更好,因为只有一次保证,而Storm只有至少一次。
我知道,一次性模式对延迟更好,但同时对于容错更糟糕吗?如果我没有重复,如何恢复流?然后......如果这是一个真正的问题,为什么一次保证被认为比其他保证更好?
有人可以给我更好的定义吗?
以下定义引自Akka文档
最多一次交付
意味着对于传递给机制的每条消息,该消息被传递零次或一次;从更随意的角度来看,这意味着消息可能会丢失。
至少一次交付
意味着对于传递给该机制的每个消息,可能在交付它时进行多次尝试,使得至少一次成功;再次,从更随意的角度来看,这意味着消息可能会重复但不会丢失。
准确一次交货
意味着对于递交给机制的每个消息,只有一个传递给接收者;消息既不会丢失也不会重复。
第一个是最便宜的最高性能,最少的实现开销 - 因为它可以以一种即发即忘的方式完成,而不会在发送端或传输机制中保持状态。第二个需要重试以对抗传输损耗,这意味着将状态保持在发送端并且在接收端具有确认机制。第三个是最昂贵的 - 并且因此具有最差的性能 - 因为除了第二个之外它还需要将状态保持在接收端以便过滤掉重复的交付
Here是一篇值得一读的好斗文章。
我会尽力回答你的问题:
Flink使用这些术语来讨论事件对应用程序状态的影响。假设我试图在日常窗口中使用标记apache-flink将帖子计数到stackoverflow。如果我正在使用一次保证,那么每个帖子将只计算一次,我的分析将100%正确,即使一路上出现故障并且必须重新处理一些数据才能实现。 Flink通过全局一致的快照和流重放来实现这一目标。至少有一次,如果有失败,一些帖子可能被计算两次,但我保证每个帖子都会被管道分析。如果发生故障,最多只有一次没有快照,也没有重播,如果出现问题,将导致欠账。
在正确性和容错性方面,恰好一次是最佳的,但代价是增加了一些延迟。
有关此主题的更深入的处理,请参阅数据Artisans - High-throughput, low-latency, and exactly-once stream processing with Apache Flink™和documentation of Flink's internals的博客文章。
我找到了一个很棒的网站,其中所有(或大多数)Cloud Computing Patterns
都被简洁地讨论过。我真的推荐给你,看看:http://www.cloudcomputingpatterns.org
完全一次交付
对于许多关键系统,重复消息是不可接受的。消息传递系统通过自动过滤可能的消息重复来确保每个消息只传送一次。
至少一次交付
如果出现导致消息丢失或需要很长时间才能恢复的故障,则会重新传输消息以确保它们至少被传送一次。