原來大廠的Redis分布式鎖都這么設(shè)計(jì)的!

1 本地鎖

常用的即 synchronize 或 Lock 等 JDK 自帶的鎖播掷,只能鎖住當(dāng)前進(jìn)程,僅適用于單體架構(gòu)服務(wù)蹦漠。而在分布式多服務(wù)實(shí)例場景下必須使用分布式鎖

2 分布式鎖

2.1 分布式鎖的原理

廁所占坑理論

可同時(shí)去一個(gè)地方“占坑”:

占到脱衙,就執(zhí)行邏輯

否則等待,直到釋放鎖

可通過自旋方式自旋

“占坑”可以去Redis傀蓉、DB、任何所有服務(wù)都能訪問的地方职抡。

2.2 分布式鎖演進(jìn)

一階段

// 占分布式鎖葬燎,去redis占坑Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock","111");if(lock) {//加鎖成功... 執(zhí)行業(yè)務(wù)Map> dataFromDb = getDataFromDb();redisTemplate . delete( key:"lock");//fH?tireturndataF romDb ;}else{// 加鎖失敗,重試。synchronized()// 休眠100ms重試// 自旋returngetCatalogJsonFromDbwithRedisLock();}復(fù)制代碼

問題場景

setnx占好了坑谱净,但是業(yè)務(wù)代碼異骋ぐ睿或程序在執(zhí)行過程中宕機(jī),即沒有執(zhí)行成功刪除鎖邏輯壕探,導(dǎo)致死鎖

解決方案:設(shè)置鎖的自動(dòng)過期冈钦,即使沒有刪除,會(huì)自動(dòng)刪除李请。

階段二

// 1. 占分布式鎖瞧筛,去redis占坑Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock","110")if(lock) {// 加鎖成功...執(zhí)行業(yè)務(wù)// 突然斷電// 2. 設(shè)置過期時(shí)間redisTemplate.expire("lock", timeout:30, TimeUnit.SECONDS) ;Map> dataFromDb = getDataFromDb();//刪除鎖redisTemplate. delete( key;"lock");returndataFromDb;}else{// 加鎖失敗...重試。 synchronized ()// 休眠100ms重試// 自旋的方式returngetCatalogJsonFromDbWithRedisLock();}復(fù)制代碼

問題場景

setnx設(shè)置好导盅,正要去設(shè)置過期時(shí)間较幌,宕機(jī),又死鎖

解決方案:設(shè)置過期時(shí)間和占位必須是原子操作白翻。redis支持使用setNxEx命令

階段三

// 1. 分布式鎖占坑Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock","110",300, TimeUnit.SECONDS);if(lock)(// 加鎖成功乍炉,執(zhí)行業(yè)務(wù)// 2. 設(shè)置過期時(shí)間,必須和加鎖一起作為原子性操作// redisTemplate. expire( "lock", з0, TimeUnit.SECONDS);Map> dataFromDb = getDataFromDb();// 刪除鎖redisTemplate.delete( key:"lock")returndataFromDb;else{// 加鎖失敗嘁字,重試// 休眠100ms重試// 自旋returngetCatalogJsonFromDbithRedislock()}復(fù)制代碼

階段四

已經(jīng)拿到了 lockvalue ,有了 UUID杉畜,但是過期了現(xiàn)在纪蜒!其他人拿到所鎖設(shè)置了新值,于是 if 后將別人的鎖刪了4说纯续!也就是刪除鎖不是原子操作。

Map> dataFromDb = getDataFromDb();String lockValue = redisTemplate.opsForValue().get("lock");if(uuid.equals(lockValue)) {// 刪除我自己的鎖redisTemplate.delete("lock");}復(fù)制代碼

問題場景

如果正好判斷是當(dāng)前值灭袁,正要?jiǎng)h除鎖時(shí)猬错,鎖已過期,別人已設(shè)置成功新值茸歧。那刪除的就是別人的鎖.

解決方案

刪除鎖必須保證原子性倦炒。使用redis+Lua腳本。

階段五

確保加鎖/解鎖都是原子操作

String script ="if redis.call('get', KEYS[1]) == ARGV[1]

then return redis.call('del', KEYS[1])

else

return 0

end";復(fù)制代碼

保證加鎖【占位+過期時(shí)間】和刪除鎖【判斷+刪除】的原子性软瞎。 更難的事情逢唤,鎖的自動(dòng)續(xù)期。

總結(jié)

其實(shí)更麻煩的事情涤浇,還有鎖的自動(dòng)續(xù)期鳖藕。所以不管是大廠還是中小型公司,我們都是直接選擇解決了這些問題的 Redisson只锭!不重復(fù)造輪子著恩,但也要知道該框架到底解決了哪些問題,方便我們遇到問題時(shí)也能快速排查定位。

下一篇我們就開始 redisson 講解他是如何做到鎖續(xù)期的~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喉誊,一起剝皮案震驚了整個(gè)濱河市邀摆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌裹驰,老刑警劉巖隧熙,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異幻林,居然都是意外死亡贞盯,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門沪饺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來躏敢,“玉大人,你說我怎么就攤上這事整葡〖啵” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵遭居,是天一觀的道長啼器。 經(jīng)常有香客問我,道長俱萍,這世上最難降的妖魔是什么端壳? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮枪蘑,結(jié)果婚禮上损谦,老公的妹妹穿的比我還像新娘。我一直安慰自己岳颇,他們只是感情好照捡,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著话侧,像睡著了一般栗精。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瞻鹏,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天术羔,我揣著相機(jī)與錄音,去河邊找鬼乙漓。 笑死级历,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的叭披。 我是一名探鬼主播寥殖,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼玩讳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嚼贡?” 一聲冷哼從身側(cè)響起熏纯,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎粤策,沒想到半個(gè)月后樟澜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叮盘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年秩贰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柔吼。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡毒费,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出愈魏,到底是詐尸還是另有隱情觅玻,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布培漏,位于F島的核電站溪厘,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏牌柄。R本人自食惡果不足惜畸悬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望友鼻。 院中可真熱鬧傻昙,春花似錦闺骚、人聲如沸彩扔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虫碉。三九已至,卻和暖如春胸梆,著一層夾襖步出監(jiān)牢的瞬間敦捧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國打工碰镜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兢卵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓绪颖,卻偏偏與公主長得像秽荤,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1 本地鎖 常用的即 synchronize 或 Lock 等 JDK 自帶的鎖窃款,只能鎖住當(dāng)前進(jìn)程课兄,僅適用于單體架...
    JavaEdge閱讀 481評(píng)論 3 1
  • 文章目錄 Redis - 分布式鎖實(shí)現(xiàn)以及相關(guān)問題解決方案 1.分布式鎖是什么? 1.1 分布式鎖設(shè)計(jì)目的 1.2...
    tj_鐵蛋兒閱讀 480評(píng)論 0 2
  • 久違的晴天晨继,家長會(huì)烟阐。 家長大會(huì)開好到教室時(shí),離放學(xué)已經(jīng)沒多少時(shí)間了紊扬。班主任說已經(jīng)安排了三個(gè)家長分享經(jīng)驗(yàn)蜒茄。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,523評(píng)論 16 22
  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友珠月。感恩相遇扩淀!感恩不離不棄。 中午開了第一次的黨會(huì)啤挎,身份的轉(zhuǎn)變要...
    迷月閃星情閱讀 10,566評(píng)論 0 11
  • 在妖界我有個(gè)名頭叫胡百曉驻谆,無論是何事,只要找到胡百曉即可有解決的辦法庆聘。因?yàn)槭侵缓偞蠹乙杂瀭饔灲形摇皟A城百曉”胜臊,...
    貓九0110閱讀 3,264評(píng)論 7 3