阿里Tair分布式鎖與Redis分布式鎖的實(shí)現(xiàn)區(qū)別
Tair分布式鎖與Redis分布式鎖的核心區(qū)別在于:Tair通過(guò)增強(qiáng)的原生命令(CAS/CAD)簡(jiǎn)化了鎖的安全釋放與續(xù)租,并提供了更強(qiáng)的一致性保障;而原生Redis則需要通過(guò)Lua腳本實(shí)現(xiàn)相同邏輯,且在集群模式下存在因主備異步復(fù)制導(dǎo)致鎖丟失的風(fēng)險(xiǎn)。
以下是詳細(xì)的對(duì)比分析:
1. 解鎖與續(xù)租的原子性:原生命令 vs Lua腳本
這是兩者最直觀的區(qū)別。在原生Redis中,為了避免誤刪其他客戶端的鎖,解鎖操作必須使用Lua腳本,先GET校驗(yàn)random_value再DEL。而Tair提供了原生的CAD(Compare And Delete)命令,將“比較并刪除”合并為一個(gè)原子操作,無(wú)需編寫腳本。
| 操作 | 原生Redis | Tair(企業(yè)版) |
|---|---|---|
| 加鎖 | SET key random NX EX seconds | SET key random NX EX seconds (相同) |
| 解鎖 | Lua腳本:get 校驗(yàn) + del | CAD key random (原子命令) |
| 續(xù)租 | Lua腳本:get 校驗(yàn) + expire | CAS key random random EX seconds |
2. 數(shù)據(jù)一致性:異步復(fù)制 vs 半同步復(fù)制
在標(biāo)準(zhǔn)Redis主從架構(gòu)中,數(shù)據(jù)復(fù)制是異步的。如果主節(jié)點(diǎn)剛寫入鎖就宕機(jī)且數(shù)據(jù)未同步到從節(jié)點(diǎn),從節(jié)點(diǎn)提升為主節(jié)點(diǎn)后,鎖就會(huì)丟失,導(dǎo)致多個(gè)客戶端同時(shí)持有鎖。Tair(企業(yè)版)支持配置半同步復(fù)制,確保數(shù)據(jù)成功寫入主節(jié)點(diǎn)并同步到至少一個(gè)備節(jié)點(diǎn)后,才向客戶端返回成功。
3. 高級(jí)特性與性能
- 高可用方案:為了提升一致性,原生Redis作者提出了復(fù)雜的RedLock算法,需要操作多個(gè)獨(dú)立的Master節(jié)點(diǎn),實(shí)現(xiàn)復(fù)雜且性能較低。Tair則通過(guò)內(nèi)置的半同步復(fù)制機(jī)制解決一致性問(wèn)題,無(wú)需引入RedLock。
- 性能:Tair(內(nèi)存型)針對(duì)高并發(fā)場(chǎng)景進(jìn)行了優(yōu)化,在鎖操作吞吐量上宣稱可達(dá)原生Redis的3倍左右。
- 樂(lè)觀鎖:Tair支持
TairString數(shù)據(jù)類型(帶版本號(hào)的String),配合EXCAS命令可以實(shí)現(xiàn)更高效、更節(jié)省網(wǎng)絡(luò)開(kāi)銷的樂(lè)觀鎖,這在高并發(fā)寫入場(chǎng)景下優(yōu)勢(shì)明顯。
4. 如何選擇?
- 如果你的業(yè)務(wù)對(duì)數(shù)據(jù)一致性有極高要求(如金融、交易):建議優(yōu)先考慮Tair。其半同步復(fù)制特性能夠有效規(guī)避因主備切換導(dǎo)致的鎖丟失風(fēng)險(xiǎn),且原生命令讓代碼更簡(jiǎn)潔。
- 如果你的業(yè)務(wù)場(chǎng)景允許極低概率的鎖丟失,或者主要用于提升效率(非強(qiáng)互斥):原生Redis完全足夠。配合Redisson等客戶端庫(kù),它可以很好地處理大多數(shù)分布式鎖需求。
5. Tair如何通過(guò)CAD命令簡(jiǎn)化鎖釋放的
Tair 通過(guò)提供原生的 CAD(Compare And Delete)命令,將 Redis 分布式鎖中“檢查 value 是否匹配 + 刪除 Key”這兩個(gè)步驟合并為一個(gè)原子操作,從而極大地簡(jiǎn)化了鎖的安全釋放邏輯。
核心原理:原生原子命令
CAD 命令的語(yǔ)法非常簡(jiǎn)單:
CAD key value
它的執(zhí)行邏輯是:
- 比較:檢查指定
key的當(dāng)前value是否與傳入的value參數(shù)相等。 - 刪除:如果相等,則刪除該
key(即釋放鎖),操作成功;如果不相等,則不進(jìn)行任何操作。
整個(gè)過(guò)程在 Tair 服務(wù)端是一個(gè)原子操作,無(wú)需在客戶端編寫 Lua 腳本,既保證了正確性,也提升了性能
代碼對(duì)比:一行代碼 vs Lua腳本
這種簡(jiǎn)化在代碼層面體現(xiàn)得非常直觀:
原生 Redis(使用 Lua 腳本)
為了確保安全,防止誤刪其他客戶端的鎖,必須通過(guò) Lua 腳本實(shí)現(xiàn)原子性的“校驗(yàn)+刪除”。
# 需要編寫 Lua 腳本,并在每次解鎖時(shí)執(zhí)行 eval
lua_script = """
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end
"""
redis.eval(lua_script, 1, lock_key, lock_value)Tair(使用 CAD 命令)
只需一行代碼,Tair 服務(wù)端就能自動(dòng)完成校驗(yàn)和刪除。
# 直接使用 CAD 命令,簡(jiǎn)潔且高效 tair.cad(lock_key, lock_value)
實(shí)戰(zhàn)流程與返回值
一個(gè)完整的 Tair 分布式鎖使用流程如下,解鎖部分展示了 CAD 命令的用法:

加鎖
使用標(biāo)準(zhǔn)的 SET 命令,帶上 NX(只在鍵不存在時(shí)設(shè)置)和 EX(過(guò)期時(shí)間)參數(shù)。
SET resource_lock my_unique_id NX EX 10
執(zhí)行業(yè)務(wù)邏輯
獲取鎖成功后,執(zhí)行需要保護(hù)的業(yè)務(wù)代碼。
釋放鎖(CAD)
直接調(diào)用 CAD 命令。通過(guò)返回值可以精確判斷釋放結(jié)果:
- 返回
1: 比較成功,Key 被刪除,鎖釋放成功。 - 返回
0: 比較失敗,當(dāng)前 Key 的 Value 與傳入的不匹配(可能鎖已被其他客戶端獲取或自動(dòng)續(xù)期過(guò)),釋放失敗。 - 返回
-1: Key 不存在(可能鎖已自動(dòng)過(guò)期)。
續(xù)租(可選)
如果業(yè)務(wù)執(zhí)行時(shí)間較長(zhǎng),可以使用 CAS 命令來(lái)延長(zhǎng)鎖的過(guò)期時(shí)間,同樣也是原子操作,無(wú)需 Lua 腳本:
# 將 key 的 value 從 my_unique_id 設(shè)置為 my_unique_id(不變),并將過(guò)期時(shí)間延長(zhǎng)到 10 秒 CAS resource_lock my_unique_id my_unique_id EX 10
總結(jié)
Tair 的 CAD 命令將分布式鎖的釋放邏輯從應(yīng)用層的復(fù)雜封裝,簡(jiǎn)化為了數(shù)據(jù)庫(kù)內(nèi)核的原生能力。這種設(shè)計(jì)不僅讓代碼更簡(jiǎn)潔、更不易出錯(cuò),也充分利用了服務(wù)端的計(jì)算能力,提升了整體性能。
到此這篇關(guān)于阿里Tair分布式鎖與Redis分布式鎖的實(shí)現(xiàn)區(qū)別的文章就介紹到這了,更多相關(guān)阿里Tair分布式鎖與Redis分布式鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Caffeine實(shí)現(xiàn)類似redis的動(dòng)態(tài)過(guò)期時(shí)間設(shè)置示例
這篇文章主要為大家介紹了Caffeine實(shí)現(xiàn)類似redis的動(dòng)態(tài)過(guò)期時(shí)間示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
phpredis提高消息隊(duì)列的實(shí)時(shí)性方法(推薦)
下面小編就為大家?guī)?lái)一篇phpredis提高消息隊(duì)列的實(shí)時(shí)性方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12
基于Redis實(shí)現(xiàn)短信驗(yàn)證碼登錄項(xiàng)目示例(附源碼)
手機(jī)登錄驗(yàn)證在很多網(wǎng)頁(yè)上都得到使用,本文主要介紹了基于Redis實(shí)現(xiàn)短信驗(yàn)證碼登錄項(xiàng)目示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
Redis?Hash序列化存儲(chǔ)的問(wèn)題及解決方案
這篇文章主要介紹了Redis?Hash序列化存儲(chǔ)的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
通過(guò)實(shí)例解析布隆過(guò)濾器工作原理及實(shí)例
這篇文章主要介紹了通過(guò)實(shí)例解析布隆過(guò)濾器工作原理及實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
SpringBoot整合Redis入門之緩存數(shù)據(jù)的方法
Redis是一個(gè)開(kāi)源的使用ANSI C語(yǔ)言編寫、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫(kù),并提供多種語(yǔ)言的API,下面通過(guò)本文給大家介紹下SpringBoot整合Redis入門之緩存數(shù)據(jù)的相關(guān)知識(shí),感興趣的朋友一起看看吧2021-11-11

