分布式系统幂等性浅淡

什么是幂等性

幂等性是一个原本是数学的概念,常见于抽象代数中。即使公式:f(x)=f(f(x))能够成立的数学性质。而在计算机学中,则是指任意多次执行所产生的影响与一次执行的影响相同。

为什么需要幂等性

在分布式系统中,其环境的复杂度、网络的不确定性会造成诸如时钟不一致、“拜占庭将军问题”等各种问题,而且机器宕机、消息丢失等问题,也会比集中式系统中更加容易出现。

基于这些特性,分布式系统在接口调用异常时进行重试补偿十分常见。但这也引入另一个问题,就是多次调用接口是否会对系统造成无法承受的损失呢?

设想这样一个支付场景,支付流程进行扣款操作,倘若这个时候扣款接口被调用多次,直接导致用户财产损失,这个便是无法接受的。

幂等性便是解决这类问题的方案之一。

幂等性如何实现

前文提到,在计算机领域,幂等性是指任意多次执行所产生的影响与一次执行的影响相同。那简单来说,只有保证操作最多只执行一次即可,这样就可以非常简便地实现了一个幂等系统。

按我们的思路,分为4个步骤:

1. 将每一个不同的业务操作赋予全局唯一ID。

2. 进行业务操作之前,查看是否有此业务操作的执行记录,从而判定此业务操作之前是否执行过。

3. 若从未执行,则记录此操作的执行记录并开始执行业务操作。

4. 若已执行,则放弃执行此次业务操作。

同时,我们需要关注以下3点:

1. 操作执行过程中,不允许相同业务操作再次执行,即上文步骤3,在开始执行业务操作的同时,需要记录此操作的执行记录。

2. 操作执行失败时,理想情况下,另一个相同操作可以立即执行,所以在操作执行失败时,需要删除此业务操作执行的记录。

3. 操作超时或者宕机时,在某个时间段后,另一个相同操作可以执行,所以记录业务操作执行记录需要有超时删除机制。

在实现过程中,由于需要记录业务操作执行记录,所以我需要一个存储引擎,简单来看,我们仅需要一个K-V存储即可。

全局幂等系统流程

Key&Value

Key和Value具体内容如图所示。

Key由AppID和TransContent组成。

AppID是为了区分不同的业务,TransContent为具体操作的内容,一般由业务自定义,例如订单系统中,具体订单处理任务的内容(json字符串)。当然为了防止TransContent内容过长导致Key过长,所以将AppID和TransContent进行MD5后作为Key。

Value由UUID,expireTimestamp,AppID和TransContent组成。

UUID作为操作记录的唯一标识,用于创建、删除K-V对相互匹配,防止删除相同业务操作,但不是同次的记录。

比如任务A开始执行,在幂等系统中记录K-V。任务A由于某种原因,任务执行超时,而且幂等系统记录K-V由于超时机制,K-V自动删除。由于重试机制,相同任务A‘开始执行,由于原有幂等系统记录K-V已超时删除,所以任务A’可以执行。在执行过程中,原有任务A执行完成,对幂等系统中记录K-V进行删除。如果没有UUID,任务A可以删除任务A‘的K-V对,故需要UUID保证创建、删除的相互匹配。

ExpireTimestamp为K-V超时时间戳,用于判断此K-V是否已超时失效,操作可以进行。另外AppID和TransContent仅仅核对业务与操作。

更多

幂等系统实现建议与存储引擎松耦合,存储引擎只需要满足K-V存储即可,可以使用Redis。若使用Redis,Value中expireTimestamp就无意义,因为Redis自带expire功能。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券