幂等这个概念,指重复操作不会产生任何影响。比如,电梯重复按两次,不会有差异(Ps:这里的电梯指的不是按第二次取消的那种,不要杠我,手下留情)。分布式系统特别强调幂等,因为通信可能丢失,就会需要重复发信号。

什么是幂等?为什么它对分布式系统中的编程有很大的帮助?我想等本篇文章写完,你将知道如何在自己的系统中实现幂等性。

幂等很重要,因为它抓住了安全重试的本质。没有安全的重试,你实际上就无法实现安全的分布式协议。

什么是幂等?其实质是,如果你两次询问,则与一次询问相同。它具有相同的效果。经典示例是电梯按钮。你走进一个电梯,按下对应楼层按钮,它点亮,然后其他人进入,按钮已经亮了,他们还是按下相同楼层的按钮。
我们知道那没有效果。由于某些原因,我们仍然想这么做。这只是个案例,也许信号没有到达电梯。他们值得尝试,因为它不会伤害任何东西。这就是我们想要灌输到分布式系统中的东西。从技术上讲,它是代数性质。

当你谈论按下按钮时,这是你对世界产生的积极影响。而在代数中,它是纯函数,数据函数的性质。这意味着,如果两次大写字符串字幕,都没关系。第一次就足够了。从技术上讲,如果将 F 应用于值,假设 F(x),与将 F 应用于 F(x) 相同。

你执行 F 的双重申请。与单一申请具有相同的效果。你可以说这意味着重复无关紧要。我按了两次按钮。第二个没关系。如果我两次应用相同的功能,第二次没有关系。第一次很重要。第二次、第三次、第五次,这些没关系。

为什么这很重要?在分布式系统中,特别是在分布式系统中,我们存在网络消息不可靠的问题。基本上,如果你发送一条消息,它可能不会到达那里并且你不知道。你不知道它是否到达那里。

有时,你知道它是否没有到达那里。你会收到一些断开连接的消息,但是有时你只是没有听到回音。超时了。

它到达了那里并且确认超时了,还是从未到达那里?另一个系统崩溃了吗?它是在发送我的电子邮件之前还是在发送我的电子邮件之后崩溃了?当你知道它崩溃了,为时已晚。电子邮件实际上是一个很好的例子,因为你不想发送相同的电子邮件两次。

假设你有一个电子邮件服务器,并且向其发送了一条消息,“请将此电子邮件发送给我的客户。” 你没有听到回音,你只是听不到答案。你是做什么?发生了什么?你会再次发送吗?

如果已经发送了电子邮件怎么办?是否要再次发送相同的电子邮件?如果没有发送,并且我也不再发送消息,那么客户将不会收到电子邮件。

这确实是一个真正的业务问题。幂等可以解决这个问题。如果我可以再次发送相同的消息,并且不会破坏任何内容,则不会产生第二种效果。就像那个电梯一样,我可以整天发送此消息。我可以发送一百次,而电子邮件只会发送一次。这是好事。

它可以让你做的就是解耦。它使发生的效果数量与你请求该效果的次数脱钩。我可以请求一百次,但是只会发送一次。那是你真正想要的东西。你希望能够使用有限的信息安全地重试。

我不知道这种情况是否发生,但是我将再次尝试。这是系统中非常好的属性。

你如何实现幂等?如果我们查看此电子邮件服务器,最简单的方法就是你需要某种识别电子邮件的方法。可以这样说:“这是我要发送的电子邮件的ID。如果我向你发送具有相同ID的同一封电子邮件,再次向你发送具有相同ID的电子邮件,请不要再次发送。”

接收它的服务器必须记住它曾经发送过的所有电子邮件ID。那时完全完全幂等的。通常,这是不实际的。你不记得每个ID,因为它可能有数百万个。他们可以追溯很多年。你不太可能收到需要花费数年才能到达的请求。

在实际情况下,你可能会看到一个窗口,上面写着:“嗯,我们保留三天的ID。” 这意味着你可以在这三天内重新发送相同的ID,而我们不会再次发送它。你必须找到一些实际的限制,以平衡内存需求和系统中的重试次数。

注意,这非常重要,这种身份概念非常重要。如果你没有身份的概念,那么再次发送相同的消息意味着什么?如果我想向此人发送两封电子邮件,则需要能够向他们发送两份电子邮件。我需要说些不同的方式。如果我想重试,我想以某种方式说这个和那个相同。

你的请求中需要一些身份。如果你正在查看电梯按钮,则此电梯服务的电子设备中可能存在某一个标识,它知道我按下了什么按钮。在三楼或四楼下。该按钮有一些标识符,首先,它可以点亮,并保持点亮状态,知道需要将其关闭为止。

该标识符可能在多个地方使用。它提出了一个请求,“哦,我们在三楼需要一个电梯,因为我们知道该按钮及其含义。” 也曾经说过:“嘿,我已经在送三楼电梯了。我不需要再做一次。” 它正在使用该标识符。

让我们回顾下。 你需要一个身份,一旦拥有该身份,就可以使用具有幂等运算的数据结构。具有幂等操作的常见幂等数据结构是一个集合,例如内存中的集合。

如果你有一组数字,则为每个电子邮件指定一个唯一的数字。电子邮件服务器发送电子邮件时,它会记住集合中的号码,并将其添加到该集合中。如果添加集合,请将其添加两次,就已经具有幂等性。

电梯也一样。如果你有一个带ID的按钮,则可以说它就像字符串“三楼向上”或“三楼向下”或“四楼向上”、“四楼向下” 一样,将其保存到一个集合中它很活跃。已被要求。这意味着你可以发送两次,两次发送也没有任何效果。

当然,现在,这还没有考虑实际的动作,即按下该按钮将电梯发送到该楼层所产生的效果。与电子邮件相同。它不考虑发送电子邮件或不发送电子邮件。

要确定是否要发送,很简单。在将事物添加到ID的集合之前,请询问集合“是否包含此ID?” 如果是这样,那么你就完成了。如果没有,则发送电子邮件,然后将ID放入集合中。还有其它幂等的数据结构。如果你有哈希图,则这些是幂等的。

如果你两次添加相同的键和值,则不会产生任何额外的影响。你可以考虑幂等的另一件事是将数字加零。如果需要某种幂等加法,则可以这样做。

还有其他具有幂等性的数据结构。它们更加复杂并且是专门用途。精力有限,我不会去研究它们。

想象它们就像具有其他属性的集合。你可以添加东西,但是也许它们的增长速度不如集合增长的速度快,它们就像是概率更大的数据结构。

我提到字符串是大写的。作为操作,这是幂等的。如果需要编写,可以使用它,例如大写名称表示与常规大小写名称有所不同。

这意味着你可以执行两次,并且不会产生任何额外的影响。你可能在某些方面使用了此功能,例如你的电子邮件系统在比较它们之前可能会小写所有电子邮件地址。如果已经小写了怎么办?没关系,它只是将所有内容都小写。如果已经小写,那就没有问题。

让我们再回顾一下。幂等意味着重复无所谓。它是某些函数,某些运算的代数性质,但我们将其扩展到世界上的动作。我们将其扩展到我们可以在世界上拥有的效果,在这里,我们说两次请求该效果与一次请求相同。这些重复在这里也没关系。

我们在分布式系统中需要它,以便我们可以进行安全的重试。它使我们能够将完成的工作与要求完成的次数脱钩。你可以使用幂等数据结构和操作轻松实现它。它需要一种感觉,即消息中的身份概念。

说了这么多,你可以找一些需要发生一次的服务。可能类似于发送电子邮件。可能正在将消息写入日志。可以是用户面板中的某些用户设置,并将它们包装在使它们成为幂等的数据结构之类的东西中试试。

最后修改:2023 年 09 月 11 日
如果觉得我的文章对你有用,请随意赞赏