深入解析 Redis 實現分布式鎖的最佳實踐

前言

在分布式系統中,多個進程或線程可能會同時訪問同一個共享資源,這就可能導致數據不一致的問題。為了保證數據的一致性,我們通常需要使用分布式鎖。Redis 作為高性能的內存數據庫,提供了一種簡單高效的方式來實現分布式鎖。本文將深入探討如何使用 Redis 來實現分布式鎖,并介紹一些優化技巧和最佳實踐。

?

?

---

?

一、為什么需要分布式鎖?

?

在單機環境下,我們可以使用 synchronized、Lock 等方式來控制并發訪問。但在分布式系統中,多個服務可能同時操作數據庫或緩存,傳統的線程鎖無法跨多個實例工作,這時候就需要用分布式鎖來保證資源的互斥訪問。

?

應用場景包括:

?

防止并發訂單超賣

?

控制定時任務的并發執行

?

限制用戶重復提交請求

?

?

?

---

?

二、使用 Redis 實現分布式鎖

?

1. 基礎實現

?

最簡單的方式是使用 Redis 的 SETNX 命令(SET if Not eXists)。

?

SETNX lock_key value

?

但是,僅使用 SETNX 存在問題:

?

如果程序崩潰,鎖可能不會釋放

?

不能設置鎖的自動過期時間

?

?

因此,我們需要改進實現方式:

?

SET lock_key value NX PX 5000 # 設置過期時間 5 秒

?

解釋:

?

NX:只有 key 不存在時才創建

?

PX 5000:設置過期時間為 5000 毫秒(5 秒)

?

?

這樣可以確保鎖在進程意外退出時不會永遠存在。

?

?

---

?

2. 釋放鎖

?

要釋放鎖,我們不能直接 DEL,因為如果鎖過期后被其他線程重新獲取,DEL 可能會誤刪新的鎖。因此,正確的方式是使用 Lua 腳本:

?

if redis.call("GET", KEYS[1]) == ARGV[1] then

? ? return redis.call("DEL", KEYS[1])

else

? ? return 0

end

?

Python 代碼示例(使用 redis-py):

?

import redis

?

client = redis.StrictRedis(host='localhost', port=6379, decode_responses=True)

lock_key = "lock:resource"

lock_value = "unique-id"

?

# 釋放鎖

lua_script = """

if redis.call("GET", KEYS[1]) == ARGV[1] then

? ? return redis.call("DEL", KEYS[1])

else

? ? return 0

end

"""

client.eval(lua_script, 1, lock_key, lock_value)

?

這樣可以確保只有持有鎖的進程才可以釋放它。

?

?

---

?

三、改進方案:RedLock 算法

?

盡管 SETNX 結合過期時間能解決基本問題,但仍然存在網絡分區等問題。因此,Redis 官方推薦 RedLock 算法:

?

核心思想:

?

1. 在多個獨立的 Redis 實例上嘗試加鎖

?

?

2. 只有在大多數節點成功獲取鎖,才算加鎖成功

?

?

3. 計算鎖的有效時間,防止時間偏移影響鎖的有效性

?

?

4. 釋放鎖時依次刪除所有 Redis 實例上的鎖

?

?

?

實現示例(Python):

?

from redis import Redis

from redis_lock import RedLock

?

lock = RedLock("resource_name", connection_list=[

? ? Redis(host='redis1.example.com', port=6379),

? ? Redis(host='redis2.example.com', port=6379),

? ? Redis(host='redis3.example.com', port=6379)

])

?

if lock.acquire():

? ? try:

? ? ? ? print("成功獲取分布式鎖")

? ? ? ? # 執行業務邏輯

? ? finally:

? ? ? ? lock.release()

else:

? ? print("獲取鎖失敗")

?

RedLock 適用于高可靠性場景,但由于需要多個 Redis 節點,部署成本更高,適用于分布式集群環境。

?

?

---

?

四、總結

?

基礎鎖: 使用 SETNX + 過期時間

?

釋放鎖: 使用 Lua 腳本確保安全性

?

高可用方案: 采用 RedLock 算法提高可靠性

?

?

在實際項目中,選擇適合的鎖方案可以有效提高系統的穩定性和并發控制能力。希望本文能幫助你更好地理解 Redis 分布式鎖的實現方式!

?

如果你有更好的想法,歡迎留言交流!

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73083.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73083.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73083.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2025年03月10日人慧前端面試(外包滴滴)

目錄 普通函數和箭頭函數的區別loader 和 plugin 的區別webpack 怎么實現分包,為什么要分包webpack 的構建流程變量提升react 開發中遇到過什么問題什么是閉包vue 開發中遇到過什么問題vue中的 dep 和 watcher 的依賴收集是什么階段什么是原型鏈react setState 是同…

Android10 系統截屏功能異常的處理

客戶反饋的問題,設備上使用狀態欄中“長截屏”功能,截屏失敗且出現系統卡死問題。 在此記錄該問題的處理 一現象: 設備A10上使用系統“長截屏”功能,出現截屏失敗,系統死機。 二復現問題并分析 使用設備操作該功能&…

openvela新時代的國產開源RTOS系統

openvela 簡介 openvela 操作系統專為 AIoT 領域量身定制,以輕量化、標準兼容、安全性和高度可擴展性為核心特點。openvela 以其卓越的技術優勢,已成為眾多物聯網設備和 AI 硬件的技術首選,涵蓋了智能手表、運動手環、智能音箱、耳機、智能家…

ENSP學習day9

ACL訪問控制列表實驗 ACL(Access Control List,訪問控制列表)是一種用于控制用戶或系統對資源(如文件、文件夾、網絡等)訪問權限的機制。通過ACL,系統管理員可以定義哪些用戶或系統可以訪問特定資源&#x…

JVM的組成--運行時數據區

JVM的組成 1、類加載器(ClassLoader) 類加載器負責將字節碼文件從文件系統中加載到JVM中,分為:加載、鏈接(驗證、準備、解析)、和初始化三個階段 2、運行時數據區 運行時數據區包括:程序計數…

RAG(Retrieval-Augmented Generation)基建之PDF解析的“魔法”與“陷阱”

嘿,親愛的算法工程師們!今天咱們聊一聊PDF解析的那些事兒,簡直就像是在玩一場“信息捉迷藏”游戲!PDF文檔就像是個調皮的小精靈,表面上看起來規規矩矩,但當你想要從它那里提取信息時,它就開始跟…

Python網絡編程入門

一.Socket 簡稱套接字,是進程之間通信的一個工具,好比現實生活中的插座,所有的家用電器要想工作都是基于插座進行,進程之間要想進行網絡通信需要Socket,Socket好比數據的搬運工~ 2個進程之間通過Socket進行相互通訊&a…

人工智能(AI)系統化學習路線

一、為什么需要系統化學習AI? 人工智能技術正在重塑各行各業,但許多初學者容易陷入誤區: ? 盲目跟風:直接學習TensorFlow/PyTorch,忽視數學與算法基礎。 ? 紙上談兵:只看理論不寫代碼,無法解…

mac calDAV 日歷交互

安裝Bakal docker https://sabre.io/dav/building-a-caldav-client/ 在Bakal服務器上注冊賬戶 http://localhost:8080/admin/?/users/calendars/user/1/ 在日歷端登錄賬戶: Server: http://127.0.0.1:8080/dav.php Server Path: /dav.php/principals/lion No e…

手機號登錄與高并發思考

基礎邏輯 一般來說這個驗證碼登錄分為手機號、以及郵箱登錄 手機號短信驗證,以騰訊云SMS 服務為例: 這個操作無非對后端來說就是兩個接口: 一個是獲取驗證碼,這塊后端生成6位數字expire_time 去推送到騰訊云sdk ,騰…

Python設計模式 - 適配器模式

定義 適配器模式(Adapter Pattern)是一種結構型設計模式,它用于將一個類的接口轉換為客戶端所期待的另一個接口。 注:在適配器模式定義中所提及的接口是指廣義的接口,它可以表示一個方法或者一組方法的集合。 結構 …

【前端工程化】

目錄 前端工程戶核心技術之模塊化前端模塊化的進化過程commonjs規范介紹commonjs規范示例commonjs模塊打包 amd規范、cmd規范前端工程化關鍵技術之npmwebpack原理 前端工程戶核心技術之模塊化 前端模塊化是一種標準,不是實現。commonjs是前端模塊化的標準&#xff…

關于CNN,RNN,GAN,GNN,DQN,Transformer,LSTM,DBN你了解多少

以下是神經網絡中常見的幾種模型的簡要介紹: 1. ?CNN (Convolutional Neural Network, 卷積神經網絡) ?用途: 主要用于圖像處理和計算機視覺任務。?特點: 通過卷積核提取局部特征,具有平移不變性,能夠有效處理高維數據(如圖像…

T113-i開發板的休眠與RTC定時喚醒指南

??在嵌入式系統設計中,休眠與喚醒技術是優化電源管理、延長設備續航的關鍵。飛凌嵌入式基于全志T113-i處理器開發設計的OK113i-S開發板提供了兩種休眠模式:freeze和mem,以滿足不同應用場景下的功耗與恢復速度需求。本文將詳細介紹如何讓OK1…

SpringBoot項目實戰(初級)

目錄 一、數據庫搭建 二、代碼開發 1.pom.xml 2.thymeleaf模塊處理的配置類 3.application配置文件 4.配置(在啟動類中) 5.編寫數據層 ②編寫dao層 ③編寫service層 接口 實現類 注意 補充(注入的3個注解) 1.AutoWir…

高性能網絡SIG雙月動態:加速 SMC eBPF 透明替換特性上游化進程,并與上游深度研討新特性

01、整體進展 本次雙月報總結了 SIG 在 1 月和 2 月的工作進展,工作聚焦在 ANCK CVE 和穩定性問題修復,以及上游 SMC eBPF 透明替換特性推進和多個話題討論上。 本月關鍵進展: 1. 推進 SMC eBPF 透明替換特性上游化,更新至 V7&…

某視頻的解密下載

下面講一下怎么爬取視頻,這個還是比小白的稍微有一點繞的 首先打開網址:aHR0cDovL3d3dy5wZWFydmlkZW8uY29tL3BvcHVsYXJfNA 首頁 看一下: 有一個標題和一個href,href只是一個片段,待會肯定要拼接, 先找一…

C++繼承機制:從基礎到避坑詳細解說

目錄 1.繼承的概念及定義 1.1繼承的概念 1.2 繼承定義 1.2.1定義格式 1.2.2繼承關系和訪問限定符 1.2.3繼承基類成員訪問方式的變化 總結: 2.基類和派生類對象賦值轉換 3.繼承中的作用域 4.派生類的默認成員函數 ?編輯 默認構造與傳參構造 拷貝構造&am…

測試基礎入門

文章目錄 軟件測試基礎1.1軟件測試概述什么是軟件測試什么是軟件需求說明書軟件測試的原則測試用例的設計測試用例設計的基本原則軟件測試分類軟件缺陷的定義 2.1軟件開發模型軟件開發模型概述大爆炸模型(邊寫邊改)軟件開發生命周期模型--螺旋模型軟件開…

022-spdlog

spdlog 以下是從原理到代碼實現的全方位spdlog技術調研結果,結合核心架構、優化策略和完整代碼示例: 一、核心架構設計原理 spdlog三級架構 (圖示說明:spdlog采用三級結構實現日志系統解耦) Registry管理中樞 全局…