更新時(shí)間:2020-10-30 來(lái)源:黑馬程序員 瀏覽量:
命名服務(wù)(Name
Service)也是分布式系統(tǒng)中比較常見(jiàn)的一類(lèi)場(chǎng)景,是分布式系統(tǒng)最基本的公共服務(wù)之一。在分布式系統(tǒng)中,被命名的實(shí)體通??梢允羌褐械臋C(jī)器、提供的服務(wù)地址或遠(yuǎn)程對(duì)象等——這些我們都可以統(tǒng)稱它們?yōu)槊?Name),其中較為常見(jiàn)的就是一些分布式服務(wù)框架(如RPC、RMI)中的服務(wù)地址列表,通過(guò)使用命名服務(wù),客戶端應(yīng)用能夠根據(jù)指定名字來(lái)獲取資源的實(shí)體、服務(wù)地址和提供者的信息等。
ZooKeeper
提供的命名服務(wù)功能能夠幫助應(yīng)用系統(tǒng)通過(guò)一個(gè)資源引用的方式來(lái)實(shí)現(xiàn)對(duì)資源的定位與使用。另外,廣義上命名服務(wù)的資源定位都不是真正意義的實(shí)體資源——在分布式環(huán)境中,上層應(yīng)用僅僅需要一個(gè)全局唯一的名字,類(lèi)似于數(shù)據(jù)庫(kù)中的唯一主鍵。
所以接下來(lái)。我們來(lái)看看如何使用ZooKeeper來(lái)實(shí)現(xiàn)一套分布式全局唯一ID的分配機(jī)制所謂ID,就是一個(gè)能夠唯一標(biāo)識(shí)某個(gè)對(duì)象的標(biāo)識(shí)符。在我們熟悉的關(guān)系型數(shù)據(jù)庫(kù)中,各個(gè)表都需要一個(gè)主鍵來(lái)唯一標(biāo)識(shí)每條數(shù)據(jù)庫(kù)記錄,這個(gè)主鍵就是這樣的唯一ID。在過(guò)去的單庫(kù)單表型系統(tǒng)中,通??梢允褂脭?shù)據(jù)庫(kù)字段自帶的auto_increment屬性來(lái)自動(dòng)為每條數(shù)據(jù)庫(kù)記錄生成一個(gè)唯一的ID,數(shù)據(jù)庫(kù)會(huì)保證生成的這個(gè)ID在全局唯一。但是隨著數(shù)據(jù)庫(kù)數(shù)據(jù)規(guī)模的不斷增大,分庫(kù)分表隨之出現(xiàn),而auto_increment屬性僅能針對(duì)單一表中的記錄自動(dòng)生成ID,因此在這種情況下,就無(wú)法再依靠數(shù)據(jù)庫(kù)的auto_increment屬性來(lái)唯一標(biāo)識(shí)一條記錄了。于是,我們必須尋求一種能夠在分布式環(huán)境下生成全局唯一ID的方法。
一說(shuō)起全局唯一 ID,相信大家都會(huì)聯(lián)想到 UUID。沒(méi)錯(cuò),UUID 是通用唯一識(shí)別碼(Universally Unique
Identifier)的簡(jiǎn)稱,是一種在分布式系統(tǒng)中廣泛使用的用于唯一標(biāo)識(shí)元素的標(biāo)準(zhǔn)
確實(shí),UUID是一個(gè)非常不錯(cuò)的全局唯一ID生成方式,能夠非常簡(jiǎn)便地保證分布式環(huán)境中的唯一性。一個(gè)標(biāo)準(zhǔn)的 UUID 是一個(gè)包含 32 位字符和 4
個(gè)短線的字符串,例如“e70f1357-f260-46ff-a32d-53a086c57ade”。UUID的優(yōu)勢(shì)自然不必多說(shuō),我們重點(diǎn)來(lái)看看它的缺陷。
長(zhǎng)度過(guò)長(zhǎng)
UUID 最大的問(wèn)題就在于生成的字符串過(guò)長(zhǎng)。顯然,和數(shù)據(jù)庫(kù)中的 INT 類(lèi)型相比,存儲(chǔ)一個(gè)UUID需要花費(fèi)更多的空間。
含義不明
上面我們已經(jīng)看到一個(gè)典型的 UUID 是類(lèi)似于“e70f1357-f260-46ff-a32d-53a086c57ade”的一個(gè)字符串。根據(jù)這個(gè)字符串,開(kāi)發(fā)人員從字面上基本看不出任何其表達(dá)的含義,這將會(huì)大大影響問(wèn)題排查和開(kāi)發(fā)調(diào)試的效率。
所以接下來(lái),我們結(jié)合一個(gè)分布式任務(wù)調(diào)度系統(tǒng)來(lái)看看如何使用ZooKeepe來(lái)實(shí)現(xiàn)這類(lèi)全局唯一ID的生成。
之前我們已經(jīng)提到,通過(guò)調(diào)用ZooKeeper節(jié)點(diǎn)創(chuàng)建的API接口可以創(chuàng)建一個(gè)順序節(jié)點(diǎn),并且在API返回值中會(huì)返回這個(gè)節(jié)點(diǎn)的完整名字。利用這個(gè)特性,我們就可以借助ZooKeeper來(lái)生成全局唯一的ID了,如下圖:
全局唯一ID生成的ZooKeeper節(jié)點(diǎn)示意圖
說(shuō)明,對(duì)于一個(gè)任務(wù)列表的主鍵,使用ZooKeeper生成唯一ID的基本步驟:
所有客戶端都會(huì)根據(jù)自己的任務(wù)類(lèi)型,在指定類(lèi)型的任務(wù)下面通過(guò)調(diào)用create()接口來(lái)創(chuàng)建一個(gè)順序節(jié)點(diǎn),例如創(chuàng)建“job-”節(jié)點(diǎn)。
節(jié)點(diǎn)創(chuàng)建完畢后,create()接口會(huì)返回一個(gè)完整的節(jié)點(diǎn)名,例如“job-0000000003”。
客戶端拿到這個(gè)返回值后,拼接上 type 類(lèi)型,例如“type2-job-0000000003”,這就可以作為一個(gè)全局唯一的ID了。
在ZooKeeper中,每一個(gè)數(shù)據(jù)節(jié)點(diǎn)都能夠維護(hù)一份子節(jié)點(diǎn)的順序順列,當(dāng)客戶端對(duì)其創(chuàng)建一個(gè)順序子節(jié)點(diǎn)的時(shí)候 ZooKeeper
會(huì)自動(dòng)以后綴的形式在其子節(jié)點(diǎn)上添加一個(gè)序號(hào),在這個(gè)場(chǎng)景中就是利用了ZooKeeper的這個(gè)特性。
猜你喜歡:
ZooKeeper數(shù)據(jù)發(fā)布/訂閱使用教程
ZooKeeper數(shù)據(jù)發(fā)布/訂閱使用教程|Publish/Subscribe使用方法
2020-10-30Java中integer和int的區(qū)別|真題案例講解
2020-10-29太原Java開(kāi)發(fā)培訓(xùn)價(jià)格是多少錢(qián)?看完避坑!
2020-10-29什么是哈希?哈希算法是怎么回事?
2020-10-29Java培訓(xùn)班培訓(xùn)費(fèi)用一般是多少?靠譜Java培訓(xùn)機(jī)構(gòu)怎么選?
2020-10-29如何通過(guò)NIO實(shí)現(xiàn)群聊?【黑馬程序員】
2020-10-29