由於專案需要,需要多執行緒去獲取和修改資料庫的庫存,考慮到給資料庫加鎖效率低,所以採用redis+lua來進行實現 。1.首先定義redis資料結構redis的單執行緒操作特性來執行lua指令碼,通過lua指令碼來保證原子性。如果通過單純的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,對字串...