秒殺庫存需不需要實時更新到mysql?

時間 2021-06-02 07:23:59

1樓:

秒殺系統, 小庫存場景,瞬間搶購完成的case,譬如iphone 11 上億人搶乙個,可通過使用事務的悲觀鎖的實現(為了降低併發衝突,可對於事務內要讀取且後續要基於此做更新的select語句 + for update來實現降低併發衝突,即加共享讀鎖),事務執行操作的結果,都需要通過判斷affectedRow是否返回0,返回0則通過rollback transaction執行回滾。 也可以不用事務,通過應用層面寫sql來實現樂觀鎖 ,譬如減庫存

select itemVersion from itemTable where itemid=id;

update itemTable set itemNum=itemNum-1 where itemVersion=oldVersion and itemid=id;

若庫存量很大,併發量也大,則併發衝突概率就大,失敗重試就多,系統做很多無用功,效能低。

此時加快取,只能降低讀的壓力,寫衝突仍舊長時間存在。

所以針對大庫存,採用訊息中介軟體,將下單和減庫存解耦,下單還是通過建立訂單,持久化至資料庫,同時寫入訊息中介軟體一條某商品待減庫存的訊息(包含order id, user id),減庫存通過快取的DECRBY操作,完成後回寫此訂單id的狀態,完全非同步化來做。

對於秒殺,給使用者延遲幾秒,前端做好提示即可。同時,若商品種類及商品數量很多,還存在熱點商品,針對海量使用者併發搶購,通過user id對訂單db分庫分表,先均攤使用者壓力;通過item id切片來寫入訊息中介軟體topic對應hasing取模後的partition。然後閃購後台作業通過配置的模數N 來啟動N個例項,通過配置指定partition執行消費,通過user id及order id來查詢及更新訂單狀態。

補充:對於訂單系統,由於基於user id分庫分表,order id為主鍵,如何分布式的生成,保障全域性單調或趨勢遞增, 可基於snowflake或segment方案

2樓:乾貨滿滿張雜湊

首先,假設你的秒殺活動是實時告訴使用者結果的場景。假設你只用了 redis 和 mysql。假設你是先更新redis判斷庫存足夠(這個是lua指令碼實現,保證原子性),之後再進行後續邏輯(下單,扣庫存,扣款等等)。

資料庫事務內不能出現其他型別的IO,例如redis操作,防止redis出現問題時,事務一直失敗或者redis緩慢時,資料庫也被拖慢。

也就是lua指令碼實現每次成功秒殺redis進行incr操作加一,當從0加到100,再有使用者參與秒殺就提示使用者庫存不足,只有redis判斷庫存足夠的時候,lua指令碼實現讀取,判斷數量,之後incr操作加一,再返回成功或者失敗,這是乙個原子操作,再進行後續邏輯(下單,扣庫存,扣款等等)。

我的建議,你的下單扣款,在乙個事務內,之後給使用者就返回成功。扣庫存,由於是操作同一行的乙個字段,很容易Lock wait timeout,這個非同步序列更新資料庫即可(但是必須是update set amount = A2, version=V2 where amount = V1 and version = V1這麼更新,用於後面redis更新)。

但是這裡有乙個問題,使用者餘額不足怎麼辦?redis更新完,程序重啟怎麼辦?這些問題,可以通過補償邏輯實現,由於搶成功的,是下單扣款這個事務完成的,所以定時對於搶完的商品,掃一下資料count一下訂單數量是否對的上,如果對不上,就更新快取內的庫存。

還有 redis 如果掛了,怎麼辦?那麼需要轉換成資料庫扣庫存,先計算出訂單數量,從而得出庫存餘額,更新資料庫(由於之前的是帶版本的更新,這裡強制更新完,之前剩餘的非同步庫存更新其實就全都更新失敗了),之後通過資料庫商品這一行的鎖,進行秒殺。

最後需要考慮的是超過redis承載能力的流量控制,redis更新,資料庫更新都有自己的併發極限。超過redis極限,就會報超時 redis command timeout,超過資料庫極限,就會報Lock wait timeout。我們要做的是,保證流量打到redis不要超過redis的極限,流量打到資料庫不要超過資料庫的極限。

資料庫前面有redis這一incr成功才繼續更新,其實已經算是控流了。如果超過了redis的承受極限,就可以直接隨機丟棄掉一些流量。

復婚需不需要彩禮?

彩禮的初衷是什麼?中國自古娶妻就要彩禮,一來顯的對女方及女方家人的尊重和重視,讓女方家人放心 二來顯的男方有地位。孔子時期,按禮儀結婚的夫妻那是士大夫的夫妻標準,平民只能割腕對血來結婚,那麼結婚是否給彩禮還體現了社會等級。太複雜。彩禮嫁妝的目的可能更是為了給婚姻更大的保障,即有物質的保障,也有雙方安...

聲樂需不需要天賦?

民間做作故事藝術 主要是看你想要達到的效果吧。比如你是想好好唱個歌業餘愛好玩玩,其實努力學習練習是可以達到的 但是你想達成職業目標,那就需要天賦和努力的學習了。並不是說一定要天賦才可以學,普通人也可以去唱。只是天賦決定上限罷了。 蓋蓋聲樂小課堂 沒錯。不光是唱歌,很多方面都一樣。天賦是肯定的,比如嗓...

Coding 需不需要天賦?

作為乙個學了三年軟體的學生,我理解的天賦是這樣的1,上同樣的課,有天賦的學生不是學的更多,而是基於老師所講的東西有更有效的應用,比如說老師講了個苗頭,然後有的人就能看到樹木長什麼樣。2,面對同樣的問題,有天賦的學生能迅速把這個問題分解成很多步,並清楚的了解每一步各種技術佔多少,數學佔多少,輸入輸出是...