IT技術互動(dong)交流平jiao)/h4>

美娱彩票官网

作者︰leesf  來源(yuan)︰IT165收集  發布日期︰2020-02-26 01:45:27

一(yi)、前ba)/strong>

  前面分析了Zookeeper對(dui)請求的處(chu)理,本篇博(bo)文接著分析Zookeeper中(zhong)如(ru)何對(dui)底層數據進行xie)媧  荽媧 環治 詿媸荽媧 詿排淌荽媧 /p>

二(er)、數據與存儲

  2.1 內存數據

  Zookeeper的數據模(mo)型是(shi)樹結構,在內存數據庫中(zhong)xiao) 媧 甦ke)樹的內容,包括所有(you)的節點路徑(jing)、節點數據、ACL信息,Zookeeper會定時將這個數據存儲到磁盤上。

  1. DataTree

  DataTree是(shi)內存數據存儲的核心mo) shi)一(yi)個樹結構,代表了內存中(zhong)一(yi)份完整的數據。DataTree不(bu)包含任何與網絡(luo)、客戶端連(lian)接及請求處(chu)理相(xiang)關的業(ye)務邏輯,是(shi)一(yi)個獨立的組件(jian)。

  2. DataNode

  DataNode是(shi)數據存儲的最小單(dan)元,其內部除了保存了結點的數據內容、ACL列表、節點狀態(tai)之外(wai),還記錄了父節點的引用和子節點列表兩個屬性,其也(ye)提供了對(dui)子節點列表進行操作的接口。

  3. ZKDatabase

  Zookeeper的內存數據庫,管理Zookeeper的所有(you)會話、DataTree存儲和事務日志。ZKDatabase會定時向磁盤dump快照數據,同時在Zookeeper啟(qi)動(dong)時,會通(tong)過(guo)磁盤的事務日志和快照文件(jian)恢復成一(yi)個完整的內存數據庫。

  2.2 事務日志

  1. 文件(jian)存儲

  在配置Zookeeper集群(qun)時需要配置dataDir目錄,其用來存儲事務日志文件(jian)。也(ye)可以為事務日志單(dan)獨分配一(yi)個文件(jian)存儲目錄:dataLogDir。若配置dataLogDir為/home/admin/zkData/zk_log,那麼Zookeeper在運行過(guo)程中(zhong)會在該目錄下建立一(yi)個名(ming)字(zi)為version-2的子目錄,該目錄確定了當前Zookeeper使(shi)用的事務日志格式版(ban)本號,當下次(ci)某個Zookeeper版(ban)本jing)dui)事務日志格式進行變更時,此(ci)目錄jia)ye)會變更,即(ji)在version-2子目錄下會生成一(yi)系(xi)列文件(jian)大小一(yi)致(64MB)的文件(jian)。

  2. 日志格式

  在配置好日志文件(jian)目錄,啟(qi)動(dong)Zookeeper後(hou),完成如(ru)下操作

  (1) 創建/test_log節點,初始(shi)值為v1。

  (2) 更新/test_log節點的數據為v2。

  (3) 創建/test_log/c節點,初始(shi)值為v1。

  (4) 刪除/test_log/c節點。

  經(jing)過(guo)四步操作後(hou),會在/log/version-2/目錄下生成一(yi)個日志文件(jian),筆者下是(shi)log.cec。

  將Zookeeper下的zookeeper-3.4.6.jar和slf4j-api-1.6.1.jar復制到/log/version-2目錄下,使(shi)用如(ru)下命(ming)令(ling)打開log.cec文件(jian)。

  java -classpath ./zookeeper-3.4.6.jar:./slf4j-api-1.6.1.jar org.apache.zookeeper.server.LogFormatter log.cec

  

  ZooKeeper Transactional Log File with dbid 0 txnlog format version 2 。是(shi)文件(jian)頭信息,主要是(shi)事務日志的DBID和日志格式版(ban)本號。  

  ...session 0x159...0xcec createSession 30000。表示(shi)客戶端會話創建操作。

  ...session 0x159...0xced create '/test_log,... 。表示(shi)創建/test_log節點,數據內容為#7631(v1)。

  ...session 0x159...0xcee setData ‘/test_log,...。表示(shi)設(she)置了/test_log節點數據,內容為#7632(v2)。

  ...session 0x159...0xcef create ’/test_log/c,...。表示(shi)創建節點/test_log/c。

  ...session 0x159...0xcf0 delete '/test_log/c。表示(shi)刪除節點/test_log/c。

  3. 日志寫(xie)入

  FileTxnLog負(fu)責維護事務日志jing)dui)外(wai)的接口,包括事務日志的寫(xie)入和讀取等。Zookeeper的事務日志寫(xie)入過(guo)程大體(ti)可以分為如(ru)下6個步驟。

  (1) 確定是(shi)否有(you)事務日志可寫(xie)。當Zookeeper服務器啟(qi)動(dong)完成需要進行第一(yi)次(ci)事務日志的寫(xie)入,或(huo)是(shi)上一(yi)次(ci)事務日志寫(xie)滿時,都會處(chu)于與事務日志文件(jian)斷開的狀態(tai),即(ji)Zookeeper服務器沒有(you)和任意一(yi)個日志文件(jian)相(xiang)關聯。因此(ci)在進行事務日志寫(xie)入前,Zookeeper首先會判斷FileTxnLog組件(jian)是(shi)否已(yi)經(jing)關聯上一(yi)個可寫(xie)的事務日志文件(jian)。若沒有(you)xiao) 蚧 shi)用該事務操作關聯的ZXID作為後(hou)綴創建一(yi)個事務日志文件(jian),同時構建事務日志的文件(jian)頭信息,並立即(ji)寫(xie)入這個事務日志文件(jian)中(zhong)去,同時將該文件(jian)的文件(jian)流放(fang)入streamToFlush集合,該集合用來記錄當前需要強制進行數據落(luo)盤的文件(jian)流。

  (2) 確定事務日志文件(jian)是(shi)否需要擴容(預分配)。Zookeeper會采用磁盤空(kong)間預分配策略。當檢測到當前事務日志文件(jian)剩(sheng)余(yu)空(kong)間不(bu)足4096字(zi)節時,就會開始(shi)進行文件(jian)空(kong)間擴容,即(ji)在現有(you)文件(jian)大小上,將文件(jian)增(zeng)加65536KB(64MB),然後(hou)使(shi)用'0'填充(chong)被擴容的文件(jian)空(kong)間。

  (3) 事務序(xu)列化。對(dui)事務頭和事務體(ti)的序(xu)列化,其中(zhong)事務體(ti)又可分為會話創建事務、節點創建事務、節點刪除事務、節點數據更新事務等。

  (4) 生成Checksum。為保證日志文件(jian)的完整性和數據的準確性,Zookeeper在將事務日志寫(xie)入文件(jian)前,會計算生成Checksum。

  (5) 寫(xie)入事務日志文件(jian)流。將序(xu)列化後(hou)的事務頭、事務體(ti)和Checksum寫(xie)入文件(jian)流中(zhong)xiao) ci)時並為寫(xie)入到磁盤上。

  (6) 事務日志刷入磁盤。由于步驟5中(zhong)的緩存原因,無法實時地寫(xie)入磁盤文件(jian)中(zhong)xiao) 虼ci)需要將緩存數據強制刷入磁盤。

  4. 日志截斷

  在Zookeeper運行過(guo)程中(zhong)xiao) 贍?魷址fei)Leader記錄的事務ID比Leader上大,這是(shi)非(fei)法運行狀態(tai)。此(ci)時,需要保證所有(you)機器必須與該Leader的數據保持同步,即(ji)Leader會發送TRUNC命(ming)令(ling)給該機器,要求進行日志截斷,Learner收到該命(ming)令(ling)後(hou),就會刪除所有(you)包含或(huo)大于該事務ID的事務日志文件(jian)。

  2.3 snapshot-數據快照

  數據快照是(shi)Zookeeper數據存儲中(zhong)非(fei)常核心的nao)誦謝疲 菘 沼美醇鍬ookeeper服務器上某一(yi)時刻的全量(liang)內存數據內容,並將其寫(xie)入指定的磁盤文件(jian)中(zhong)。

  1. 文件(jian)存儲

  與事務文件(jian)類似,Zookeeper快照文件(jian)也(ye)可以指定特(te)定磁盤目錄,通(tong)過(guo)dataDir屬性來配置。若指定dataDir為/home/admin/zkData/zk_data,則在運行過(guo)程中(zhong)會在該目錄下創建version-2的目錄,該目錄確定了當前Zookeeper使(shi)用的快照數據格式版(ban)本號。在Zookeeper運行時,會生成一(yi)系(xi)列文件(jian)。

  2. 數據快照

  FileSnap負(fu)責維護快照數據對(dui)外(wai)的接口,包括快照數據的寫(xie)入和讀取等,將內存數據庫寫(xie)入快照數據文件(jian)其實是(shi)一(yi)個序(xu)列化過(guo)程。針對(dui)客戶端的每(mei)一(yi)次(ci)事務操作,Zookeeper都會將他們記錄到事務日志中(zhong)xiao)  幣ye)會將數據變更應用到內存數據庫中(zhong)xiao)ookeeper在進行若干次(ci)事務日志記錄後(hou),將內存數據庫的全量(liang)數據Dump到本地文件(jian)中(zhong)xiao) 餼褪shi)數據快照。其步驟如(ru)下

  (1) 確定是(shi)否需要進行數據快照。每(mei)進行一(yi)次(ci)事務日志記錄之後(hou),Zookeeper都會檢測當前是(shi)否需要進行數據快照,考慮(lv)到數據快照對(dui)于Zookeeper機器的影響(xiang),需要盡量(liang)避(bi)免(mian)Zookeeper集群(qun)中(zhong)的所有(you)機器在同一(yi)時刻進行數據快照。采用過(guo)半隨機策略進行數據快照操作。

  (2) 切換事務日志文件(jian)。表示(shi)當前的事務日志已(yi)經(jing)寫(xie)滿,需要重(zhong)新創建一(yi)個新的事務日志。

  (3) 創建數據快照異步線程。創建單(dan)獨的異步線程來進行數據快照以避(bi)免(mian)影響(xiang)Zookeeper主流程。

  (4) 獲取全量(liang)數據和會話信息。從ZKDatabase中(zhong)獲取到DataTree和會話信息。

  (5) 生成快照數據文件(jian)名(ming)。Zookeeper根據當前已(yi)經(jing)提交的最大ZXID來生成數據快照文件(jian)名(ming)。

  (6) 數據序(xu)列化。首先序(xu)列化文件(jian)頭信息,然後(hou)再對(dui)會話信息和DataTree分別進行序(xu)列化,同時生成一(yi)個Checksum,一(yi)並寫(xie)入快照數據文件(jian)中(zhong)去。

  2.4 初始(shi)化

  在Zookeeper服務器啟(qi)動(dong)期間,首先會進行數據初始(shi)化工(gong)作,用于將存儲在磁盤上xi)氖菸募jian)加載到Zookeeper服務器內存中(zhong)。

  1. 初始(shi)化流程

  Zookeeper的書初始(shi)化過(guo)程如(ru)下圖所示(shi)

  數據的初始(shi)化工(gong)作是(shi)從磁盤上加載數據的過(guo)程,主要包括了從快照文件(jian)中(zhong)加載快照數據和根據實物日志進行數據修正兩個過(guo)程。

  (1) 初始(shi)化FileTxnSnapLog。FileTxnSnapLog是(shi)Zookeeper事務日志和快照數據訪問層,用于餃接上層業(ye)務和底層數據存儲,底層數據包含了事務日志和快照數據兩部分。FileTxnSnapLog中(zhong)對(dui)應FileTxnLog和FileSnap。

  (2) 初始(shi)化ZKDatabase。首先構建DataTree,同時將FileTxnSnapLog交付ZKDatabase,以便內存數據庫能夠對(dui)事務日志和快照數據進行訪問。在ZKDatabase初始(shi)化時,DataTree也(ye)會進行相(xiang)應的初始(shi)化工(gong)作,如(ru)創建一(yi)些默(mo)認結點,如(ru)/、/zookeeper、/zookeeper/quota三個節點。

  (3) 創建PlayBackListener。其主要用來接you)帳攣裼τ霉guo)程中(zhong)的回調,在Zookeeper數據恢復後(hou)期,會有(you)事務修正過(guo)程,此(ci)過(guo)程會回調PlayBackListener來進行對(dui)應的數據修正。

  (4) 處(chu)理快照文件(jian)。此(ci)時可以yuan)喲排討zhong)恢復數據了,首先從快照文件(jian)開始(shi)加載。

  (5) 獲取最新的100個快照文件(jian)。更新時間最晚(wan)的快照文件(jian)包含了最新的全量(liang)數據。

  (6) 解析快照文件(jian)。逐個解析快照文件(jian),此(ci)時需要進行反序(xu)列化,生成DataTree和sessionsWithTimeouts,同時還會校(xiao)驗(yan)Checksum及快照文件(jian)的正確性。對(dui)于100個快找文件(jian),如(ru)果(guo)正確性校(xiao)驗(yan)通(tong)過(guo)時,通(tong)常只會解析最新的那個快照文件(jian)。只有(you)最新快照文件(jian)不(bu)可用時,才會逐個進行解析,直至100個快照文件(jian)全部解析完。若將100個快照文件(jian)解析完後(hou)還gu)shi)無法成功恢復一(yi)個完整的DataTree和sessionWithTimeouts,此(ci)時服務器啟(qi)動(dong)失敗。

  (7) 獲取最新的ZXID。此(ci)時根據快照文件(jian)的文件(jian)名(ming)即(ji)可解析出最新的ZXID︰zxid_for_snap。該ZXID代表了Zookeeper開始(shi)進行數據快照的時刻。

  (8) 處(chu)理事務日志。此(ci)時服務器內存中(zhong)已(yi)經(jing)有(you)了一(yi)份近似全量(liang)的數據,現在開始(shi)通(tong)過(guo)事務日志來更新增(zeng)量(liang)數據。

  (9) 獲取所有(you)zxid_for_snap之後(hou)提交的事務。此(ci)時,已(yi)經(jing)可以獲取快照數據的最新ZXID。只需要從you)攣袢罩局zhong)獲取所有(you)ZXID比步驟7得到的ZXID大的事務操作。

  (10) 事務應用。獲取大于zxid_for_snap的事務後(hou),將其逐個應用到之前基(ji)于快照數據文件(jian)恢復出來的DataTree和sessionsWithTimeouts。每(mei)當有(you)一(yi)個事務被應用到內存數據庫中(zhong)後(hou),Zookeeper同時會回調PlayBackListener,將這事務操作記錄轉換成Proposal,並保存到ZKDatabase的committedLog中(zhong)xiao) 員ollower進行快速同步。

  (11) 獲取最新的ZXID。待所有(you)的事務都被完整地應用到內存數據庫中(zhong)後(hou),也(ye)就基(ji)本上完成了數據的初始(shi)化過(guo)程,此(ci)時再次(ci)獲取ZXID,用來標識上次(ci)服務器正常運行時提交的最大事務ID。

  (12) 校(xiao)驗(yan)epoch。epoch標識了當前Leader周期,集群(qun)機器相(xiang)互通(tong)信時,會帶上這個epoch以確保彼此(ci)在同一(yi)個Leader周期中(zhong)。完成數據加載後(hou),Zookeeper會從步驟11中(zhong)確定ZXID中(zhong)解析出事務處(chu)理的Leader周期︰epochOfZxid。同時也(ye)會從磁盤的currentEpoch和acceptedEpoch文件(jian)中(zhong)讀取上次(ci)記錄的最新的epoch值,進行校(xiao)驗(yan)。

  2.5 數據同步

  整個集群(qun)完成Leader選舉後(hou),Learner會向Leader進行注冊,當Learner向Leader完成注冊後(hou),就進入數據同步環節,同步過(guo)程就是(shi)Leader將那些沒有(you)在Learner服務器上提交過(guo)的事務請求同步給Learner服務器,大體(ti)過(guo)程如(ru)下

  (1) 獲取Learner狀態(tai)。在注冊Learner的最後(hou)階(jie)段,Learner服務器會發送給Leader服務器一(yi)個ACKEPOCH數據包,Leader會從這個數據包中(zhong)解析出該Learner的currentEpoch和lastZxid。

  (2) 數據同步初始(shi)化。首先從Zookeeper內存數據庫中(zhong)提取出事務請求對(dui)應的提議緩存隊(dui)列proposals,同時完成peerLastZxid(該Learner最後(hou)處(chu)理的ZXID)、minCommittedLog(Leader提議緩存隊(dui)列commitedLog中(zhong)最小的ZXID)、maxCommittedLog(Leader提議緩存隊(dui)列commitedLog中(zhong)的最大ZXID)三個ZXID值的初始(shi)化。

  對(dui)于集群(qun)數據同步而言,通(tong)常分為四類,直接差異化同步(DIFF同步)、先回滾再差異化同步(TRUNC+DIFF同步)、僅回滾同步(TRUNC同步)、全量(liang)同步(SNAP同步),在初始(shi)化階(jie)段,Leader會優先以全量(liang)同步方式來同步數據。同時,會根據Leader和Learner之間的數據差異情況來決定最終的數據同步方式。

  · 直接差異化同步(DIFF同步,peerLastZxid介(jie)于minCommittedLog和maxCommittedLog之間)。Leader首先向這個Learner發送一(yi)個DIFF指令(ling),用于通(tong)知(zhi)Learner進入差異化數據同步階(jie)段,Leader即(ji)將把(ba)一(yi)些Proposal同步給自己,針對(dui)每(mei)個Proposal,Leader都會通(tong)過(guo)發送PROPOSAL內容數據包和COMMIT指令(ling)數據包來完成,

  · 先回滾再差異化同步(TRUNC+DIFF同步,Leader已(yi)經(jing)將事務記錄到本地事務日志中(zhong)xiao) dan)是(shi)沒有(you)成功發起Proposal流程)。當Leader發現某個Learner包含了一(yi)條(tiao)自己沒有(you)的事務記錄,那麼就需要該Learner進行事務回滾,回滾到Leader服務器上存在的mo)  幣ye)是(shi)最接近于peerLastZxid的ZXID。

  · 僅回滾同步(TRUNC同步,peerLastZxid大于maxCommittedLog)。Leader要求Learner回滾到ZXID值為maxCommittedLog對(dui)應的事務操作。

  · 全量(liang)同步(SNAP同步,peerLastZxid小于minCommittedLog或(huo)peerLastZxid不(bu)等于lastProcessedZxid)。Leader無法直接you)shi)用提議緩存隊(dui)列和Learner進行同步,因此(ci)只能進行全量(liang)同步。Leader將本機的全量(liang)內存數據同步給Learner。Leader首先向Learner發送一(yi)個SNAP指令(ling),通(tong)知(zhi)Learner即(ji)將進行全量(liang)同步,隨後(hou),Leader會從內存數據庫中(zhong)獲取到全量(liang)的數據節點和會話超時時間記錄器,將他們序(xu)列化後(hou)傳輸給Learner。Learner接you)盞礁萌 liang)數據後(hou),會對(dui)其反序(xu)列化後(hou)載入到內存數據庫中(zhong)。

三、總(zong)結

  本篇博(bo)文主要講解了Zookeeper的數據與存儲,包括內存數據,快照數據,以及如(ru)何進行數據的同步等細節,至此(ci),Zookeeper的理論學習部分已(yi)經(jing)全部完成,之後(hou)會進行源(yuan)碼(ma)分析,也(ye)謝謝各(ge)位園友的觀看~

  • 美娱彩票官网

About IT165 - 廣告服務 - 隱私聲(sheng)明(ming) - 版(ban)權申明(ming) - 免(mian)責條(tiao)款 - 網站地圖 - 網友投稿 - 聯系(xi)方式
本站內容來自于互聯網,僅供用于網絡(luo)技術學習,學習中(zhong)請遵循相(xiang)關法律法規
美娱彩票官网 | 下一页