关于在分布式环境中RVN和使用场景的介绍4

简介

在前面的文档中,我们介绍了RVN的概念,通过RVN可以解决的某类问题和使用技巧,以及处理RVN的逻辑的具体实现。在本文中,我们将要介绍关于如何使用RVN解决另一种在分布式系统中常出现的问题。

问题

假设我们创建了一个service来维护某种record。我们的service允许client获取record,并且基于现有record的内容对record进行修改。举例说,假设我们的record记录了client一方的某种操作的数量。Client每完成一次操作就将service一侧的count加1。当然我们有其它的方法,但是我们现在要求count的计算部分在client一侧完成。具体来说,我们的record可以定义为:

复制代码
Record {
    int ID;
    int count;
}

Service提供的API 为:

复制代码
void updateRecord(Record record);

但是在分布式系统中,可能有多个client同时试图更新同一个record,这样这两个client的update就会互相覆盖,从而使最终的结果错误。例如在下图,我们数据库中保存的ID "1"的数量是10。现在有两个client同时获取了这个记录,然后同时试图将数量改为11。最终两个带有11的结果将互相覆盖,从而我们错误的保存了11,而不是12。我们将如何避免这个问题?

解决方法

这个问题同样可以使用RVN来解决。具体来说,我们在record里加入RVN,代表某条记录的版本号。对于每次更新,client都要先获取当前记录以及它的版本号,然后将版本号加1写入到update record的request里。而service端需要检查request的RVN,确保该RVN大于当前保存的保本好,最后再将该记录和RVN写入到数据库。我们详细描述该过程如下:

现在client1和client2都获取了RVN为1的记录,然后都将RVN更新为2,发送request去试图更新service一侧的数据。Service一侧的逻辑如下:

在这里我们需要特别说明几点。为了保证处理的正确性,service必须保证在处理record的过程中RVN一直是合理的,否则就可能出现两个thread都认为自己的RVN是正确的,从而仍然互相覆盖。这样我们可以使用lock住record的ID,并且在处理完record之后再unlock,来保证处理的正确性。我们也可以使用DynamoDB的condition update来达到相同的目的,具体可以参见《关于在分布式环境中RVN和使用场景的介绍3》。

在这种逻辑下,后获得锁的thread将会发现它所持有的RVN已经不是合理的RVN了,所以它会拒绝处理它持有的request,并且向client汇报这一情况(比如可以throw exception)。而client可以重新从service获得最新的RVN的record,再次尝试根据最新的记录进行更新。

问题扩展

在我们讨论的解决方案里,我们期望service和client可以遵守共同的规则在一起工作,比如期望所有的client都可以基于获取的RVN每次增加1。只有在这种情况下,我们的数据才能被维护正确。假如,我们的API是公开的API,也就是说client并不总是可信的。Client可能会破坏规则给RVN增加2或者更多来试图非法获取修改数据的规则。在这种情况下,我们可以给每一个record version生成一个UUID来代替RVN。Client必须提供当前version的UUID以获取修改当前record的资格。在每次record被改变时都生成新的UUID。

参考文档

《关于在分布式环境中RVN和使用场景的介绍1》

《关于在分布式环境中RVN和使用场景的介绍2》

《关于在分布式环境中RVN和使用场景的介绍3》

相关推荐
久念祈3 小时前
C++ - 仿 RabbitMQ 实现消息队列--服务端核心模块实现(四)
分布式·rabbitmq
MetaverseMan7 小时前
GitHub Actions打包容器,推送 AWS ECR 并使 EKS 自动拉取以完成发版部署
云计算·aws
aiguangyuan7 小时前
前端开发 Vue 组件优化
系统架构·vue·前端开发
白鹭8 小时前
基于LNMP架构的分布式个人博客搭建
linux·运维·服务器·网络·分布式·apache
不辉放弃8 小时前
kafka的消费者负载均衡机制
数据库·分布式·kafka·负载均衡
可观测性用观测云9 小时前
AWS MemoryDB 可观测最佳实践
aws
程序员JerrySUN9 小时前
Linux系统架构核心全景详解
linux·运维·系统架构
java叶新东老师10 小时前
三、搭建springCloudAlibaba2021.1版本分布式微服务-springcloud loadbalancer负载均衡
分布式·spring cloud·微服务
沉下去,苦磨练!12 小时前
kafka的部署和jmeter连接kafka
分布式·jmeter·kafka
蝸牛ちゃん12 小时前
设计模式(七)结构型:适配器模式详解
设计模式·系统架构·软考高级·适配器模式