当前位置: 首页 > news >正文

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

简介

在《关于在分布式环境中RVN和使用场景的介绍2》和《关于在分布式环境中RVN和使用场景的介绍1》中我们介绍了RVN的概念和在一些具体用例中的使用。在本文中我们讨论一下在分布式环境中使用RVN需要注意的问题。

问题

我们在收到一条待处理的事件时,需要检查该事件的RVN是否已经太旧。如果该事件的RVN已经太旧,我们就不再处理该事件,并且丢弃该事件。通过这个逻辑,我们可以保障在分布式环境中正确的处理消息的乱序,丢失,和重复等问题。就这个逻辑本身而言是非常简单的。但是我们现在要考虑到分布式环境中所有的消息处理都是并行的,我们需要小心的检查这个逻辑的实现。在本文中,我们讨论一下如何在分布式环境中正确的处理这个逻辑。

解决方案

关于RVN更新的基本逻辑和它所能解决的问题,可以参看《关于在分布式环境中RVN和使用场景的介绍1》。下面是基于两种不同方法的RVN的实现方案。

基于锁的解决方案

在并行编程中,锁(lock)是很常见的工具。锁的功能是可以在多个并行逻辑都想访问同一个资源时进行同步。具体来说,我们可以认为锁提供了如下的接口:

Acquire(key)Release(key)

当一个并行逻辑试图访问某个资源(该资源以“key”作为标识),它需要先lock该资源的key。假如没有其它的并行逻辑已经获得该资源的锁,则此并行逻辑可以获得该资源的锁,并且可以继续执行以使用该资源;否则此并行逻辑将被阻塞在该锁上,直到使用该资源的其它并行逻辑release了该锁。

在分布式环境中同样可以实现lock。比如AWS里的DynamoDB Lock Client。这是一个基于DynamoDB的表实现的锁,任何AWS里的计算资源(比如Lambda,ECS,EC2)都可以通过创建DynamoDB Lock Client以达到互相同步的目的。关于DynamoDB Lock Client的具体介绍可以参看这里。

下面是一个可以正常工作的使用DynamoDB Lock Client来维护RVN的逻辑流程:

在这里我们需要注意对于RVN的检查和RVN检查以后对于当前消息的处理都必须一直在持有锁的状态下执行。这是因为一旦锁已经释放,就有可能更新的RVN的消息开始被处理,从而和更新RVN和消息处理产生冲突。

基于锁的解决方案的缺点是需要额外的二次DynamoDB的操作,也就是对锁的获取和释放。当我们需要处理很多消息时,这样做的效率是比较低的,同时也会产生大量额外的费用。

基于DynamoDB的Condition Update的解决方案

另一种对RVN的维护方式可以使用DynamoDB的condition update。DynamoDB的condition update允许我们在update的请求里指定一些条件,只有当该条件满足时该update的请求才会被执行,否则就会被拒绝。关于DynamoDB的condition update可以参看这个文档。

利用condition update,我们可以使用RVN作为condition,要求被更新的数据或者不存在,或者RVN小于新的数据。该condition会被如下形式定义:

attribute_not_exists(#hashKey) OR (#versionNumber <= :versionNumber)

当我们使用condition update来解决冲突问题时,我们应该考虑将RVN和被存储的数据写在一个表中,从而可以使用condition update在更新数据时检查RVN是否是新的RVN。这个方案解决了需要额外访问DynamoDB的问题,但是这个方案的缺点也很明显,就是对于复杂的处理的逻辑灵活性很差。比如说我们考虑使用收到的消息更新两个表的数据。那么我们就必须在两个表中都存储RVN的信息。再比如说我们需要使用收到的两种消息更新同一个表。那么我们就必须在一个表中维护两种消息的RVN。当消息的处理逻辑比较复杂时,这种混乱的表定义无疑会增加开发和维护的难度。

问题的扩展

现在我们考虑如果我们的消息里有大量的消息是针对同一个key的,也就是说大量的消息之间需要同步执行。假如我们使用锁的方案,我们就会发现这些消息本质上是串行处理的,效率很低。在这里我们除了可以考虑使用《关于在分布式环境中RVN和使用场景的介绍2》中提到的方法来减少需要处理的消息数量外,还可以在获取锁之前先检查RVN是否有效来达到优化的目的。

我们具体来考虑如下的例子。我们收到RVN的顺序是:1,4,3, 2,5。假如我们按照普通的流程,我们需要串行处理这五条消息。其中每一条都需要两次DynamoDB的操作(也就是锁的获取和释放),其中RVN 1,4,5需要消息的处理,所以我们总共需要10次DynamoDB的操作,3次次消息处理,总共有5条消息被串行处理。但是如果我们在试图获取锁之前,先检查RVN是否已经太旧,我们就会在获取锁之前将RVN 3和2丢弃,所以我们只需要6次DynamoDB的操作,3次消息处理,总共有3条消息被串行处理。这样的流程图如下所示:

在这里我们有两点需要注意:

  • 第一,即便我们有了这个防御机制,我们在获取锁之后对于仍然需要对RVN进行第二次检查。这是因为在我们获取锁的过程中,我们的RVN有可能已经变得不再有效。
  • 第二,第一次对于RVN的检查仍然需要一次DynamoDB的读操作。如果该次检查RVN是有效的,则该次DynamoDB的读是浪费的。所以是否采用这种防御机制仍然需要根据具体情况决定,并不能保证一定是更好的方案。

通过对本文中问题的讨论,我们可以看到在分布式环境中编写程序是复杂和混乱的,当然带来的好处就是效率的提升,未来扩展的灵活,还有容错性增强等等。但是我们需要主要注意的是在分布式环境中给出一个简介同时高效的设计尤为重要,因为一旦在分布式环境中出现设计上的缺陷以及设计上的重构,都会比集中环境要复杂的多。我们会在以后的文章中对其它一些模式做进一步讨论。

相关文章:

  • Kafka集群安装与部署
  • 力扣-1. 两数之和
  • 华为问界M9:领跑未来智能交通的自动驾驶黑科技
  • ACK One Argo工作流:实现动态 Fan-out/Fan-in 任务编排
  • TinUI v5预发布记录
  • Javaweb之SpringBootWeb案例之propagation属性案例演示的详细解析
  • 使用C++从零开始,自己写一个MiniWeb
  • 贪心算法之找零钱
  • openJudge | 距离排序 C语言
  • OCP使用web console创建和构建应用
  • 设计模式理解:单例模式+工厂模式+建设者模式+原型模式
  • macbook电脑如何永久删除app软件?
  • 使用C#快速创建一个非常实用的桌面应用程序
  • 设计模式-建造者模式Builder
  • 【开源】SpringBoot框架开发桃花峪滑雪场租赁系统
  • 分享一款快速APP功能测试工具
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • mysql 数据库四种事务隔离级别
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • React-生命周期杂记
  • Transformer-XL: Unleashing the Potential of Attention Models
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • 近期前端发展计划
  • 利用jquery编写加法运算验证码
  • 如何设计一个比特币钱包服务
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 用Canvas画一棵二叉树
  • 鱼骨图 - 如何绘制?
  • 在electron中实现跨域请求,无需更改服务器端设置
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • ​flutter 代码混淆
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (3)nginx 配置(nginx.conf)
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .net core 6 redis操作类
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • .NET面试题(二)
  • .NET项目中存在多个web.config文件时的加载顺序
  • .net专家(高海东的专栏)
  • @ConditionalOnProperty注解使用说明
  • @select 怎么写存储过程_你知道select语句和update语句分别是怎么执行的吗?
  • @Valid和@NotNull字段校验使用
  • [20170713] 无法访问SQL Server
  • [2023年]-hadoop面试真题(一)
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [Android]Android开发入门之HelloWorld
  • [BZOJ 3282] Tree 【LCT】
  • [ccc3.0][数字钥匙] UWB配置和使用(二)