Apache ZooKeeper - JMX監(jiān)控 ZooKeeper 的運行狀態(tài)">Apache ZooKeeper - JMX監(jiān)控 ZooKeeper 的運行狀態(tài)
899
2025-04-01
文章目錄
流程圖
目的
啟動前的準備工作
解析配置文件
創(chuàng)建文件清理器
服務初始化
ServerStats創(chuàng)建
FileTxnSnapLog
ServerCnxnFactory
初始化請求處理鏈
小結
流程圖
目的
通過對單機版的 ZooKeeper 中的啟動與服務的初始化過程進行分析,來了解 ZooKeeper 服務端相關的處理知識。現(xiàn)在開始深入到服務器端看一看 ZooKeeper 是如何從初始化到對外提供服務的。
啟動前的準備工作
在 ZooKeeper 服務的初始化之前,首先要對配置文件等信息進行解析和載入。也就是在真正開始服務的初始化之前需要對服務的相關參數(shù)進行準備,而 ZooKeeper 服務的準備階段大體上可分為啟動程序入口、zoo.cfg 配置文件解析、創(chuàng)建歷史文件清理器等
QuorumPeerMain 類是 ZooKeeper 服務的啟動接口,可以理解為 Java 中的 main 函數(shù)。 通常我們在控制臺啟動 ZooKeeper 服務的時候,輸入 zkServer.cm 或 zkServer.sh 命令就是用來啟動這個 Java 類的。如下代碼所示,QuorumPeerMain 類函數(shù)只有一個 initializeAndRun 方法,是作用為所有 ZooKeeper 服務啟動邏輯的入口。
package org.apache.zookeeper.server.quorum public class QuorumPeerMain { ... public static void main(String[] args) { ... main.initializeAndRun(args); ... } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
解析配置文件
首先要做的事情就是解析配置文件 zoo.cfg。我們知道zoo.cfg 是服務端的配置文件,在這個文件中可以配置數(shù)據(jù)目錄、端口號等信息。
所以解析 zoo.cfg 配置文件是 ZooKeeper 服務啟動的關鍵步驟。
創(chuàng)建文件清理器
面對大流量的網絡訪問,ZooKeeper 會因此產生海量的數(shù)據(jù),如果磁盤數(shù)據(jù)過多或者磁盤空間不足,則會導致 ZooKeeper 服務器不能正常運行,進而影響整個分布式系統(tǒng)。
所以面對這種問題,ZooKeeper 采用了 DatadirCleanupManager 類作為歷史文件的清理工具類。在 3.4.0 版本后的 ZooKeeper 中更是增加了自動清理歷史數(shù)據(jù)的功能以盡量避免磁盤空間的浪費。
如下代碼所示,DatadirCleanupManager 類有 5 個屬性,其中 snapDir 和 dataLogDir 分別表示數(shù)據(jù)快照地址以及日志數(shù)據(jù)的存放地址。
在日常工作中可以通過在 zoo.cfg 文件中配置 autopurge.snapRetainCount 和 autopurge.purgeInterval 這兩個參數(shù)實現(xiàn)數(shù)據(jù)文件的定時清理功能,
autopurge.purgeInterval 這個參數(shù)指定了清理頻率,以小時為單位,需要填寫一個 1 或更大的整數(shù),默認是 0,表示不開啟自己清理功能。
autopurge.snapRetainCount 這個參數(shù)和上面的參數(shù)搭配使用,這個參數(shù)指定了需要保留的文件數(shù)目,默認是保留 3 個。
public class DatadirCleanupManager { private final File snapDir; private final File dataLogDir; private final int snapRetainCount; private final int purgeInterval; private Timer timer; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
服務初始化
經過了上面的配置文件解析等準備階段后, ZooKeeper 開始服務的初始化階段。初始化階段可以理解為根據(jù)解析準備階段的配置信息,實例化服務對象。服務初始化階段的主要工作是創(chuàng)建用于服務統(tǒng)計的工具類,如下圖所示主要有以下幾種:
ServerStats創(chuàng)建
統(tǒng)計工具類 ServerStats用于統(tǒng)計 ZooKeeper 服務運行時的狀態(tài)信息統(tǒng)計。主要統(tǒng)計的數(shù)據(jù)有服務端向客戶端發(fā)送的響應包次數(shù)、接收到的客戶端發(fā)送的請求包次數(shù)、服務端處理請求的延遲情況以及處理客戶端的請求次數(shù)。在日常運維工作中,監(jiān)控服務器的性能以及運行狀態(tài)等參數(shù)很多都是這個類負責收集的。、
public class ServerStats { private long packetsSent; private long packetsReceived; private long maxLatency; private long minLatency = Long.MAX_VALUE; private long totalLatency = 0; private long count = 0; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FileTxnSnapLog
用來管理 ZooKeeper 的數(shù)據(jù)存儲等相關操作,可以看作為 ZooKeeper 服務層提供底層持久化的接口。在 ZooKeeper 服務啟動過程中,它會根據(jù) zoo.cfg 配置文件中的 dataDir 數(shù)據(jù)快照目錄和 dataLogDir 事物日志目錄來創(chuàng)建 FileTxnSnapLog 類。
package org.apache.zookeeper.server.persistence; public class FileTxnSnapLog { private final File dataDir; private final File snapDir; private TxnLog txnLog; private SnapShot snapLog; private final boolean autoCreateDB }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ServerCnxnFactory
ZooKeeper 中客戶端和服務端通過網絡通信,其本質是通過 Java 的 IO 數(shù)據(jù)流的方式進行通信,但是傳統(tǒng)的 IO 方式具有阻塞等待的問題,而 NIO 框架作為傳統(tǒng)的 Java IO 框架的替代方案,在性能上大大優(yōu)于前者。
也正因如此,NIO 框架也被廣泛應用于網絡傳輸?shù)慕鉀Q方案中。而 ZooKeeper 最早也是使用自己實現(xiàn)的 NIO 框架,但是從 3.4.0 版本后,引入了第三方 Netty 等框架來滿足不同使用情況的需求,而我們可以通過 ServerCnxnFactory 類來設置 ZooKeeper 服務器,從而在運行的時候使用我們指定的 NIO 框架。如代碼中 ServerCnxnFactory 類通過setServerCnxnFactory 函數(shù)來創(chuàng)建對應的工廠類
package org.apache.zookeeper.server; public abstract class ServerCnxnFactory { final public void setZooKeeperServer(ZooKeeperServer zks) { this.zkServer = zks; if (zks != null) { if (secure) { zks.setSecureServerCnxnFactory(this); } else { zks.setServerCnxnFactory(this); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
在通過 ServerCnxnFactory 類制定了具體的 NIO 框架類后。ZooKeeper 首先會創(chuàng)建一個線程
Thread 類作為 ServerCnxnFactory 類的啟動主線程。之后 ZooKeeper 服務再初始化具體的 NIO 類。這里請你注意的是,雖然初始化完相關的 NIO 類 ,比如已經設置好了服務端的對外端口,客戶端也能通過諸如 2181 端口等訪問到服務端,但是此時 ZooKeeper 服務器還是無法處理客戶端的請求操作。這是因為 ZooKeeper 啟動后,還需要從本地的快照數(shù)據(jù)文件和事務日志文件中恢復數(shù)據(jù)。這之后才真正完成了 ZooKeeper 服務的啟動。
初始化請求處理鏈
在完成了 ZooKeeper 服務的啟動后,ZooKeeper 會初始化一個請求處理邏輯上的相關類。這個操作就是初始化請求處理鏈。
所謂的請求處理鏈是一種責任鏈模式的實現(xiàn)方式,根據(jù)不同的客戶端請求,在 ZooKeeper 服務器上會采用不同的處理邏輯。
而為了更好地實現(xiàn)這種業(yè)務場景,ZooKeeper 中采用多個請求處理器類一次處理客戶端請求中的不同邏輯部分。這種處理請求的邏輯方式就是責任鏈模式。而我們這里主要說的是單機版服務器的處理邏輯,主要分為PrepRequestProcessor、SyncRequestProcessor、FinalRequestProcessor 3 個請求處理器,而在一個請求到達 ZooKeeper 服務端進行處理的過程,則是嚴格按照這個順序分別調用這 3 個類處理請求中的對應邏輯。
小結
主要從 ZooKeeper 服務內部的實現(xiàn)邏輯來學習 ZooKeeper 中的相關知識,從單機版服務器的啟動,到對外提供服務的整個過程,逐步分析 ZooKeeper 實現(xiàn)的每個步驟,理解 ZooKeeper 服務器的初始化、配置解析、服務實例化等過程對我們日后在工作中分析排查 ZooKeeper 產生的相關問題以及提高 ZooKeeper 服務器的穩(wěn)定性或性能都有很大的幫助。
Apache ZooKeeper
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。