当前位置: 首页 > 科技观察

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

时间:2023-03-18 21:04:27 科技观察

文章开头,同一个用户并发扣款时,有一定概率出现数据不一致的情况。您可以使用CAS乐观锁定来确保数据一致性而不降低吞吐量:UPDATEt_yueSETmoney=$new_moneyWHEREuid=$uidANDmoney=$old_money;更详细的说明见《并发扣款,如何保证数据的一致性?》。不能直接扣:UPDATEt_yueSETmoneymoney=money-$diffWHEREuid=$uid;更详细的描述见《并发扣款一致性,幂等性问题》。当然,更通用的方式,可以使用版本号来实现CAS乐观锁:UPDATEt_yueSETmoney=$new_money,ver=$ver_newWHEREuid=$uidANDver=$ver_old;更详细的说明,请看《并发扣款一致性优化,CAS下ABA问题》。对于这种CAS乐观锁方案,很多朋友都有疑惑:在并发高的时候,版本号比较会导致大量的更新失败。这个方案不适合高并发场景吗?是这样吗?大家关心的高并发是不是有什么误解?今天就来聊聊这个话题。首先分析三个业务场景。1、QQQQ部分核心业务包括:个人: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属性。例如拉取好友列表:selectfriend_idfromuser_friendswhereuid=$uid;当用户量大,并发量大时,不同用户/组/消息数据的读写不存在锁冲突。画外音:10万用户同时读写,互不锁冲突。只有当同一个用户在短时间内有大量的并发时,才有可能出现锁冲突。画外音:比如1个用户每秒读写10000次。2.微博微博的核心业务是feed流:发送消息,写操作刷新消息,读操作阅读更多。派遣。查看主页提要流的最简单方法是:拉取您关注的用户的id_list;从这些用户那里拉取最新的N条消息;对N*id_list消息进行排序;返回首页消息获取自己的首页feed流;当用户量大,并发量大时,某些数据会出现读写锁冲突。画外音:与QQ基本读写自己的数据不同,微博需要写自己的数据,读取别人的数据。3、1230612306的核心业务是:查票、读操作买票、写操作stock(id,num)//某趟车还有多少张票?锁冲突。画外音:这个业务的数据量不大。对于这种“秒杀”的业务,如果不做特别的优化,数据库很容易死锁卡死,谁也买不到票成功。画外音:应该做哪些特别的优化?结束QQ、微博、12306也是高并发服务。就数据存储锁冲突而言,各自的难度和数据不一致的概率是不同的。画外音:你不能说QQ不是高并发业务。回到开头,使用CAS乐观锁定库存扣除:UPDATEt_yueSETmoney=$new_money,ver=$ver_newWHEREuid=$uidANDver=$ver_old;只要有uid的filter属性,即使10W用户同时扣钱,也不会轻易出现数据不一致的情况。只有当同一用户在同一秒内有大量扣款时,才会有一定的碰撞几率,但不会造成数据不一致。画外音:有个很可爱的水友说PC和APP同时下单怎么办。结论对于高并发的推演场景,可以使用CAS乐观锁,使用select&set方式进行推演,既能保证吞吐量,又能保证一致性。【本文为专栏作者《58神剑》原创稿件,转载请联系原作者】点此阅读更多该作者好文