分布式鎖原理

為了保障程序的高可用性牙甫,避免用戶在使用公司產(chǎn)品的時候,突然掛掉訪問不了落午,一般公司的后臺服務(wù),都需要部署多個實例蜕便,這樣就算一個掛了,另外幾個實例還能夠正常的工作忽妒,也就是做了所謂的負(fù)載均衡玩裙。

這樣也就會產(chǎn)生了一個問題,服務(wù)中的定時腳本也會被部署多份段直,當(dāng)指定的時間一到,腳本也會運行多個溶诞,可能會造成一些不必要的計算和麻煩鸯檬。

怎么去保證,同一時刻螺垢,只有一個腳本在運行呢喧务?比較好的,普遍適用的方式枉圃,就是使用分布式鎖功茴。

分布式鎖的使用

假設(shè)你啟動了多個實例A, B, C, D,為了達(dá)到同一時間只有一個實例在運行孽亲,我們需要在redis里面設(shè)置一把鎖:

SETNX keyName = 1

上面的SETNX命令只有當(dāng)keyName沒有被設(shè)置值的時候坎穿,才會成功,這樣返劲,當(dāng)A, B, C, D在啟動的時候玲昧,先去執(zhí)行上面的命令,成功的那個篮绿,才去執(zhí)行孵延,就可以保證同一時刻只有一個腳本在運行,當(dāng)然程序運行結(jié)束后亲配,需要執(zhí)行:

DEL keyName

來釋放鎖尘应。

死鎖問題

但是這樣也有一個問題惶凝,假設(shè)A設(shè)置了鎖,但是在后續(xù)執(zhí)行的時候犬钢,程序奔潰了梨睁,這樣keyName的值永遠(yuǎn)為1,B, C, D再也沒有獲取到鎖的機會娜饵,甚至連A自己重新啟動后也無法獲取鎖坡贺。

為了避免這種問題,我們可以為keyName設(shè)置一個超時時間t箱舞,這樣即使拿到鎖的程序崩潰了遍坟,超時時間一過,鎖也會自動釋放晴股。

鎖沖突問題

一般情況下愿伴,為了避免單點故障,我們一般會采用redis的主從架構(gòu)电湘,一個redis的master節(jié)點隔节,掛上n個slave從節(jié)點,這樣如果master奔潰了寂呛,會啟用一個slave節(jié)點繼續(xù)服務(wù)怎诫,考慮這樣一種情況:

  • A調(diào)用SETNX設(shè)置了master節(jié)點上的鎖,然后開始執(zhí)行贷痪。
  • master節(jié)點在將鎖的信息同步到slave節(jié)點前幻妓,崩潰了
  • slave被切換成master繼續(xù)服務(wù),但此時這個節(jié)點沒有了鎖的信息
  • B調(diào)用SETNX也成功的設(shè)置了鎖(跟A沖突)

這種問題怎么處理呢劫拢?我們需要借助另外的一些master節(jié)點肉津,假設(shè)你有N個redis的master節(jié)點,并且這些節(jié)點之間相互獨立舱沧,不存在同步數(shù)據(jù)的關(guān)系妹沙,然后獲取鎖的操作走下面的過程:

  • 獲取當(dāng)前時間t
  • 然后用t嘗試在N個master節(jié)點上輪流獲取鎖,只有當(dāng)客戶端在大部分master節(jié)點上獲取到了鎖熟吏,才認(rèn)為這個鎖是有效的距糖,否則就釋放所有的鎖。

延時問題

上面這么干分俯,鎖是不是靠譜肾筐?會不會有兩個客戶端可能同時拿到鎖?答案是有可能的缸剪!

我們來分析一下吗铐,假設(shè)從0時刻開始,客戶端向R1, R2, R3, R4, R5三個master節(jié)點發(fā)送了獲取鎖的請求杏节,假設(shè)獲取了R1, R3, R4三把鎖唬渗,受網(wǎng)絡(luò)影響典阵,拿到鎖消耗的實踐分別為T1, T2, T3:

如果鎖的超時時間設(shè)置為T,三把鎖分別釋放的時間為T11, T22和T33:

注意镊逝,客戶端至少在T2壮啊,才會認(rèn)為自己拿到鎖,所以它會認(rèn)為自己在T22時刻才失去鎖撑蒜,但是在T33時刻歹啼,客戶端A已經(jīng)釋放了R1上的鎖,此時另外的一個客戶端是有可能拿到大部分的鎖成為鎖的擁有者座菠,同樣會造成鎖沖突狸眼。

當(dāng)然解決方法也是有的,就是定義鎖的超時時間為:最先釋放鎖的時間-獲取鎖的總消耗時間浴滴,比如上面的情況拓萌,超時時間就應(yīng)該定義為:T11-T2

時鐘差問題

超時問題解決之后,是不是一定可以保證互斥性了呢升略?也不一定微王,因為各個機器之間還可能存在著時鐘差問題,比如客戶端認(rèn)為的T11時刻品嚣,R1所在的服務(wù)器可能認(rèn)為是T1'炕倘,R3所在的服務(wù)器可能認(rèn)為是T1'':

所以,客戶端以為自己還在持有鎖腰根,但實際情況可能這把鎖已經(jīng)被master節(jié)點釋放掉了激才,這種情況該如何處理呢?

這個的解決方式也很簡單额嘿,我們只需要把過期時間定義為:T1'-T2就可以了,其中T1' = T11 - TT劣挫,TT表示機器之間的時鐘偏差册养,一般這個偏差在幾毫秒左右。

總結(jié)

時鐘偏差問題解決后压固,鎖是不是一定就是安全的了呢球拦?忽略一些可有可無的細(xì)節(jié)問題,目前來看是安全的帐我,這種鎖也是redis官方推薦的坎炼,但是官方也承認(rèn)可能隱藏著一些不可知的因素,具體還是要等待大家的發(fā)現(xiàn)拦键。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谣光,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子芬为,更是在濱河造成了極大的恐慌萄金,老刑警劉巖蟀悦,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異氧敢,居然都是意外死亡日戈,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門孙乖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浙炼,“玉大人,你說我怎么就攤上這事唯袄⊥淝” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵越妈,是天一觀的道長季俩。 經(jīng)常有香客問我,道長梅掠,這世上最難降的妖魔是什么酌住? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮阎抒,結(jié)果婚禮上酪我,老公的妹妹穿的比我還像新娘。我一直安慰自己且叁,他們只是感情好都哭,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著逞带,像睡著了一般欺矫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上展氓,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天穆趴,我揣著相機與錄音,去河邊找鬼遇汞。 笑死未妹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的空入。 我是一名探鬼主播络它,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼歪赢!你這毒婦竟也來了化戳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤轨淌,失蹤者是張志新(化名)和其女友劉穎迂烁,沒想到半個月后看尼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡盟步,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年藏斩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片却盘。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡狰域,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出黄橘,到底是詐尸還是另有隱情兆览,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布塞关,位于F島的核電站抬探,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏帆赢。R本人自食惡果不足惜小压,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望椰于。 院中可真熱鬧怠益,春花似錦、人聲如沸瘾婿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽偏陪。三九已至抢呆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間笛谦,已是汗流浹背镀娶。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留揪罕,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓宝泵,卻偏偏與公主長得像好啰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子儿奶,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355