使用Redis分布式鎖控制請求串行處理


1.需求背景

在一些寫接口的場景下,由於一些網絡因素導致用戶的表單重復提交,就會在相鄰很短的時間內,發出多個數據一樣的請求。后台接口的冪等性保證一般都是先檢查數據的狀態,然后決定是否進行執行寫入操作,最后更新狀態。那么在這個很短的時間內,數據可能還沒來及寫入,多個請求同時進入了狀態判斷的邏輯,此時就可能繞過檢查,執行多次重復的寫入。

在此給出的解決方案是,使用redis分布式鎖,控制用戶的請求串行處理:客戶端的請求進入時,基於用戶的維度進行搶鎖,搶到了就可以往下執行邏輯,搶不到鎖的請求直接被拒絕。

2.redis分布式鎖的使用

2.1.使用下面的命令獲取鎖:

 SET resource_name my_random_value EX 100 NX

當 resource_name 不存在的時候設置,將值設置為 my_random_value 同時指定 100秒過期時間,my_random_value 必須在鎖定請求中絕對唯一,用於后面的解鎖釋放。

2.2.使用Lua腳本解鎖:

if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

這段Lua腳本執行的時候將 resource_name 作為 KEYS[1],將 my_random_value 作為 ARGV[1] 的值傳進去,只有當 my_random_value 的值恰好是之前存的值,才刪除它。

3. Redlock算法的高級鎖

Redlock算法 的介紹可以看Redis官網,關於這個算法的安全性問題,發生過一場 爭論 ,在此不展開分析。

就我目前的業務中是直接使用雲廠商 集群版的redis,客戶端的連接上只有一個實例,業務開發時等效於單機版來使用,雲廠商負責后面的主從支持。那么使用單redis節點的鎖方案就足夠了,簡單且效率高;用不了,也沒法用 Redlock算法的高級鎖方案。其實,最后是一個問題,有沒有必要去使用 Redlock這個過重的實現?還是看個人負責的業務場景吧,就我目前的業務需求是用不上的,也許后續會有更嚴苛的業務場景,到那時再會。

參考資料

  1. Distributed locks with Redis – Redis
  2. How to do distributed locking — Martin Kleppmann’s blog


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM