如何解决秒杀的性能问题和超卖的讨论
最近业务试水电商,接了一个秒杀的活。之前经常看到淘宝的同行们讨论秒杀,讨论电商,这次终于轮到我们自己理论结合实际一次了。
ps:进入正文前先说一点个人感受,之前看淘宝的ppt感觉都懂了,等到自己出解决方案的时候发现还是有很多想不到的地方其实都没懂,再次验证了“细节是魔鬼”的理论。并且一个人的能力有限,只有大家一起讨论才能想的更周全,更细致。好了,闲话少说,下面进入正文。
一、秒杀带来了什么?
秒杀或抢购活动一般会经过【预约】【抢订单】【支付】这3个大环节,而其中【抢订单】这个环节是最考验业务提供方的抗压能力的。
抢订单环节一般会带来2个问题:
1、高并发
比较火热的秒杀在线人数都是10w起的,如此之高的在线人数对于网站架构从前到后都是一种考验。
2、超卖
任何商品都会有数量上限,如何避免成功下订单买到商品的人数不超过商品数量的上限,这是每个抢购活动都要面临的难题。
二、如何解决?
首先,产品解决方案我们就不予讨论了。我们只讨论技术解决方案
1、前端
面对高并发的抢购活动,前端常用的三板斧是【扩容】【静态化】【限流】
A:扩容
加机器,这是最简单的方法,通过增加前端池的整体承载量来抗峰值。
B:静态化
将活动页面上的所有可以静态的元素全部静态化,并尽量减少动态元素。通过CDN来抗峰值。
C:限流
一般都会采用IP级别的限流,即针对某一个IP,限制单位时间内发起请求数量。
或者活动入口的时候增加游戏或者问题环节进行消峰操作。
D:有损服务
最后一招,在接近前端池承载能力的水位上限的时候,随机拒绝部分请求来保护活动整体的可用性。
2、后端
那么后端的数据库在高并发和超卖下会遇到什么问题呢?主要会有如下3个问题:(主要讨论写的问题,读的问题通过增加cache可以很容易的解决)
I: 首先MySQL自身对于高并发的处理性能就会出现问题,一般来说,MySQL的处理性能会随着并发thread上升而上升,但是到了一定的并发度之后会出现明显的拐点,之后一路下降,最终甚至会比单thread的性能还要差。
II: 其次,超卖的根结在于减库存操作是一个事务操作,需要先select,然后insert,最后update -1。最后这个-1操作是不能出现负数的,但是当多用户在有库存的情况下并发操作,出现负数这是无法避免的。
III:最后,当减库存和高并发碰到一起的时候,由于操作的库存数目在同一行,就会出现争抢InnoDB行锁的问题,导致出现互相等待甚至死锁,从而大大降低MySQL的处理性能,最终导致前端页面出现超时异常。
针对上述问题,如何解决呢? 我们先看眼淘宝的高大上解决方案:
I: 关闭死锁检测,提高并发处理性能。
II:修改源代码,将排队提到进入引擎层前,降低引擎层面的并发度。
III:组提交,降低server和引擎的交互次数,降低IO消耗。
以上内容可以参考丁奇在DTCC2013上分享的《秒杀场景下MySQL的低效》一文。在文中所有优化都使用后,TPS在高并发下,从原始的150飙升到8.5w,提升近566倍,非常吓人!!!
不过结合我们的实际,改源码这种高大上的解决方案显然有那么一点不切实际。于是小伙伴们需要讨论出一种适合我们实际情况的解决方案。以下就是我们讨论的解决方案:
首先设定一个前提,为了防止超卖现象,所有减库存操作都需要进行一次减后检查,保证减完不能等于负数。(由于MySQL事务的特性,这种方法只能降低超卖的数量,但是不可能完全避免超卖)
update number set x=x-1 where (x -1 ) >= 0;
解决方案1:
将存库从MySQL前移到Redis中,所有的写操作放到内存中,由于Redis中不存在锁故不会出现互相等待,并且由于Redis的写性能和读性能都远高于MySQL,这就解决了高并发下的性能问题。然后通过队列等异步手段,将变化的数据异步写入到DB中。
优点:解决性能问题
缺点:没有解决超卖问题,同时由于异步写入DB,存在某一时刻DB和Redis中数据不一致的风险。
解决方案2:
引入队列,然后将所有写DB操作在单队列中排队,完全串行处理。当达到库存阀值的时候就不在消费队列,并关闭购买功能。这就解决了超卖问题。
优点:解决超卖问题,略微提升性能。
缺点:性能受限于队列处理机处理性能和DB的写入性能中最短的那个,另外多商品同时抢购的时候需要准备多条队列。
解决方案3:
将写操作前移到MC中,同时利用MC的轻量级的锁机制CAS来实现减库存操作。
优点:读写在内存中,操作性能快,引入轻量级锁之后可以保证同一时刻只有一个写入成功,解决减库存问题。
缺点:没有实测,基于CAS的特性不知道高并发下是否会出现大量更新失败?不过加锁之后肯定对并发性能会有影响。
解决方案4:
将提交操作变成两段式,先申请后确认。然后利用Redis的原子自增操作(相比较MySQL的自增来说没有空洞),同时利用Redis的事务特性来发号,保证拿到小于等于库存阀值的号的人都可以成功提交订单。然后数据异步更新到DB中。
优点:解决超卖问题,库存读写都在内存中,故同时解决性能问题。
缺点:由于异步写入DB,可能存在数据不一致。另可能存在少买,也就是如果拿到号的人不真正下订单,可能库存减为0,但是订单数并没有达到库存阀值。
三、总结
1、前端三板斧【扩容】【限流】【静态化】
2、后端两条路【内存】+【排队】
四、非技术感想
1、团队的力量是无穷的,各种各样的解决方案(先不谈可行性)都是在小伙伴们七嘴八舌中讨论出来的。我们需要让所有人都发出自己的声音,不要着急去否定。
2、优化需要从整体层面去思考,不要只纠结于自己负责的部分,如果只盯着一个点思考,最后很可能就走进死胡同中了。
3、有很多东西以为读过了就懂了,其实不然。依然还是需要实践,否则别人的知识永远不可能变成自己的。
4、多思考为什么,会发生什么,不要想当然。只有这样才能深入进去,而不是留在表面。
ps:以上仅仅是我们讨论的一些方案设想,欢迎大家一起讨论各种可行方案。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

2024淘寶免單活動每日三場,大家需要在對應時間下單付款對應金額的商品,免單金額是以等額紅包形式發放,接下來給大家帶來了淘寶免單紅包領取方法2024:搶到免單的用戶,紅包資格將發放至卡券包,為待激活狀態;網頁版淘寶暫無卡券包,僅做免單活動的中獎記錄的展示;卡券包在【淘寶APP-我的淘寶-我的權益-紅包】。淘寶免單紅包領取方式20241、搶到免單的用戶,紅包資格將發放至卡券包,為待激活狀態;2、網頁版淘寶暫無卡券包,僅做免單活動的中獎記錄的展示;3、卡券包在【淘寶APP-我的淘寶-我的權益-紅包】

改名功能在淘寶中可以讓用戶自由改名字暱稱,有些用戶並不知道淘寶怎麼改名字,在我的淘寶中的設定裡點擊頭像的淘寶帳號進行修改即可,接下來小編就為大家帶來了改名字暱稱方法的介紹,還不知道的用戶快來下載試試看。淘寶使用教學淘寶怎麼改名字答:在我的淘寶中的設定裡點擊頭像的淘寶帳號進行修改即可詳情介紹:1、進入淘寶,點擊右下【我的淘寶】。 2.點選右上的【設定】圖示。 3.點擊頭像。 4、再點【淘寶帳號】。 5.點選【修改帳號名】,輸入修改即可。

淘寶是許多小夥伴們常用的網購軟體,平常很多東西各位都會從裡面下單購買,裡面給用戶們提供了紅包提醒功能,有的朋友們想要來關掉,那麼就趕快來PHP中文網看看吧。淘寶關閉紅包提醒步驟一覽1、開啟淘寶APP的個人中心,選擇【設定】按鈕進入頁面。 2.找到【訊息通知】選項,在這裡可以選擇訊息推播開關,找到紅包訊息將開關關閉就可以了。 3.或也可以透過手機的設定頁面,將淘寶APP的通知權限關閉,這樣所有來自淘寶的訊息都不會進入推播,只有開啟後才能看到。 4.使用者可以自己設定想要接收哪些類型的訊息,這樣使用起來也

淘寶510免單紅包怎麼用?淘寶近期開展了510週年慶的免單活動,這個活動是可以獲得免單紅包的,福利非常的多,相信很多小伙伴都想參與這個活動,也有小伙伴已經領取到了免單紅包,但是卻不知道具體的用法,今天就帶大家一起來看看相關的介紹。淘寶510週年慶免單紅包使用介紹使用方:猜題下單的所有訂單確認收貨後,免單紅包即可使用。一、免單紅包發放及追回用戶可以透過網頁版淘寶暫無卡券包,但可在【淘寶APP-我的淘寶-我的權益-紅包】處查看。搶到免單的用戶,紅包資格將發放至卡券包,為待啟動狀態;卡券包在進行中獎

在淘寶購物時,我們經常會使用免單紅包來享受優惠。但是,如果我們需要退款,這些免單紅包會被退回嗎?讓我們來看看這個問題的答案。淘寶免單紅包退款會退回嗎分情況而論獲得紅包時,紅包是待激活狀態,在兌換商品之前,這個待激活的紅包是沒有激活的,暫時無法使用,等購買的商品確認收貨之後,待啟動狀態的紅包才可使用。免單紅包使用後商品有問題需要退貨,那麼紅包的退貨需要按照實際情況來判斷:一、退款規則11、紅包使用後發生退款,則紅包按比例退回。 2.在未逾期的情況下,退回紅包的使用期限為原定使用期限,若逾期7天內發

C++中機器學習演算法面臨的常見挑戰包括記憶體管理、多執行緒、效能最佳化和可維護性。解決方案包括使用智慧指標、現代線程庫、SIMD指令和第三方庫,並遵循程式碼風格指南和使用自動化工具。實作案例展示如何利用Eigen函式庫實現線性迴歸演算法,有效地管理記憶體和使用高效能矩陣操作。

1.開啟淘寶app,點選右下角的【我的淘寶】,點選右上角【設定】。 2.選擇【商家入駐】,點選【淘寶開店】,選擇【普通商家】。 3.在【免費開店】介面,使用者可以看到【個人商家】開店的具體流程。 4.為自己的小店命名,然後點選【去開店】,三項全部勾選,點選【0元開店】。 5.最後完成【實人認證】,完善【店鋪基礎資訊】即可成功開店。

淘寶大贏家3月31日問題:唐朝時,人們還可以稱父親為?有很多用戶不知道唐朝時,人們還可以稱父親為什麼?,那麼接下來小編就為大家帶來了3.31淘寶大贏家每日一猜今日答案分享,有興趣的朋友快來了解一下吧。淘寶每日一猜答案大全淘寶大贏家3月31日:唐朝時,人們還可以稱父親為?問題:唐朝時,人們還可以稱父親為?答案:B.哥哥答案解析:1、點擊進來找線索,在如下圖的頁面即可找到問題的答案;2、唐代人可以稱父親為哥哥,《舊唐書·王琚傳》中“玄宗曰:四哥仁孝”;3、這裡的“四哥”,指的是玄宗的父親睿宗,在同
