开篇

同一个用户并发扣款时,有一定概率出现数据不一致,可以使用CAS乐观锁的方式,在不降低吞吐量,保证数据的一致性:

UPDATE t_yue SET money=$new_money

WHERE uid=$uid AND money=$old_money;

不能采用直接扣减的方式

UPDATE t_yue SET money=money-$diff WHERE uid=$uid;

当然,更通用的方式,可以使用版本号来实现CAS乐观锁:

UPDATE t_yue SET money=$new_money,ver=$ver_new 
WHERE uid=$uid AND 
ver=$ver_old;

对于这个CAS乐观锁方案,很有朋友有疑问:当并发量高时,版本号比对会导致大量的更新失败,这个方案不适用于高并发场景吗? 究竟是不是这样呢?大家对高并发是不是有什么误解呢?今天来聊一聊这个话题。

先分析三个业务场景。

一、QQ

QQ的一些核心业务有:

  • 个人:user(uid, user_info, …)

  • 好友:user_friends(uid, friend_id, …)

  • 加入的群:user_groups(uid, group_id, …)

  • 群:group(gid, group_info, …)

  • 群成员:group_members(gid, uid, …)

  • 个人消息:msgs_user(msg_id, uid, …)

  • 群消息:msgs_group(msg_id, gid, …)

这些信息的读写有一个特点,都会带上uid/gid/msgid属性。

例如,拉取好友列表

select friend_id from user_friends where uid=$uid;

在用户量很大,并发量很大时,不同用户/群/消息数据的读写并没有锁冲突。

画外音:10W个用户同时读写,彼此没有锁冲突。

只有当,同一个用户,很短的时间内,有大量并发时,才可能存在锁冲突。

画外音:例如,1个用户,1秒钟读写1W次。

二、微博微博的核心业务是feed流:

  • 发消息,写操作

  • 刷消息,读操作

微博业务显然是读多写少的,在用户刷消息时,自己feed流里的消息,是由别人发出的。

查看自己主页feed流,最朴素的实现方法是:

(1) 拉取自己关注的用户id_list;

(2) 拉取这些用户最近N条消息;

(3) 将这N*id_list条消息排序;

(4) 返回第一页消息,得到自己主页feed流;

画外音:这里不展开读扩散,写扩散, 在用户量很大,并发量很大时,会有一定数据的读写锁冲突。

画外音:不像QQ,基本是读写自己的数据,微博要写自己的数据,读别人的数据。

三、1230612306的核心业务是:

  • 查票,读操作

  • 买票,写操作

stock(id, num) // 某一列车有多少张余票

在用户量很大,并发量很大时,有极大的锁冲突。

画外音:这个业务,数据量并不大。

这类“秒杀”业务,如果不做特殊的优化,数据库很容易死锁卡死,没有任何人能买票成功。

画外音:要做什么特殊的优化呢?

收尾

QQ,微博、12306,同样是高并发业务,就数据存储锁冲突来说,各自的难度,数据不一致的概率是不同的。

画外音:你不能说,QQ不是高并发业务吧。

回到开篇,使用CAS乐观锁进库存扣减:

UPDATE t_yue SET money=$new_money,ver=$ver_new 
WHERE uid=$uid AND 
ver=$ver_old;

只要有uid这个过滤属性,即使10W用户同时扣款,也不容易出现数据不一致。 只有当同一个用户,同一秒钟,有大量扣减时,才有一定几率会冲撞,但也不会导致数据不一致。

画外音:有一位很可爱的水友,说万一PC端和APP端同时下单怎么办。

结论
高并发的扣款场景,可以使用CAS乐观锁,采用select&set方式进行扣款,既能够保证吞吐量,又能够保证一致性。

欢迎关注公众号:“Java架构师学习”

你会喜欢的!

同样是高并发,QQ/微博/12306的架构难度一样吗?的更多相关文章

  1. 一套高可用、易伸缩、高并发的IM群聊架构方案设计实践

    本文原题为“一套高可用群聊消息系统实现”,由作者“于雨氏”授权整理和发布,内容有些许改动,作者博客地址:alexstocks.github.io.应作者要求,如需转载,请联系作者获得授权. 一.引言 ...

  2. 高吞吐高并发Java NIO服务的架构(NIO架构及应用之一)

    高吞吐高并发Java NIO服务的架构(NIO架构及应用之一) http://maoyidao.iteye.com/blog/1149015   Java NIO成功的应用在了各种分布式.即时通信和中 ...

  3. 高并发关于微博、秒杀抢单等应用场景在PHP环境下结合Redis队列延迟入库

    第一步:创建模拟数据表. CREATE TABLE `test_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NUL ...

  4. 达达O2O后台架构演进实践:从0到4000高并发请求背后的努力

    1.引言   达达创立于2014年5月,业务覆盖全国37个城市,拥有130万注册众包配送员,日均配送百万单,是全国领先的最后三公里物流配送平台. 达达的业务模式与滴滴以及Uber很相似,以众包的方式利 ...

  5. jmeter高并发设计方案(转)

    高并发设计方案二(秒杀架构) 优化方向: (1)将请求尽量拦截在系统上游(不要让锁冲突落到数据库上去).传统秒杀系统之所以挂,请求都压倒了后端数据层,数据读写锁冲突严重,并发高响应慢,几乎所有请求都超 ...

  6. python高并发和多线程的关系

    “高并发和多线程”总是被一起提起,给人感觉两者好像相等,实则 高并发 ≠ 多线程 多线程是完成任务的一种方法,高并发是系统运行的一种状态,通过多线程有助于系统承受高并发状态的实现.   高并发是一种系 ...

  7. php-fpm和cgi,并发响应的理解以及高并发和多线程的关系

    首先搞清楚php-fpm与cgi的关系 cgi cgi是一个web server与cgi程序(这里可以理解为是php解释器)之间进行数据传输的协议,保证了传递的是标准数据. php-cgi php-c ...

  8. 想玩转JAVA高并发,这些概念你必须懂!

    我们在找工作时,经常在招聘信息上看到有这么一条:有构建大型互联网服务及高并发等经验,你第一时间想到的是媒体常说的双十一吗?带着问题,我们一起思考技术…. 高并发高并发 它是互联网分布式系统架构设计中必 ...

  9. 想玩转JAVA高并发,这些概念你必须懂

    高并发高并发 它是互联网分布式系统架构设计中必须考虑的因素之一,通常是指,保证系统能够同时并行化处理海量请求 同步和异步 同步:发送一个请求,等待返回,然后再发送下一个请求.提交请求 -> 等待 ...

随机推荐

  1. 【朝花夕拾】Android性能篇之(八)来自官网的自白

    前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10823372.html],谢谢! Android性能优化无疑是Android中的一个重点,也是 ...

  2. 并发编程-多线程,GIL锁

    本章内容: 1.什么是GIL 2.GIL带来的问题 3.为什么需要GIL 4.关于GIL的性能讨论 5.自定义的线程互斥锁与GIL的区别 6.线程池与进程池 7.同步异步,阻塞非阻塞 一.什么是GIL ...

  3. SSM框架之Spring(3)IOC及依赖注入(基于注解的实现)

    Spring(3)IOC及依赖注入(基于注解的实现) 学习基于注解的 IoC 配置,大家脑海里首先得有一个认知,即注解配置和 xml 配置要实现的功能都是一样 的,都是要降低程序间的耦合.只是配置的形 ...

  4. Python Web(二)

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.Django-debug-toolbar django-debug-toolbar 是一组可配置的面板,可显示 ...

  5. SQL高效运行注意事项(四)

    为了SQLSERVER能高效运行,SQLSERVER的磁盘子系统是一个重要的方面 Avg. Disk Sec/Read 这个计数器是指每秒从磁盘读取数据的平均值 下面的列表显示这个计数器值的范围,并指 ...

  6. mtu测试

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/jeromezmzx007/article ...

  7. fallowing-travelvue

    1. 2.Header.vue 3.Swiper.vue . 4.Icons.vue 解决了上次轮播图--分页小圆点不显示的问题,本来以为图片应该都可以,结果换了轮播长图之后,小圆点听话的显示出啦 而 ...

  8. SpringCloud学习笔记(二、SpringCloud Config)

    目录: 配置中心简介 SpringCloud Config服务端 SpringCloud Config客户端 动态配置属性bean 一些补充(源码分析):Spring事件监听.健康检查health() ...

  9. acwing 7 混合背包

    习题地址  https://www.acwing.com/problem/content/description/7/ 题目描述有 N 种物品和一个容量是 V 的背包. 物品一共有三类: 第一类物品只 ...

  10. C++ 数据类型判断 typeid

    #include <iostream> // typeid testing //////////////////////////////////////////////////////// ...