下單減庫存

1. 減庫存redis

通常下單減庫存的流程大概是這樣的:數據庫

一、查詢商品庫存。這裏直接查的Redis中的庫存。緩存

二、Redis中的庫存減1。這裏用到的Redis命令是:incrby -1併發

三、扣減數據庫中的庫存。這裏用數據庫樂觀鎖,不用額外加鎖異步

四、異步刷新Redis中的庫存分佈式

五、定時掃描超時未支付的交易,庫存加回去性能

總結一下這個流程就是:先減redis庫存,再減數據庫庫存,最後刷新redis庫存優化

用到的Redis命令可能:DECR key  或者  INCRBY key -1spa

更新數據庫的SQL多是這樣的:線程

update 商品庫存表 set 庫存 = 庫存 - 1 where 商品ID = xxx and 庫存 > 0;

或者

update 商品庫存表 set 庫存 = 庫存 - 1 where 商品ID = xxx and version = xxx;

用樂觀鎖是一種比較好的方式,並且一遍ID字段都有索引,能夠充分利用MySQL行級鎖

這種方式還有一個比較巧妙的地方是,利用redis的單線程來操做庫存,並且又是原子命令,能夠避免併發問題

同時,先減redis庫存後能夠防止後續因庫存不足而形成下單失敗

最後,數據庫更新完之後,再經過MQ異步刷新緩存,可使得redis中的庫存偏差不會太大

交易系統會定時掃描超時未支付的訂單,而後用MQ異步通知訂單和商品中心,將訂單關閉,庫存再放回去

2. 加鎖

加鎖(好比:基於Redis的分佈式鎖)

MQ能夠把並行轉成串行,可是並不能很好的解決併發訪問的問題,只能靠鎖

加鎖會影響性能,可是影響不大。假設咱們用Redisson分佈式鎖,操做redis只須要幾毫秒,所以這點兒損耗不是什麼大問題。都是這麼玩兒的,不加鎖還能怎麼辦呢。

3. 內存緩存

在cms管理後臺修改數據後,同步或異步刷新redis緩存,同時利用zookeeper刷新內存緩存,這樣就能夠不用等到須要用的時候再從redis中同步。

必定要避免redis大key,最多見的就是hash key,設置的時候不注意,一不當心裏面就幾千個field了,這對查詢很是不利,能夠取模進行分片。

必定要避免HGETALL命令,利用Pinpoint能夠幫助咱們分析每一個請求在每一個操做所消耗的時候,從而有助於咱們優化

數據遷移用Canal

 

https://redis.io/commands/incr 

相關文章
相關標籤/搜索