HBase WAL原理學習


1.概述 
客戶端往RegionServer端提交數據的時候,會寫WAL日志,只有當WAL日志寫成功以后,客戶端才會被告訴提交數據成功,如果寫WAL失敗會告知客戶端提交失敗,換句話說這其實是一個數據落地的過程。在一個RegionServer上的所有的Region都共享一個HLog,一次數據的提交是先寫WAL,再寫memstore,示意圖如下 
 

2.HLog Class 
WAL的實現類是HLog,當一個Region被初始化的時候,一個HLog的實例會作為構造函數的參數傳進去。當Region在處理Put、Delete等更新操作時,可以直接使用該共享的HLog的append方法來落地數據。Put、Delete在客戶端上可以通過setWriteToWAL(false)方法來關閉該操作的日志,這么做雖然可以提升入庫速度,但最好別這么做,因為有數據丟失的風險存在。 
HLog的另一個重要功能是跟蹤變化,這個通過sequence number來實現。sequence number作為HFile里的一個元數據字段,它用來跟蹤哪些日志是已經持久化了的,哪些還在內存中。(注:通過對源碼的分析,這種變化因為每個Region是不一樣的,所以在HLog的日志里是記錄了多條,是針對於每個Region來記錄的,把該Region的最后一次持久化的seqId作為一條日志寫入HLog,這樣,比該seqId小的數據就是已經持久化過的了。)(照這種分析,在HLog replay的過程中,豈不是從后往前replay日志更方便么?有待學習replay的實現方式來驗證) 

 
這個圖表明同一個RegionServer上的三個Region共享一個HLog,因此當它們寫數據時,是把<HLogKey,WALEdit>這個的數據對按順序混合的寫到HLog上的,以獲得最好的寫入速度。 

3.HLogKey Class 

WAL現在是通過Hadoop的SequenceFile來存儲key/value集合。value簡單的存儲了來自客戶端的數據如row key, column family, column qualifier, timestamp, type, and value;而HLogKey則存儲了the region and table name、還有更新時間、sequence number和cluster ID,cluster ID用於將日志復制到集群里的其他機器上。 

4.WALEdit Class 
來自客戶端的更新數據的請求被封裝到WALEdit類上。這個類把對row數據的修改原子化。(怎么原子化的還得看源碼) 
5.LogSyncer Class 
Table在創建的時候,有一個參數可以設置,是否每次寫Log日志都需要往集群里的其他機器同步一次,默認是每次都同步,同步的開銷是比較大的,但不及時同步又可能因為機器宕而丟日志。 
Pipeline vs. n-Way Writes 
同步的操作現在是通過Pipeline的方式來實現的,Pipeline是指datanode接收數據后,再傳給另外一台datanode,是一種串行的方式;n-Way Writes是指多datanode同時接收數據,最慢的一台結束就是整個結束。差別在於一個延遲大,一個並發高,hdfs現在正在開發中,以便可以選擇是按Pipeline還是n-Way Writes來實現寫操作。 
Table如果設置每次不同步,則寫操作會被RegionServer緩存,並啟動一個LogSyncer線程來定時同步日志,定時時間默認是一秒也可由hbase.regionserver.optionallogflushinterval設置 

5、HLog的幾個特點
 
WAL(Write-Ahead-Log)HBaseRegionServer在處理數據插入和刪除的過程中用來記錄操作內容的一種日志。在每次PutDelete等一條記錄時,首先將其數據封裝成〉,appendRegionServer對應的 HLog文件的過程。它有幾個重要的特點:
    1RegionServer上所有的Region共享HLog文件;也就是RegionServer的個數與HLog是一一對應的,為什么不選擇每個Table對應一個HLog的原因是,通過RegionServer的個數可以衡量分布式系統的規模,這是系統運維可以控制的因素,而Table的個數和大小完全是由應用層來決定。極端情況下,我們的HBase集群可能只有一張大表 (每天10億規模的讀寫),而可能需要上百個節點搭建HBase集群,在這種情況下,按照RegionServer記錄一個HLog的意義就凸現出來了。 同樣的道理可以解釋,為什么要把所有的Regionlog都插入同一個文件。

HBase中WAL(Write-Ahead-Log)的特性與場景分析

 1 RegionServerWAL文件與Region的關系圖


2HLog也是記錄在HDFS上;這一個眾所周知的問題,這里提出來的原因在於,在大多數情況下它成為了影響了HBase寫操作吞吐的重要因素。如圖23顯示,在對表格進行批量刪除數據時,每次操作時不寫HLog比寫HLog,性能要好大概10~20倍。而且正是由於寫HDFS的原因,可以看到大概有些點的性能偏離平均值2倍以上的性能。對於圖2WAL而言,這些點大部分屬於寫HDFS響應的時間的異常點。在HBase-0.92版本中,使用的append操作在hdfs底層其實是一種write操作,而這種操作在遇到超過block預設大小時,會有一次和NameNode的操作,另外在高負載的HDFS集群上,寫速度波浪式的,不會持續保持穩定,而這種不穩定對於像append這樣的操作,最終在反復測試時,就會表現出現偏離平均值2倍以上的1%現象。相比較而言,圖3由於沒有寫WAL,可以看到它不僅在平均性能上表現更好,也在穩定性上更勝一籌,它的抖動出現在MemStoreHDFS刷數據的時間點上。顯然,在MemStore足夠大的情況下,這種波動是可以預期的,甚至也是很多應用可以容忍的。

HBase中WAL(Write-Ahead-Log)的特性與場景分析

 

 

 2WAL批量刪除數據的性能圖



HBase中WAL(Write-Ahead-Log)的特性與場景分析

 

                            圖 3不寫WAL批量刪除數據的性能圖

    WAL 還是不寫 WAL ,在一定程度上確實會給系統性能產生了很大影響,根據 HBase 內部設計, WAL 是一種規避數據丟失風險的一種補償機制,如果應  用可以容忍一定的數據丟失的風險,可以嘗試在更新數據時,關閉寫 WAL 下一篇文章,會介紹使用不寫 WAL 刪除數據失效的場景。

   3HLog是系統穩定的重要依據。在一個HRegionServer的存活周期內,可能因為長時間的Stop-The-World GC,或者因為它所依賴的HDFS或者ZooKeeper,出現下線的情況,對於一個高負載的HBase生產集群而言,這是一個非常常見的現象。對於RegionServer的下線,往往通過jps監控進程存活和nc –z來監控關鍵服務端口的存活狀態來驗證服務的狀態,保證讓下線的RegionServer盡快恢復,保證原HBase集群的整體負載的吞吐。在RegionServer下線這個過程中,是HBase內部最核心部件工作的關鍵時期,簡單總結一下RegionServer下線后內核處理流程如下:

  •  (1) HMasterZooKeeper捕獲到對應RegionServerznode被刪除,將其放入ServerManagerDeadSevers列表中。
  • 2)啟動ServerShutdownHandler,進入該handler的處理流程中。
  • 3SplitLogManager對原RegionServerHLog文件夾內的Hlog文件提交到zookeepersplitlog路徑下。(注意,HLog存在Roll操作,造成了Hlog文件夾內可能存在多個hlog文件)
  • 4SplitLogManager等待RegionServer上的SplitLogWorker認領任務,並在任務完成之后,進入Region Assign流程。每個SplitLogWorker都會經歷將HLog上出現的所有Region分別以文件的形式存儲,在hbase所在hdfs根目錄下splitlog文件夾內,會以RegionServer認領一個某個下線的RegionServerHLog為文件夾名,包含按照Region分散開來的Hlog文件集。
  • 5HMasterAssignmentManager.META.以及當前處於InTransaction狀態的集合中,計算出需要AssignRegion,然后通過getRegionPlan獲得將該Region遷移的目的地址,並修改Region狀態從Offline變成OPENING。然后AssignmentManager就進入了狀態機的處理流程中。
  • 6)被選中目的地的RegionMaster通過RPC讓其執行openRegion操作,RegionSever使用HRegion.openRegion,會首先經歷一次replayRecoveredEditsIfAny,將那些散落在splitlog下各個worker處理過的RegionHlog信息加載過來,並執行replay
  • 7)所有相關的Region處理完畢,這樣一個RegionServer下線的影響就結束了。在這段時間內,相應Region的讀寫操作全部暫停。你如果客戶端寫得比較友好,Region上線有足夠快的話,對於客戶端而言,相當於一次服務抖動,只是這個抖動有點大。

從這個流程中可以看出,雖然HLog采用了Distributed Split來加快切分,但是這里Hlog的穩定仍然是服務穩定性重要因素。因此,有一項比較有趣的事情時,我們完全可以做一個備用的RegionServer來輪詢是否有RegionServer處於下線狀態,一旦處於下線狀態,就按照只讀的方式來加載相應的Region,這樣至少可以保證在RegionServer下線,可以保證數據服務的一定的可用性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM