• 同样是高并发,QQ/微博/12306的架构难度一样吗?


    开篇

    同一个用户并发扣款时,有一定概率出现数据不一致,可以使用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架构师学习”

    你会喜欢的!

  • 相关阅读:
    Java 利用SWFUpload多文件上传 session 为空失效,不能验证的问题 swfUpload多文件上传
    对ExtJS4应用 性能优化的几点建议
    Extjs4中用combox做下拉带图片的下拉框
    当你的才华还撑不起你的野心时,就应该静下心来学习(转)
    占位符行为 PlaceHolderBehavior 的实现以及使用
    一个简单的TabItem样式。
    WPF实现Twitter按钮效果(转)
    模仿36。杀毒~button(转)
    WPF自适应可关闭的TabControl 类似浏览器的标签页(转)
    WPF绘制简单常用的Path(转)
  • 原文地址:https://www.cnblogs.com/xueSpring/p/11540401.html
Copyright © 2020-2023  润新知