一、服務器角色
1. Leader
1)事務請求的唯一調度者和處理者。保證事務處理的順序性
事務請求:導致數據一致性的請求(數據發生改變)。如刪除一個節點、創建一個節點、設置節點數據,設置節點權限就是一個事物請求,全局的事物id(zxid)只能由leader來分配
2)集群內部個服務器之間的調度者
2. Follower
1)處理客戶端的非事務請求。事務請求必須轉發給Leader服務器。
非事物請求:讀取數據
2)參與事務請求Proposal(議案)的投票
3)參與Leader選舉
3. Observer
在實際運行中,它只是負責讀,Leader不會將事務的投票發送給Observer。
在zk的配置server.1=master:2888:3888后面加:observer以后就是一個Observer
server.1=master:2888:3888:observer
二、序列化與通信協議
1. zookeeper序列化
常見序列化協議:
ProtoBuf
Thrift
Hessian
Kryo
Avro
JDK Serializable
Jsoniter/Jackson
Jute是zookeeper序列化、反序列化協議。
2. zookeeper通信協議
基於TCP/IP協議,所以是一個長連接。zookeeper在這個基礎上完成客戶端和服務器,服務器和服務器之間的通信。
zookeeper請求包:請求頭+請求體
0-3 |
4-11 |
12-n |
|||
len |
4-7 |
8-11 |
12-15 |
16-(n-1) |
n |
xid |
type |
len |
path |
watch |
zookeeper響應包:響應頭+響應體
0-3 |
4-19 |
20 - n |
|||||
len |
4-7 |
8-15 |
16-19 |
20-23 |
len位 |
48位 |
8位 |
xid |
zxid |
err |
len |
data |
...... |
pzxid |
0-3位:version+dbid+magic(魔數)
三、數據存儲
1. 內存數據
Zk有個內存數據庫:ZkDataBase、DataTree、DataNode
2. 日志數據FileTxnLog
運行時,不停地有數據寫入。
當日志的剩余空間不足4K(4096),日志就做擴充,擴充64M,后面以“0”填充。
log都是使用zxid作為文件名的后綴。
查看日志方式:
cd /software/zookeeper-3.4.6
java -cp ./zookeeper-3.4.6.jar::./lib/log4j-1.2.16.jar:./lib/slf4j-api-1.6.1.jar:./lib/slf4j-log4j12-1.6.1.jar org.apache.zookeeper.server.LogFormatter /zookeeper/zk1/version-2/log.100000001
說明:
1)必須在zookeeper的安裝目錄下執行
2)/zookeeper/zk1/是zookeeper配置文件里面配置的數據目錄(dataDir)
3. 快照數據
快照數據:在某一時刻內存所有全量數據的一個磁盤文件。舉例:快照閾值100000,觸發快照數據。
快照數據都是使用Zxid作為文件名的后綴。這樣的話,獲取快照數據的時候就不用遍歷了,直接根據Zxid去獲取就行了
查看快照命令:
cd /software/zookeeper-3.4.6
java -cp ./zookeeper-3.4.6.jar::./lib/log4j-1.2.16.jar:./lib/slf4j-api-1.6.1.jar:./lib/slf4j-log4j12-1.6.1.jar org.apache.zookeeper.server.SnapshotFormatter /zookeeper/zk1/version-2/snapshot.100000050
說明:
1)必須在zookeeper的安裝目錄下執行
2)/zookeeper/zk1/是zookeeper配置文件里面配置的數據目錄(dataDir)
快照觸發機制,非“半數機制”,過半隨機策略。
logcount > (snapcount/2 + randroll)
logcount: 代表當前記錄日志數量
snapcount: 多少次事務日志記錄后觸發一次數據快照
randroll: 1~snapcount/2 之間的一個隨機數
四、zookeeper總結
ZK在分布式系統中的各種應用,本質其實就是對節點的創建,刪除,數據更新等事件做監聽,監聽到以后做對應的操作
ZK是觀察者設計模式
都是為了解決高可用,解決單點故障問題,數據可靠性