架构与思维:漫谈高并发业务的CAS及ABA

1 高并发场景下的难题

1.1 典型支付场景

这是最经典的场景。支付过程,要先查询买家的账户余额,然后计算商品价格,最后对买家进行进行扣款,像这类的分布式操作,如果是并发量低的情况下完全没有问题的,但如果是并发扣款,那可能就有一致性问题。在高并发的分布式业务场景中,类似这种 “查询+修改” 的操作很可能导致数据的不一致性。

image

1.2 在线下单场景

同理,买家在电商平台下单,往往会涉及到两个动作,一个是扣库存,第二个是更新订单状态,库存和订单一般属于不同的数据库,需要使用分布式事务保证数据一致性。

image

1.3 跨行转账场景

跨行转账问题也是一个典型的分布式事务,用户A同学向B同学的账户转账500,要先进行A同学的账户-500,然后B同学的账户+500,既然是 不同的银行,涉及不同的业务平台,为了保证这两个操作步骤的一致,数据一致性方案必然要被引入。

image

2 CAS方案

分布式CAS(Compare-and-Swap)模式就是一种无锁化思想的应用,它通过无锁算法实现线程间对共享资源的无冲突访问,既保证性能高效,有保证数据的强一致性,避免了上面集中问题的产生。CAS模式包含三个基本操作数:内存地址V、旧的预期值A和要修改的新值B。在更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。

我们以 1.1节 的 典型支付场景 作为例子分析(参考下图):

  • 初始余额为 800

  • 业务1和业务2同时查询余额为800

  • 业务1执行购买操作,扣减去100,结果是700,这是新的余额。理论上只有在原余额为800时,扣减的Action才能执行成功。

  • 业务2执行生活缴费操作(比如自动交电费),原余额800,扣减去200,结果是600,这是新的余额。理论上只有在原余额为800时,扣减的Action才能执行成功。可实际上,这个时候数据库中的金额已经变为600了,所以业务2的并发扣减不应该成功。

根据上面的CAS原理,在Swap更新余额的时候,加上Compare条件,跟初始读取的余额比较,只有初始余额不变时,才允许Swap成功,这是一种常见的降低读写锁冲突,保证数据一致性的方法。

image

3 引出ABA问题

在CAS(Compare-and-Swap)操作中,ABA问题是一个常见的挑战。这边假设三个操作数——内存位置(V)、预期原值(A)和新值(B)。ABA问题是指当某个线程读取一个共享变量V的值为A,之后准备将其更新为B时,另一个线程可能已经将其从A改为了B,然后又改回了A。此时,当前线程仍认为V的值是原始的A,因此CAS操作会将V的值更新为B,但实际上V的值已经被其他线程改变过。

image

它有如下危害:

1. 数据一致性受损,并导致业务逻辑错误在复杂的业务逻辑中,共享变量的值往往代表了某种业务状态或条件。ABA问题可能导致这些状态或条件被意外地改变,从而引发业务逻辑错误,如库存超卖、资金重复发放等。★ 以下的图详细描述了ABA是怎么导致库存逻辑出错的:

image

2. 难以调试与定位ABA问题通常发生在多线程环境下,且其触发条件较为隐蔽。因此,当系统出现由ABA问题导致的异常时,往往难以快速定位问题原因,增加了调试的复杂性和时间成本。

4 不同维度的处理方式

ABA出现的原因,是CAS的过程中,只关注Value值的校验。但是忽略了这个值还是不是之前的那个值,可以参考上面的库存图例。所以某些情况下,Value虽然相同,却已经不是原来的数据了。

解决方案:CAS不能只比对 Value,还必须确保的是原来的数据,才能修改成功。一般的做法是,给 Value 设置一个Version(版本号),用来比对,一个数据一个版本,每次数据变化的时候版本跟随变化,这样的话就不会随随便便修改成功。

4.1 应用程序层

Java中的java.util.concurrent.atomic包提供了解决ABA问题的工具类。在Go语言中,通常使用sync/atomic包提供的原子操作来处理并发问题,并引入版本号或时间戳的概念。示例代码如下:

type ValueWithVersion struct {  Value     int32  Version   int32  
}  var sharedValue atomic.Value // 使用atomic.Value来存储ValueWithVersion的指针  func updateValue(newValue, newVersion int32) bool {  current := sharedValue.Load().(*ValueWithVersion)  if current.Value == newValue && current.Version == newVersion {  // CAS操作:只有当前值和版本号都匹配时,才更新值  newValueWithVersion := &ValueWithVersion{Value: newValue, Version: newVersion + 1}  sharedValue.Store(newValueWithVersion)  return true  }  return false  
}  

4.2 数据层

1、CAS策略

update stock set num_val=$num_new_val where sid=$sid and num_val=$num_old_val

2、CAS策略+Version,避免ABA问题

# 这边注意,有了version,就没必要再比较old_val了
update stock set num=$num_new_val, version=$version_new where sid=$sid and version=$version_old

5 总结

  1. 高并发下的难题:支付、下单、跨行转账

  2. CAS方案以及引发的ABA问题

  3. 不同维度的处理方式:应用层、数据层

文章转载自:Hello-Brand

原文链接:https://www.cnblogs.com/wzh2010/p/18031157

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/444173.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

其他:python语言绘制案例

文章目录 介绍导入python包图1图2 介绍 python语言的科研绘图合集,数据来源Hydrogen-diffusion-and-water-rock-reaction 导入python包 import pandas as pd import glob import proplot as pplt import seaborn as sns import numpy as np import matplotlib.py…

基于 Prometheus+Grafana+Alertmanager 搭建 K8S 云监控告警平台(附配置告警至QQ、钉钉)

文章目录 一、机器规划二、部署安装 node-exporter、prometheus、Grafana、kube-state-metrics1、创建 monitor-sa 命名空间2、安装node-exporter组件2.1、说明2.2、应用资源清单2.3、通过node-exporter采集数据 3、k8s 集群中部署 prometheus3.1、创建一个 sa 账号3.2、将 sa …

element-ui的树形结构样式调整,添加线条和边框样式

element-ui的树形结构样式调整&#xff0c;添加线条和边框样式 先看图效果&#xff1a; <template><div class"temperature_monitoring"><div class"temperature_monitoring_left"><div class"tree-container"><e…

鸿蒙NEXT开发-动画(基于最新api12稳定版)

注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&#xff0c;博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…

PostgreSQL数据库定期清理归档(pg_wal)日志

一、配置归档模式 在postgresql.conf文件中设置archive_mode on来启用归档功能。 二、设置归档命令 同样在postgresql.conf中&#xff0c;设置archive_command参数&#xff0c;指定一个shell命令来处理归档日志&#xff0c;例如&#xff1a; archive_command cp %p /home/…

若依项目搭建(黑马经验)

欢迎你搜索和了解到若依&#xff0c;这个项目是从黑马课程的一个实践&#xff0c;更多的项目经历和平台搭建期待着我们的共同学习&#xff01; 关于若依 若依是一套全部开源的快速开发平台&#xff0c;毫无保留给个人及企业免费使用。 前端采用Vue、Element UI。后端采用Sprin…

无人机之巡航控制篇

一、巡航控制的基本原理 无人机巡航控制的基本原理是通过传感器检测无人机的飞行状态和环境信息&#xff0c;并将其反馈给控制器。控制器根据反馈信息和任务需求&#xff0c;计算出无人机的控制指令&#xff0c;并将其发送给执行机构。执行机构根据控制器的控制指令&#xff0c…

linux线程 | 线程的概念

前言:本篇讲述linux里面线程的相关概念。 线程在我们的教材中的定义通常是这样的——线程是进程的一个执行分支。 线程的执行粒度&#xff0c; 要比进程要细。 我们在读完这句话后其实并不能很好的理解什么是线程。 所以&#xff0c; 本节内容博主将会带友友们理解什么是线程&a…

从加载到对话:使用 Llama-cpp-python 本地运行量化 LLM 大模型(GGUF)

&#xff08;无需显卡&#xff09;使用 Llama-cpp-python 在本地加载具有 70 亿参数的 LLM 大语言模型&#xff0c;通过这篇文章你将学会用代码创建属于自己的 GPT。 建议阅读完 19a 的「前言」和「模型下载」部分后再进行本文的阅读。 代码文件下载 - Llama-cpp-python 文章目…

字节跳动青训营开始报名了!

关于青训营&#xff1a; 青训营是字节跳动技术团队发起的技术系列培训 &人才选拔项目;面向高校在校生&#xff0c;旨在培养优秀且具有职业竞争力的开发工程师。 本次技术训练营由掘金联合豆包MarsCode 团队主办课程包含前端、后端和 A 方向&#xff0c;在这个飞速发…

彩族相机内存卡恢复多种攻略:告别数据丢失

在数字时代&#xff0c;相机内存卡作为我们存储珍贵照片和视频的重要媒介&#xff0c;其数据安全性显得尤为重要。然而&#xff0c;意外删除、错误格式化、存储卡损坏等情况时有发生&#xff0c;导致数据丢失&#xff0c;给用户带来不小的困扰。本文将详细介绍彩族相机内存卡数…

服装生产管理的数字化转型:SpringBoot框架

4 系统设计 4.1 系统结构设计 在结构设计过程中&#xff0c;首先对系统进行需求分析&#xff0c;然后进行系统初步设计&#xff0c;将系统功能模块细化&#xff0c;具体分析每一个功能模块具体应该首先哪些功能&#xff0c;最后将各个模块进行整合&#xff0c;实现系统结构的…

R语言的Meta分析【全流程、不确定性分析】方法与Meta机器学习技术应用

Meta分析是针对某一科研问题&#xff0c;根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法&#xff0c;对来源不同的研究成果进行收集、合并及定量统计分析的方法&#xff0c;最早出现于“循证医学”&#xff0c;现已广泛应用于农林生态&#xff0c;资源环境等方面。…

RelationGraph实现工单进度图——js技能提升

直接上图&#xff1a; 从上图中可以看到整个工单的进度是从【开始】指向【PCB判责】【完善客诉】【PCBA列表】&#xff0c;同时【完善客诉】又可以同时指向【PCB判责】【PCBA列表】&#xff0c;后续各自指向自己的进度。 直接上代码&#xff1a; 1.安装 1.1 Npm 方式 npm …

PostgreSQL学习笔记七:常规SQL操作

PostgreSQL 支持标准的 SQL 语句&#xff0c;同时也扩展了一些特有的功能。以下是一些常规的 SQL 语句示例&#xff0c;这些示例涵盖了数据定义、数据操作和数据查询的基本操作&#xff1a; 数据定义语言 (DDL 创建数据库&#xff1a; CREATE DATABASE mydatabase;创建表&#…

安卓使用.9图实现阴影效果box-shadow: 0 2px 6px 1px rgba(0,0,0,0.08);

1.安卓实现阴影效果有很多种&#xff0c;一般UX设计会给以H5参数box-shadow: 0 2px 6px 1px rgba(0,0,0,0.08);这种方式提供背景阴影效果&#xff0c;这里记录一下实现过程 2.界面xml源码 <?xml version"1.0" encoding"utf-8"?> <layout xmlns…

鸿蒙架构-系统架构师(七十八)

1信息加密是保证系统机密性的常用手段。使用哈希校验是保证数据完整性的常用方法。可用性保证合法用户对资源的正常访问&#xff0c;不会被不正当的拒绝。&#xff08;&#xff09;就是破坏系统的可用性。 A 跨站脚本攻击XSS B 拒绝服务攻击DoS C 跨站请求伪造攻击CSRF D 缓…

MQTT vs HTTP:谁更适合物联网?

前言 随着物联网&#xff08;IoT&#xff09;技术的飞速发展中&#xff0c;其应用规模和使用场景正在持续扩大&#xff0c;但它关键的流程仍然是围绕数据传输来进行的&#xff0c;因此设备通信协议选择至关重要。 作为两种主要的通信协议&#xff0c;MQTT 协议和 HTTP 协议各…

网络资源模板--Android Studio 实现简易计算器App

目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 一、项目演示 网络资源模板--基于Android studio 实现的简易计算器 二、项目测试环境 三、项目详情 动态绑定按钮&#xff1a; 使用循环遍历 buttons 数组&#xff0c;根据动态生成的按钮 ID (btn_0, …

【环境搭建】MAC M1安装ElasticSearch

STEP1 官网下载ES Download Elasticsearch | Elastic&#xff0c;下载mac m1对应版本的es STEP2 进入bin文件夹&#xff0c;执行./elasticSearch 浏览器输入 127.0.0.1:9200 STEP 3 下载对应Kibana版本&#xff0c;Download Kibana Free | Get Started Now | Elastic 出现报错…