高併發下防止商品超賣的Redis實現

2021-08-15 12:27:39 字數 1174 閱讀 3132

朋友面試被問到高併發下,如何防止10個商品被超賣,當時想到了訊息佇列。我也搜了下,都是推薦記憶體處理秒殺類的高併發搶購,減庫存則是通過非同步的方式寫到資料庫,但是在這之前就已經對秒殺成功的使用者完成了登記。看了網友的答案,總結大致如下:

1. 首先定義乙個 redis 佇列名為 sku:awards,裡面的元素的值都是比如 1,只是用來代表乙個商品,元素的個數則是供秒殺的商品總數。

2. 因為 redis 是單執行緒的,所以可以將併發的請求序列化,而且 redis list 的 pop 操作是原子性的。

3. 所有請求打到 redis 上,都是從 sku:awards 佇列上 pop 出乙個元素:

a. 如果有,說明還有商品,那麼需要

把使用者id加入到redis 的 set 名為

candidate:userids 裡:

a. 如果加入成功,說明使用者是第一次搶購

b. 否則,說明使用者已經成功搶購了,不能重複搶購,需要往佇列 sku:awards

彌補乙個商品標識元素

b. 沒有取到,說明都被秒殺完了

通過 jmeter 模擬併發,無論是 100,300 還是 400,candidate:userids 有且只有 10 個元素,說明商品沒有超賣。

**如下:

public void testmiaosha() else 

} else

}

下面是 jmeter 測試介面:

看了【問底】徐漢彬:web系統大規模併發——電商秒殺與搶購,裡面提到了作弊手段,前兩個可以通過鑑別是否同乙個賬號,

或者請求來自同乙個ip位址來處理(上文使用的是鑑別同一賬號)。也有網友提到了即便使用 redis 也有可能搶購開始的一瞬

間請求數過多,撐爆了 redis 的記憶體,那麼是否可以引入如 kafka 這樣的訊息佇列對請求進行消峰,然後取請求數的一小部分

進入 redis 進行下一步的真正搶購;還是直接使用訊息佇列就能完全應付下來呢?

高併發下防止庫存超賣的解決方案

最近在看秒殺相關的專案,針對防止庫存超賣的問題,查閱了很多資料,其解決方案可以分為悲觀鎖 樂觀鎖 分布式鎖 redis原子操作 佇列序列化等等,這裡進行淺顯的記錄總結。首先我們來看下庫存超賣問題是怎樣產生的 1 2 3 45 6 1.查詢出商品 庫存資訊 select stock from t go...

PHP redis樂觀鎖防止高併發超賣

error level error reporting 0 con new mysqli localhost root root test if con sql select from products where id 1 result mysqli query con,sql aa mysqli...

《轉》 mysql處理高併發,防止庫存超賣

今天王總又給我們上了一課,其實mysql處理高併發,防止庫存超賣的問題,在去年的時候,王總已經提過 但是很可惜,即使當時大家都聽懂了,但是在現實開發中,還是沒這方面的意識。今天就我的一些理解,整理一下這個問題,並希望以後這樣的課程能多點。先來就庫存超賣的問題作描述 一般電子商務 都會遇到如 秒殺 之...