Zookeeper Server持久化兩類資料,Transaction以及Snapshot,logDir儲存transaction命令,dataDir儲存snap快照,其下子目錄名稱以version-2命名,子目錄內部檔案是分別以log.zxid和snapshot. lastProcessedZxid命名,每個目錄下可以有很多個這樣的檔案,
Transaction檔案的檔案名稱中zxid是檔案中所有命令中zxid最小的zxid,而Snapshot中的lastProcessedZxid是最後一個操作的zxid,一般來講是最大的zxid。
交易記錄記錄的是當前要操作的命令以及命令參數,可以認為是動態,快照記錄的是當前的ZK待用資料結構,包括ACL,節點樹,session/臨時節點對應關係,從下面的結構中可以分析到並沒有持久化watch相關資料,watch是怎麼搞後面我還得看看。
Transactionlog儲存的檔案格式:
LogFile: FileHeader TxnList ZeroPad FileHeader: { magic 4bytes (ZKLG) version 4bytes(2) dbid 8bytes //該檔案所屬資料庫 } TxnList: Txn || Txn TxnList Txn: checksum Txnlen TxnHeader Record 0x42 checksum: 8bytes Adler32 is currently used calculated across payload -- Txnlen, TxnHeader, Record and 0x42 Txnlen: len 4bytes TxnHeader: { sessionid 8bytes cxid 4bytes//用戶端的xid zxid 8bytes//伺服器事務xid time 8bytes//伺服器事務開始時間 type 4bytes//操作的類型 } Record: See Jute definition file for details on the various record types ZeroPad: 0 padded to EOF (filled during preallocation stage)
可以尋找最後一個zxid,尋找zxid所在的檔案,以及刪除zxid以後的所有記錄和檔案。
Snapshot 檔案格式:
FileSnap: FileHeader sessionsData DataTree checksum /[分割線] FileHeader: { magic 4bytes (ZKSN) version 4bytes(2) dbid 8bytes //該檔案所屬資料庫 } sessionsData:{ sessioncount 4bytes sessionList} sessionList: session || session session:{ id 8bytes //sessionid timeout 4bytes//到期時間 } DataTree: ACLS Nodes ACLS: Aclsize acllist Acllist: longId acls Acls: Perms id{schema,id} Nodes:Path node childnodesChildnoes: Path node childnodesNode:Data[bytes] acl[long] stat[統計資訊] Stat:Czxid createNode時事務號mzxid, createNode時與Czxid同,setData時的事務號ctime 建立節點時間mtime createNode時與ctime相同,setData時間version createNode版本為0,setData的資料版本號碼cversion createNode版本為0,增加/刪除子節點時父節點+1aversion createNode版本為0,setACL時節點的版本號碼ephemeralOwner 臨時節點表示sessionid,非臨時節點這個值為0pzxid createNode時與Czxid同,增加/刪除子節點時為子節點事務號FileTxnSnapLog. Restore時會讀取snapshot然後根據snapshot中lastProcessedZxid+1後讀取命令log重做命令附加到DataTree上。