Redis lua進行類似秒殺的實現

2021-08-20 02:36:06 字數 1332 閱讀 9270

由於專案需要,需要多執行緒去獲取和修改資料庫的庫存,考慮到給資料庫加鎖效率低,所以採用redis+lua來進行實現 。

redis的單執行緒操作特性來執行lua指令碼,通過lua指令碼來保證原子性。如果通過單純的redis指令來進行更改,在讀和寫之間會存在多執行緒併發更新的問題。

1.首先定義redis資料結構

goodid:

local n = tonumber(argv[1])

ifnot n or n == 0

then

return

0end

local vals = redis.call("hmget", keys[1], "total", "released");

local total = tonumber(vals[1])

local blocked = tonumber(vals[2])

ifnot total or

not blocked then

return

0end

if blocked + n <= total then

redis.call("hincrby", keys[1], "released", n)

return n;

endreturn

0

若庫存足夠則返回申請的數量,否則返回0,不返回可滿足的剩餘數

3.spring boot 呼叫

- pom dependency

org.springframework.bootgroupid>

spring-boot-starter-data-redisartifactid>

2.0.1.releaseversion>

long count = redishelper.getstrcache().execute(new rediscallback() 

});

4.redis->database

針對redis到databases的更新,思考了很久,沒有找到較好的解決辦法,先採用定時任務非同步更新。至於資料是否丟失的問題,如果redis掛了,重啟後redis會恢復資料,等下次定時任務就可以將資料庫中的資料保持一致,缺點是redis掛了秒殺活動會失敗。

至於redis到database更新的如何驅動,列出兩種愚見:

- redis存乙份相關hash鍵名單表,通過讀取名單表來讀取更新

- 通過流式讀取databases中的表來讀取更新。

對所有表進行類似處理

eg1 大家知道,如果將乙個表所有者改為dbo,只需 sp changeobjectowner 表名 dbo 即可 但要將所有的表的所有者都改為dbo,可以用迴圈處理,此處略 其實用sql的系統儲存過程sp msforeachtable可以輕鬆搞定 只需execsp msforeachtable s...

居於redis lua指令碼實現的滑動視窗

我們常常使用滑動視窗實現限流操作,在單機時我們經常放在記憶體中實現,而在做全域性介面限流時,我們除了可以通過查詢介面呼叫記錄外,還可以通過依賴redis實現的滑動視窗進行,比如限制1分鐘可呼叫1000次,一小時可呼叫10000次。1 乙個固定長度的迴圈佇列 2 每個時間片的時長,可以是按秒 分 時。...

秒殺的架構

昨天回答的太差了,明明都是些很簡單的東西,我居然回答的那麼差 讓我很有挫敗感 一些概念性的東西這裡就不說了,下面兩個問題,重新梳理一下 1,一致性雜湊虛擬節點與真實節點對映關係的建立 現在我們使用的是字串構成的圓環,每台真實伺服器生成n個虛擬節點,虛擬節點生成的規則為,用 i遍歷從0到n 1,對字串...