zookeeper(二)zookeeper單機啟動

2021-10-09 17:44:49 字數 3795 閱讀 9365

其實都不用想單機邏輯肯定非常簡單,畢竟一台伺服器,很多都很好實現。

整個流程圖如下:

其中箭頭中的數字是呼叫的順序,橫向表示在同乙個方法中,而黃色區域為該方法的注釋。單機啟動的整個體系就是這個展開的。

從啟動項就能明白,我們指定了配置檔案啟動,所以肯定是把配置檔案的引數解析出來,然後載入到記憶體中,最後初始化好server即可。因為解析配置都很簡單,所以就不說了,主要是後面放到對應的配置類之後做了什麼事?怎麼初始化的?當乙個client傳送請求應該怎麼處理的?這個才是重點需要了解的。

我們直接定位到org.apache.zookeeper.server.zookeeperservermain#runfromconfig這個方法。你可以在這裡打個斷點,直接就粗暴的認為前面就是讀取檔案,實際還有判斷判斷集群單機,快照和事務的定時策略等。

public

void

runfromconfig

(serverconfig config)

throws ioexception

}catch

(interruptedexception e)

finally

}}

這個方法的注釋我也寫出來了。其實重點還是cnxnfactory.startup(zkserver);這行**。前面的**就認為是為整個啟動做準備。

跟蹤到這個**下面:

@override

public

void

startup

(zookeeperserver zks)

throws ioexception,

interruptedexception

這個就很重要了。可以說是單機最核心的啟動流程,針對這四步乙個乙個的說。

1、start()方法:它啟動了乙個執行緒,呼叫執行緒的start()方法,所以直接定位到run()方法中。

public

void

run(

) arraylist

selectedlist =

newarraylist

( selected)

; collections.

shuffle

(selectedlist)

;for

(selectionkey k : selectedlist)

else

}elseif(

(k.readyops()

&(selectionkey.op_read | selectionkey.op_write))!=

0)else}}

selected.

clear()

;}catch

(runtimeexception e)

catch

(exception e)

}closeall()

; log.

info

("nioservercnxn factory exited run method");

}

也就不詳細說了,其實就是不斷的獲取客戶端的資料。

2、setzookeeperserver(zks)比較簡單,就是把配置設定到單機的的啟動類中。

3、zks.startdata():這個方法就比較重要了,因為比如zookeeper啟動過一段時間,然後停止了,但是要再次啟動這些資料再**呢?zookeeper也是做了持久化了的,再次啟動之前就需要把這些配置讀取資料到記憶體。

public

void

startdata()

throws ioexception, interruptedexception if(

!zkdb.

isinitialized()

)}

public

void

loaddata()

throws ioexception, interruptedexception

else

// clean up dead sessions

linkedlist

deadsessions =

newlinkedlist

();for

(long session : zkdb.

getsessions()

)}zkdb.

setdatatreeinit

(true);

for(

long session : deadsessions)

}

我們看看setzxid(zkdb.loaddatabase());這個方法,從頭初始化。

public

long

loaddatabase()

throws ioexception

因為很多其實都在注釋中了,就不多說了。

4、zks.startup()我們在前面做了什麼事呢?再來回想一下。

1、啟動執行緒:為了能夠接收客戶端的資料。

2、配置出乙個zookeeperserver。

3、把zookeeper恢復到上次關閉的狀態。

所以第四步應該做什麼呢?仔細想想前3步。可有什麼沒有做的?

是的。我們還沒有去處理並返回客戶端的請求。所以我們最後啟動是做什麼呢?肯定是初始化請求處理啦!來來來,我們看看這個方法做了什麼。

public

synchronized

void

startup()

//開啟乙個session跟蹤

startsessiontracker()

;//設定乙個請求處理器。傳說中的責任鏈模式。這個有點繞。不過理解了這個模式就好懂。

//流程就是preprequestprocessor->syncrequestprocessor->finalrequestprocessor

setuprequestprocessors()

;//幹嘛的不知道

registerjmx()

;//設定狀態為執行

setstate

(state.running)

;//啟動完成。開始喚醒所有執行緒。這裡不知道有什麼作用,我就算是注釋掉操作照樣能執行。

//但是上一步setstate(state.running);注釋掉客戶端就能連證明至少要到setstate後server才初始化完成。

notifyall()

;}

其它不說,我認為最重要的**是:

setuprequestprocessors()

;

我們看看這個方法裡面是什麼。

protected

void

setuprequestprocessors()

因為這個相當於使用了3個執行緒去處理,每一步都有自己的負責的事情,故而稱之為責任鏈模式(也可以認為是流水線)。至於每個執行緒中的run()方法就不帶進去看了。這個相信用了一段時間zookeeper的人裡面的run()方法應該能看懂。後面這裡補個請求處理鏈的流程圖。

zookeeper學習之路二

zookeeper 是以fast paxos演算法為基礎的,並做了一些優化,解決了活鎖 有多個交錯提交情況時,會出現相互排斥無法成功提交 的問題。zookeeper 基本運轉流程,1.選舉 leader 2.同步資料 3.選舉 leader 標準的一致性 4.leader 要有最高的 zxid 事務...

ZooKeeper學習筆記(二)

2.將解壓後的zookeeper複製出2份,將這三分分別命名 如 z1,z2,z3 ticktime 2000 initlimit 10 synclimit 5 datadir data clientport 2181 server.1 127.0.0.1 2222 2223 server.2 12...

Zookeeper系列二 Zookeeper原理

從擴充套件性開始講起,在zk中存在的角色有leader,follower,observer。zk是讀寫分離的,所有的寫都會壓到leader上面,讀操作可以在follower上面完成。只有follower才能選擇,observer比follower級別還低。observer只是為了放大查詢能力。乙個集...