为啥恰好一次语义不可行?
Posted
技术标签:
【中文标题】为啥恰好一次语义不可行?【英文标题】:Why is exactly once semantics infeasible?为什么恰好一次语义不可行? 【发布时间】:2010-09-29 19:33:38 【问题描述】:在 Erlang 寄希望于最好的 RPC 语义中,SUN RPC 至少一次和 Java RMI 最多一次但没有人有完全一次的语义。
为什么只有一次语义似乎不可行?
例如,如果客户端不断重新发送带有唯一标记的请求,直到收到回复,并且服务器会跟踪所有处理的请求,以免重复请求。那不是一次吗?
【问题讨论】:
【参考方案1】:考虑一下如果服务器在执行请求和记录它执行了请求之间崩溃会发生什么?
您最多可以通过记录请求然后执行它来获得一次。如果您在两者之间发生崩溃,那么您(错误地)将其记录为已执行,因此您不会再这样做了。因此最多一次
奇怪的是,这个(有超时)专利:http://www.freepatentsonline.com/7162512.html。除了我上面所说的,它不能保证完全一次。
您至少可以通过执行它然后记录它来获得一次。如果您在两者之间发生崩溃,如果重复请求,您将再次执行。
但在所有情况下都说“恰好一次”并不是真的可行
(网络错误也有类似的场景,而不是服务器崩溃)
【讨论】:
一次有趣的论文:ilpubs.stanford.edu:8090/483/1/2000-7.pdf【参考方案2】:像 IBM 的 WebSphere MQ 这样的高端消息传递总线声称只提供一次交付。事实上,这是默认行为(截至我上次使用 WMQ 时...)。他们通过Write-ahead logs 和各种锁定技术实现了这一点。
当然,我不怀疑埋在他们的法律文件中的某个地方,“恰好一次”实际上被定义为“消息可能会或可能不会被传递,一次,不止一次。或很多。或少于零。”为了掩盖他们的背部,但它在绝大多数情况下确实有效,包括踢掉电源线,将斧头砍到网络基础设施等。
【讨论】:
WebMethods Broker 在其营销材料中也有“恰好一次”。 这肯定必须“尚未执行或仅执行一次”? IE。它必须有无限长的事务 - 或者只是考虑关闭服务器:) 如果最后的传递步骤是原子的,我认为你可以只传递一次消息。但是,如果在“交付”步骤中有任意计算(就像 RPC 一样),我不知道如何精确地执行此操作。 确实,WebMethods 文档指出,他们称之为“保证交付”,需要原子事务。 任意计算由于停机问题而变得不可行?是的-我想恰好一次真的意味着“它在那里,我们已经完成了,或者它还没有”。通过这些让步,绝对可以实现分布式原子性。【参考方案3】:我认为答案是您需要无限的时间来获得这些语义,因为客户端必须等待来自服务器的明确结果,而这可能永远不会到来。这个要求在真实网络上是不切实际的。
如果客户端放弃尝试(或者如果服务器在完成事务之前或在发出信号完成之前长时间停机,这取决于它执行这些操作的顺序),那么可能没有办法客户端知道请求是否被接收和处理。在实践中,例如 RPC 系统可能希望遵守默认的 TCP 超时,因此不希望必须等待服务器确定的成功或失败。
不过这是个猜测:我从未设计过 RPC 协议。
【讨论】:
以上是关于为啥恰好一次语义不可行?的主要内容,如果未能解决你的问题,请参考以下文章