真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Redis中Redlock的示例分析

這篇文章主要介紹了redis中Redlock的示例分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

柳河網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)公司!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)公司于2013年成立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專(zhuān)注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)公司

為什么要用鎖

我待過(guò)的一家k12教育公司,我們當(dāng)時(shí)有個(gè)業(yè)務(wù)場(chǎng)景是這樣的。業(yè)務(wù)這邊要給學(xué)生排課,偶爾會(huì)反饋學(xué)生的課時(shí)明明充足的但是卻提示課時(shí)不足,等再刷新一遍頁(yè)面卻發(fā)現(xiàn)學(xué)生的課時(shí)已經(jīng)不夠了。更可怕的是,偶爾會(huì)有學(xué)生的課時(shí)被扣成負(fù)數(shù)(公司被白嫖課時(shí))。

再比如下面這個(gè)例子

Redis中Redlock的示例分析

上面的這倆個(gè)問(wèn)題都是并發(fā)給我們的業(yè)務(wù)帶來(lái)的問(wèn)題。解決這個(gè)問(wèn)題的核心就是,同一時(shí)間只能允許有一個(gè)請(qǐng)求來(lái)對(duì)這些敏感(重要)的數(shù)據(jù)進(jìn)行讀寫(xiě)操作。所以這個(gè)時(shí)候就要使用到分布式鎖來(lái)限制程序的并發(fā)執(zhí)行。

setnx有哪些問(wèn)題

我們先來(lái)看看用Redis如何實(shí)現(xiàn)分布式鎖,想必大家都很熟悉。比如針對(duì)我文章開(kāi)頭講的學(xué)生排課的問(wèn)題我們就可以這樣加鎖

Redis中Redlock的示例分析

這就是我們常規(guī)使用setnx來(lái)實(shí)現(xiàn)鎖的方式。

現(xiàn)在我們假設(shè)有這樣一個(gè)場(chǎng)景。A請(qǐng)求拿到鎖到了第2步給學(xué)生排課的時(shí)候程序掛了,沒(méi)有釋放鎖。那么這個(gè)鎖就成了死鎖,下一個(gè)操作同一個(gè)學(xué)生的請(qǐng)求永遠(yuǎn)就拿不到鎖,那么這個(gè)學(xué)生就沒(méi)法被排課了。這個(gè)時(shí)候都需要手動(dòng)去把鎖釋放掉。

為了解決死鎖的問(wèn)題,我們給鎖加一個(gè)過(guò)期時(shí)間。

Redis中Redlock的示例分析

加上過(guò)期時(shí)間之后,如果A請(qǐng)求沒(méi)有主動(dòng)釋放鎖,在鎖過(guò)期之后也會(huì)主動(dòng)釋放,這樣B請(qǐng)求一樣可以獲取鎖處理業(yè)務(wù)邏輯。但是如果在加過(guò)期時(shí)間的時(shí)候也就是在第1步和第2步之間程序崩潰。那還是會(huì)出現(xiàn)死鎖的問(wèn)題。這個(gè)問(wèn)題的根源就在于setnx和expire這兩條指令不是原子指令。所以如果setnx和expire能夠要么全部執(zhí)行要么一個(gè)都不執(zhí)行那該多好。

為此在Redis2.8之前社區(qū)涌現(xiàn)了一大批擴(kuò)展包來(lái)解決該問(wèn)題。官方為了治理該亂象,在2.8版本中加入了set指令的擴(kuò)展參數(shù)使得setnx和expire指令可以一起執(zhí)行,所以現(xiàn)在我們使用分布式鎖應(yīng)該是這樣了

Redis中Redlock的示例分析

這樣看起來(lái)已經(jīng)很完美了,已經(jīng)達(dá)成了我們的期望“setnx和expire能夠要么全部執(zhí)行要么一個(gè)都不執(zhí)行那該多好”。我們?cè)偌僭O(shè)現(xiàn)在有如下場(chǎng)景:

A請(qǐng)求現(xiàn)在獲取到了鎖,鎖的超時(shí)時(shí)間設(shè)置的是5秒。到了第2步執(zhí)行業(yè)務(wù)邏輯,結(jié)果因?yàn)槟承┰?秒之后業(yè)務(wù)邏輯還沒(méi)有執(zhí)行完,此時(shí)鎖由于超時(shí)自動(dòng)釋放了。這個(gè)時(shí)候B請(qǐng)求也來(lái)了,拿到鎖之后開(kāi)始執(zhí)行業(yè)務(wù)邏輯。A請(qǐng)求這個(gè)時(shí)候業(yè)務(wù)邏輯執(zhí)行完了,開(kāi)始執(zhí)行第三步,釋放了鎖。而這個(gè)時(shí)候鎖是B請(qǐng)求拿到的,結(jié)果被A請(qǐng)求釋放了。那么C請(qǐng)求就可以拿到鎖了。這個(gè)時(shí)候B請(qǐng)求和C請(qǐng)求就會(huì)導(dǎo)致并發(fā)問(wèn)題了。所以可以從這個(gè)例子看出來(lái),在分布式鎖中過(guò)期時(shí)間的設(shè)置非常重要,如果設(shè)置的時(shí)間小于這個(gè)接口的響應(yīng)時(shí)間那么仍然會(huì)產(chǎn)生并發(fā)問(wèn)題。所以我們可以參考接口響應(yīng)時(shí)長(zhǎng)的監(jiān)控來(lái)設(shè)置鎖的過(guò)期時(shí)間。

Redlock

我們上述的方案都是基于單點(diǎn)的Redis的實(shí)現(xiàn)方式。單點(diǎn)的Redis實(shí)現(xiàn)分布式鎖基本上可以滿足95%的業(yè)務(wù)場(chǎng)景。剩下的5%就是對(duì)數(shù)據(jù)一致性要求極其嚴(yán)苛并且對(duì)于鎖丟失的0容忍的業(yè)務(wù)場(chǎng)景。這個(gè)時(shí)候就得考慮Redlock了。至于單點(diǎn)的Redis即使通過(guò)sentinel保證高可用,如果這個(gè)master節(jié)點(diǎn)由于某些原因發(fā)生了主從切換,如果數(shù)據(jù)主從數(shù)據(jù)同步不及時(shí)那么勢(shì)必會(huì)有數(shù)據(jù)丟失,那么就會(huì)出現(xiàn)鎖丟失的情況。

假設(shè)存在多個(gè)Redis實(shí)例,這些節(jié)點(diǎn)是完全獨(dú)立的,不需要使用復(fù)制或者任何協(xié)調(diào)數(shù)據(jù)的系統(tǒng),我們假設(shè)有5個(gè)Redis master節(jié)點(diǎn),客戶端為了取到鎖,步驟將會(huì)變成這樣:

  • 以毫秒為單位獲取當(dāng)前的服務(wù)器時(shí)間

  • 嘗試使用相同的key和隨機(jī)值來(lái)獲取鎖,客戶端對(duì)每一個(gè)機(jī)器獲取鎖時(shí)都應(yīng)該有一個(gè)超時(shí)時(shí)間,比如鎖的過(guò)期時(shí)間為10s,那么獲取單個(gè)節(jié)點(diǎn)鎖的超時(shí)時(shí)間就應(yīng)該為5到50毫秒左右,他這樣做的目的是為了保證客戶端與故障的機(jī)器連接不耗費(fèi)多余的時(shí)間!超時(shí)間時(shí)間內(nèi)未獲取數(shù)據(jù)就放棄該節(jié)點(diǎn),從而去下一個(gè)Redis節(jié)點(diǎn)獲取。

  • 獲取完成后,獲取當(dāng)前時(shí)間減去步驟一獲取的時(shí)間,當(dāng)且僅當(dāng)客戶端從半數(shù)以上(這里是3個(gè)節(jié)點(diǎn))的Redis節(jié)點(diǎn)獲取到鎖且獲取鎖的時(shí)間小于鎖額超時(shí)時(shí)間,則證明該鎖生效!

  • 如果取到了鎖,key的真正有效時(shí)間等于有效時(shí)間減去獲取鎖所使用的時(shí)間(步驟3計(jì)算的結(jié)果)。

  • 如果獲取鎖的機(jī)器不滿足半數(shù)以上,或者鎖的超時(shí)時(shí)間計(jì)算完畢后為負(fù)數(shù)等異常操作,則系統(tǒng)會(huì)嘗試解鎖所有實(shí)例,即便某些Redis實(shí)例根本就沒(méi)有加鎖成功,防止某些節(jié)點(diǎn)獲取到鎖但是客戶端沒(méi)有得到響應(yīng)而導(dǎo)致接下來(lái)的一段時(shí)間不能被重新獲取鎖

所以我們看出,redlock其實(shí)是比單點(diǎn)Redis看起來(lái)更加可靠的鎖。

如果你跟我一樣是Node.js程序員那么正好有第三方庫(kù)redlock直接使用。

我們真的需要redlock嗎

關(guān)于redlock其實(shí)也有另外一種聲音,Martin Kleppmann(劍橋大學(xué)的研究員,從事數(shù)據(jù)庫(kù)、分布式系統(tǒng)和信息安全交叉領(lǐng)域的TRVE DATA項(xiàng)目)寫(xiě)過(guò)一篇blog發(fā)表了關(guān)于對(duì)redlock的一些看法,感興趣的可以看看。Redis作者Salvatore也對(duì)這篇文章的疑問(wèn)做出了一些回應(yīng),還挺有意思的。作者的blog主要的觀點(diǎn)如下:

分布式鎖的用途無(wú)非兩種:

  • 效率:使用鎖可以避免不必要地做同樣的工作兩次(例如一些昂貴的計(jì)算)。如果鎖定失敗并且兩個(gè)節(jié)點(diǎn)最終完成相同的工作,結(jié)果是成本略有增加(您最終向 AWS 支付的費(fèi)用比其他情況多 5 美分)或帶來(lái)輕微的不便(例如,用戶最終兩次收到相同的電子郵件通知)。

  • 正確性:使用鎖可以防止并發(fā)進(jìn)程相互干擾并破壞系統(tǒng)狀態(tài)。如果鎖定失敗并且兩個(gè)節(jié)點(diǎn)同時(shí)處理同一條數(shù)據(jù),則結(jié)果是文件損壞、數(shù)據(jù)丟失、永久性不一致、給患者服用的藥物劑量錯(cuò)誤或其他一些非常嚴(yán)重的問(wèn)題。

如果是為了效率,則根本沒(méi)有必要承擔(dān) Redlock 的成本和復(fù)雜性,鎖丟失導(dǎo)致多發(fā)幾次郵件和運(yùn)行 5 個(gè) Redis 服務(wù)器的成本相比,最好只使用單個(gè) Redis 實(shí)例。如果你使用的是單個(gè) Redis 實(shí)例,Redis 節(jié)點(diǎn)突然斷電或者崩潰,或者出現(xiàn)其他問(wèn)題,這個(gè)時(shí)候當(dāng)然會(huì)丟失鎖。但是如果你只是將鎖用作效率優(yōu)化,而且這種崩潰不會(huì)經(jīng)常發(fā)生,那沒(méi)什么大不了的。這種“沒(méi)什么大不了”的場(chǎng)景是 也恰好是Redis優(yōu)秀的地方。至少如果依賴單個(gè) Redis 實(shí)例,那么查看系統(tǒng)的每個(gè)人都能夠更方便的定位問(wèn)題。

如果是為了正確性,那么嚴(yán)格來(lái)講,redlock根本不具有強(qiáng)一致的嚴(yán)格性。舉了一些例子

  • 時(shí)序和系統(tǒng)時(shí)鐘做出了危險(xiǎn)的假設(shè),對(duì)每臺(tái)服務(wù)器的時(shí)鐘強(qiáng)依賴。因?yàn)橛邢到y(tǒng)有GC的存在,做GC的時(shí)整個(gè)服務(wù)器是夯住的,時(shí)間也就停滯了,所以我們不能夠?qū)r(shí)鐘有強(qiáng)依賴。

  • 沒(méi)有令牌??蛻舳嗣看潍@取鎖的時(shí)候服務(wù)端沒(méi)有下發(fā)令牌,服務(wù)端應(yīng)該校驗(yàn)每次操作的時(shí)候客戶端的令牌要與服務(wù)端當(dāng)前的令牌一致才難操作鎖。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Redis中Redlock的示例分析”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!


分享標(biāo)題:Redis中Redlock的示例分析
轉(zhuǎn)載注明:http://weahome.cn/article/pshddi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部