其實真是的秒殺不是這樣的
作為java的多年經(jīng)驗的碼農覺得老師的東西很怪異,CAS原理都不講的,你用mysql的鎖去應對秒殺基本就死在哪里了。
1、老師說得這個行鎖很怪異,mysql根本就沒有這個東西,沒有加for update你會有行鎖嗎?不知道老師所謂的行鎖是從天而降嗎??這個稱為悲觀鎖。但是代價太大,我們基本不用。因為使用它,你所有的線程就等著掛起和等待了,系統(tǒng)就基本就死在哪里了。
2、一般我們即時使用數(shù)據(jù)庫,也不會這樣用,應該加一個version字段。
(1)首先是程序讀取select? version, left from table;
(2)然后記錄version字段(舊值),判定left - buyCount(購買數(shù)量)>=0,如果否退出,結束業(yè)務。否則繼續(xù)(3)
(3)開始執(zhí)行減庫存
update table set left = left - #{byCount} , version =? version+1
where count >0 and vesion = #{vesion}//這個version是舊值,而更新一次成功version就加1
這里數(shù)據(jù)庫并沒有任何鎖,但是這里巧妙的使用了version字段,符合一個CAS原理,就是我當初讀出的version(舊值)和實時數(shù)據(jù)庫的version(當前需要更新時刻的實時值)是否一致,如果一致,則我會認為這條記錄沒有被其他線程修改,則減庫存成功,如果不一致則我會認為其他線程修改過這個記錄。就不會進行操作這個被稱為樂觀鎖。這個時候我們會考慮重入,重復執(zhí)行(1)-(3)步驟直至(2)的退出或者(3)成功繼續(xù)我們的操作,這樣就是一個沒有鎖的機制。這就是一個樂觀鎖的機制,而沒有任何等待的機制,是一個非阻塞的過程。
3、企業(yè)的秒殺目前應該考慮使用redis,而不是mysql。
別和我說你mysql的性能和redis比,個人自測分別批量插入數(shù)據(jù):
redis每秒在我的機子可以執(zhí)行40萬次的插入,而mysql只能執(zhí)行不到2萬次。這個性能差了幾十倍。你用mysql是自己找麻煩。這個級別根本不同級,其次redis提供的事務很好的符合了秒殺的功能。
首先任何線程執(zhí)行redis的操作的時候都是使用lua語言,redis在執(zhí)行l(wèi)ua語言的時候是原子性的,讓它執(zhí)行減庫存,并且記錄用戶購買記錄。
直至秒殺時間到期或者庫存為0,才考慮將redis緩存的數(shù)據(jù)批量一次性把減庫存和用戶購買的信息批量寫入mysql。整個秒殺過程基本在redis完成,而不是數(shù)據(jù)庫,不是你mysql的性能可比的,你服務器上mysql一秒可以4萬次,redis可以上百萬次,你怎么比??
2016-10-31
秒殺場景主要兩個點:
1:流控系統(tǒng),防止后端過載或不必要流量進入,因為慕課要求課程的長度和簡單性,沒有加。
2:減庫存競爭,減庫存的update必然涉及exclusive lock ,持有鎖的時間越短,并發(fā)性越高。
CAS是否適用瞬時競爭?
1:"select? version, left from table where pk= {pid}"不加 for update 并發(fā)得到共享version
2: "update table set left = left - #{byCount} , version =? version+1?where pk={id} count >0 and vesion = #{vesion}" 首先這句sql本身會加row-level exclusive?lock。version大量沖突導致減庫存失效,客戶端重試導致TPS翻倍,加重DB負擔。
3:對于使用redis+LUA實現(xiàn)秒殺庫存邏輯,重點在異步MQ落地可靠性和異常回滾機制。
對于生產(chǎn)環(huán)境的秒殺沒有這么簡單,需要全鏈路梳理和優(yōu)化,參見之前同事的分享:http://www.infoq.com/cn/presentations/challenge-of-alipay-red-envelopes
最后,不用回我了,如果你覺得我講的問題多,希望你也錄一個課程,這樣可以幫助大家,何樂不為呢。
2016-10-31
首先感謝你的回復,這門課已經(jīng)說了,用最常用的技術分析實現(xiàn)秒殺場景。
其次你的思路請在想想。參考一下文檔:
http://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html
http://www.infoq.com/cn/presentations/seckill-solution-based-sql
http://geek.csdn.net/news/detail/93986
作者之前就在阿里淘寶技術部,秒殺處理方式我還是比較清楚的。
最后這門課只是幫助有需要的同學。
2019-08-07
mysql的默認RR級別,對于寫寫操作,不是默認加行鎖嗎?這個人問了一大段的結果問題就是錯的
2017-12-18
mysql執(zhí)行update語句的時候已經(jīng)獲得了這條記錄的排它鎖了 也就是老師說的行級鎖吧
2016-11-15
楊開振你這妖孽寫完書來這兒砸場子