2023-01-06
節(jié)點(diǎn) child 分布式
1. 分布式鎖的介紹
在Java的多線程部分,我們知道如果在一個(gè)jvm進(jìn)程中,多個(gè)線程之間同時(shí)訪問(wèn)一個(gè)資源,此時(shí)會(huì)有多線程的安全問(wèn)題。為了解決這個(gè)線程安全的問(wèn)題,我們可以使用“鎖”來(lái)實(shí)現(xiàn)。但是,多個(gè)jvm進(jìn)程之間如果同時(shí)訪問(wèn)一個(gè)資源呢?此時(shí)在Java部分學(xué)習(xí)到的“鎖”已經(jīng)不能解決這個(gè)問(wèn)題了,我們就需要“分布式鎖”來(lái)實(shí)現(xiàn)這樣的效果了。
維基百科對(duì)分布式鎖的定義:
分布式鎖,是控制分布式系統(tǒng)之間同步訪問(wèn)共享資源的一種方式。在分布式系統(tǒng)中,常常需要協(xié)調(diào)他們的動(dòng)作。如果不同的系統(tǒng)或是同一個(gè)系統(tǒng)的不同主機(jī)之間共享了一個(gè)或一組資源,那么訪問(wèn)這些資源的時(shí)候,往往需要互斥來(lái)防止彼此干擾來(lái)保證一致性,在這種情況下,便需要使用到分布式鎖。
2. 分布式鎖的分類
在不同的業(yè)務(wù)場(chǎng)景下,分布式鎖也有不同的使用方式,常見(jiàn)的分類有兩種: 阻塞鎖 和 非阻塞鎖。
阻塞鎖:
當(dāng)有多個(gè)jvm進(jìn)程同時(shí)訪問(wèn)一個(gè)共享的資源的時(shí)候,已經(jīng)搶到分布式鎖的jvm進(jìn)程執(zhí)行自己的業(yè)務(wù)邏輯,沒(méi)有搶到分布式鎖的jvm進(jìn)程進(jìn)入阻塞狀態(tài)等待。獲取到分布式鎖的jvm進(jìn)程在處理完自己的業(yè)務(wù)邏輯之后,會(huì)將鎖進(jìn)行釋放。
執(zhí)行自己的業(yè)務(wù)邏輯爭(zhēng)搶分布式鎖事物開(kāi)始搶到了鎖沒(méi)有搶到鎖釋放鎖事務(wù)結(jié)束
非阻塞鎖:
當(dāng)有多個(gè)jvm進(jìn)程同時(shí)訪問(wèn)一個(gè)共享的資源的時(shí)候,已經(jīng)搶到分布式鎖的jvm進(jìn)程執(zhí)行自己的業(yè)務(wù)邏輯,沒(méi)有搶到分布式鎖的jvm進(jìn)程不會(huì)等待,直接結(jié)束,不執(zhí)行任何的業(yè)務(wù)邏輯。
爭(zhēng)搶分布式鎖執(zhí)行自己的業(yè)務(wù)邏輯事物開(kāi)始搶到了鎖釋放鎖事務(wù)結(jié)束沒(méi)有搶到鎖
3. 分布式鎖的原理
使用ZooKeeper實(shí)現(xiàn)分布式鎖,其實(shí)就是在Zookeeper上進(jìn)行節(jié)點(diǎn)的創(chuàng)建。多個(gè)程序同時(shí)需要操作一個(gè)共享的資源時(shí),可以先在ZooKeeper進(jìn)行節(jié)點(diǎn)的注冊(cè),注冊(cè)成功的表示搶到了鎖,注冊(cè)失敗的表示沒(méi)有獲取到鎖。
3.1. 使用節(jié)點(diǎn)實(shí)現(xiàn)
所有的程序向ZooKeeper中注冊(cè)同一個(gè)指定名字的節(jié)點(diǎn),首先將節(jié)點(diǎn)創(chuàng)建成功的程序持有鎖,可以操作共享資源。后來(lái)的程序在進(jìn)行節(jié)點(diǎn)創(chuàng)建的時(shí)候,發(fā)現(xiàn)鎖已經(jīng)存在了,于是無(wú)法重復(fù)注冊(cè)。
3.2. 使用子節(jié)點(diǎn)實(shí)現(xiàn)
所有的程序向ZooKeeper中的指定節(jié)點(diǎn)下注冊(cè)子節(jié)點(diǎn)(需要使用短暫、有序節(jié)點(diǎn)),以節(jié)點(diǎn)的序號(hào)為優(yōu)先級(jí),序號(hào)小的更早注冊(cè),序號(hào)大的晚注冊(cè)。于是,序號(hào)小的節(jié)點(diǎn)獲取到鎖,其他的程序依次向前監(jiān)聽(tīng)節(jié)點(diǎn)。
以/root節(jié)點(diǎn),5個(gè)程序?yàn)槔?
A程序注冊(cè)節(jié)點(diǎn)/root/child0001
此時(shí)子節(jié)點(diǎn): { child0001 }
自己就是序號(hào)最小的節(jié)點(diǎn),可以獲取鎖,執(zhí)行自己的邏輯操作
B程序注冊(cè)節(jié)點(diǎn)/root/child0002
此時(shí)的子節(jié)點(diǎn): { child0001, child0002 }
B發(fā)現(xiàn)自己不是最小的節(jié)點(diǎn),說(shuō)明有人捷足先登了,于是監(jiān)聽(tīng)自己前面的child0001節(jié)點(diǎn)
C程序注冊(cè)節(jié)點(diǎn)/root/child0003
此時(shí)的子節(jié)點(diǎn): { child0001, child0002, child0003 }
C發(fā)現(xiàn)自己不是最小的節(jié)點(diǎn),說(shuō)明有人捷足先登了,于是監(jiān)聽(tīng)自己前面的child0002節(jié)點(diǎn)
此時(shí)A程序執(zhí)行結(jié)束了,由于是短暫類型的節(jié)點(diǎn),因此child0001節(jié)點(diǎn)會(huì)被刪除
此時(shí)的子節(jié)點(diǎn): { child0002, child0003 }
B程序由于監(jiān)聽(tīng)了child0001,因此可以得知這個(gè)節(jié)點(diǎn)已經(jīng)被刪除了,被喚醒之后發(fā)現(xiàn)自己就是最小的節(jié)點(diǎn),獲取到鎖,執(zhí)行邏輯
D程序注冊(cè)節(jié)點(diǎn)/root/child0004
此時(shí)的子節(jié)點(diǎn): { child0002, child0003, child0004 }
D發(fā)現(xiàn)自己不是最小的節(jié)點(diǎn),說(shuō)明有人捷足先登了,于是監(jiān)聽(tīng)自己前面的child0003節(jié)點(diǎn)
此時(shí)B程序執(zhí)行結(jié)束了,由于是短暫類型的節(jié)點(diǎn),因此child0002節(jié)點(diǎn)會(huì)被刪除
此時(shí)的子節(jié)點(diǎn): { child0003, child0004 }
C程序由于監(jiān)聽(tīng)了child0002,因此可以得知這個(gè)節(jié)點(diǎn)已經(jīng)被刪除了,被喚醒之后發(fā)現(xiàn)自己就是最小的節(jié)點(diǎn),獲取到鎖,執(zhí)行邏輯
E程序注冊(cè)節(jié)點(diǎn)/root/child0005
此時(shí)的子節(jié)點(diǎn): { child0003, child0004, child0005 }
E發(fā)現(xiàn)自己不是最小的節(jié)點(diǎn),說(shuō)明有人捷足先登了,于是監(jiān)聽(tīng)自己前面的child0004節(jié)點(diǎn)
...
開(kāi)班時(shí)間:2021-04-12(深圳)
開(kāi)班盛況開(kāi)班時(shí)間:2021-05-17(北京)
開(kāi)班盛況開(kāi)班時(shí)間:2021-03-22(杭州)
開(kāi)班盛況開(kāi)班時(shí)間:2021-04-26(北京)
開(kāi)班盛況開(kāi)班時(shí)間:2021-05-10(北京)
開(kāi)班盛況開(kāi)班時(shí)間:2021-02-22(北京)
開(kāi)班盛況開(kāi)班時(shí)間:2021-07-12(北京)
預(yù)約報(bào)名開(kāi)班時(shí)間:2020-09-21(上海)
開(kāi)班盛況開(kāi)班時(shí)間:2021-07-12(北京)
預(yù)約報(bào)名開(kāi)班時(shí)間:2019-07-22(北京)
開(kāi)班盛況Copyright 2011-2023 北京千鋒互聯(lián)科技有限公司 .All Right 京ICP備12003911號(hào)-5 京公網(wǎng)安備 11010802035720號(hào)