天天看點

HBase存儲剖析與資料遷移1.概述2.内容3.日志資訊4.資料存儲5.Region分割6.磁盤合理規劃7.資料遷移8.總結9.結束語

1.概述

  HBase的存儲結構和關系型資料庫不一樣,HBase面向半結構化資料進行存儲。是以,對于結構化的SQL語言查詢,HBase自身并沒有接口支援。在大資料應用中,雖然也有SQL查詢引擎可以查詢HBase,比如Phoenix、Drill這類。但是閱讀這類SQL查詢引擎的底層實作,依然是調用了HBase的Java API來實作查詢,寫入等操作。這類查詢引擎在業務層建立Schema來映射HBase表結構,然後通過解析SQL文法數,最後底層在調用HBase的Java API實作。

  本篇内容,筆者并不是給大家來介紹HBase的SQL引擎,我們來關注HBase更低層的東西,那就是HBase的存儲實作。以及跨叢集的HBase叢集資料遷移。

2.内容

  HBase資料庫是唯一索引就是RowKey,所有的資料分布和查詢均依賴RowKey。是以,HBase資料庫在表的設計上會有很嚴格的要求,從存儲架構上來看,HBase是基于分布式來實作的,通過Zookeeper叢集來管理HBase中繼資料資訊,比如表名就存放在Zookeeper的/hbase/table目錄下。如下圖所示:

HBase存儲剖析與資料遷移1.概述2.内容3.日志資訊4.資料存儲5.Region分割6.磁盤合理規劃7.資料遷移8.總結9.結束語

2.1 Architecture

  HBase是一個分布式存儲系統,底層資料存儲依賴Hadoop的分布式存儲系統(HDFS)。HBase架構分三部分來組成,它們分别是:ZooKeeper、HMaster和HRegionServer。

  • ZooKeeper:HBase的中繼資料資訊、HMaster程序的位址、Master和RegionServer的監控維護(節點之間的心跳,判斷節點是否下線)等内容均需要依賴ZooKeeper來完成。是HBase叢集中不可缺少的核心之一。
  • HMaster:HMaster程序在HBase中承擔Master的責任,負責一些管理操作,比如給表配置設定Region、和資料節點的心跳維持等。一般用戶端的讀寫資料的請求操作不會經過Master,是以在配置設定JVM記憶體的适合,一般32GB大小即可。
  • HRegionServer:HRegionServer程序在HBase中承擔RegionServer的責任,負責資料的存儲。每個RegionServer由多個Region組成,一個Region維護一定區間的RowKey的資料。如下圖所示:
HBase存儲剖析與資料遷移1.概述2.内容3.日志資訊4.資料存儲5.Region分割6.磁盤合理規劃7.資料遷移8.總結9.結束語

  圖中Region(dn2:16030)維護的RowKey範圍為0001~0002。HBase叢集的存儲結構如下圖所示:

  Zookeeper通常由奇數個組成,便于分布式選舉,可參考《

分布式系統選舉算法剖析

》一文了解,這裡不多贅述細節。HBase為了保證高可用性(HA),一般都會部署兩個Master節點,其中一個作為主,另一個作為Backup節點。這裡誰是主,誰是Backup取決于那個HMaster程序能從Zookeeper上對應的Master目錄中競争到Lock,持有該目錄Lock的HMaster程序為主Master,而另外一個為Backup,當主Master發生意外或者當機時,Backup的Master會立刻競争到Master目錄下的Lock進而接管服務,成為主Master對外提供服務,保證HBase叢集的高可用性。

2.2 RegionServer

  HBase負責資料存儲的就是RegionServer,簡稱RS。在HBase叢集中,如果隻有一份副本時,整個HBase叢集中的資料都是唯一的,沒有備援的資料存在,也就是說HBase叢集中的每個RegionServer節點上儲存的資料都是不一樣的,這種模式由于副本數隻有一份,即是配置多個RegionServer組成叢集,也并不是高可用的。這樣的RegionServer是存在單點問題的。雖然,HBase叢集内部資料有Region存儲和Region遷移機制,RegionServer服務的單點問題可能花費很小的代價可以恢複,但是一旦停止RegionServre上含有ROOT或者META表的Region,那這個問題就嚴重,由于資料節點RegionServer停止,該節點的資料将在短期内無法通路,需要等待該節點的HRegionServer程序重新啟動才能通路其資料。這樣HBase的資料讀寫請求如果恰好指向該節點将會收到影響,比如:抛出連接配接異常、RegionServer不可用等異常。

3.日志資訊

  HBase在實作WAL方式時會産生日志資訊,即HLog。每一個RegionServer節點上都有一個HLog,所有該RegionServer節點上的Region寫入資料均會被記錄到該HLog中。HLog的主要職責就是當遇到RegionServer異常時,能夠盡量的恢複資料。

  在HBase運作的過程當中,HLog的容量會随着資料的寫入越來越大,HBase會通過HLog過期政策來進行定期清理HLog,每個RegionServer内部均有一個HLog的監控線程。HLog資料從MemStore Flush到底層存儲(HDFS)上後,說明該時間段的HLog已經不需要了,就會被移到“oldlogs”這個目錄中,HLog監控線程監控該目錄下的HLog,當該檔案夾中的HLog達到“hbase.master.logcleaner.ttl”(機關是毫秒)屬性所配置的閥值後,監控線程會立即删除過期的HLog資料。

4.資料存儲

  HBase通過MemStore來緩存Region資料,大小可以通過“hbase.hregion.memstore.flush.size”(機關byte)屬性來進行設定。RegionServer在寫完HLog後,資料會接着寫入到Region的MemStore。由于MemStore的存在,HBase的資料寫入并非是同步的,不需要立刻響應用戶端。由于是異步操作,具有高性能和高資源使用率等優秀的特性。資料在寫入到MemStore中的資料後都是預先按照RowKey的值來進行排序的,這樣便于查詢的時候查找資料。

5.Region分割

  在HBase存儲中,通過把資料配置設定到一定數量的Region來達到負載均衡。一個HBase表會被配置設定到一個或者多個Region,這些Region會被配置設定到一個或者多個RegionServer中。在自動分割政策中,當一個Region中的資料量達到閥值就會被自動分割成兩個Region。HBase的表中的Region按照RowKey來進行排序,并且一個RowKey所對應的Region隻有一個,保證了HBase的一緻性。

  一個Region中由一個或者多個Store組成,每個Store對應一個列族。一個Store中包含一個MemStore和多個Store Files,每個列族是分開存放以及分開通路的。自動分割有三種政策,分别是:

  • ConstantSizeRegionSplitPolicy:在HBase-0.94版本之前是預設和唯一的分割政策。當某一個Store的大小超過閥值時(hbase.hregion.max.filesize,預設時10G),Region會自動分割。
  • IncreasingToUpperBoundRegionSplitPolicy:在HBase-0.94中,這個政策分割大小和表的RegionServer中的Region有關系。分割計算公式為:Min(R*R*'hbase.hregion.memstore.flush.size','hbase.hregion.max.filesize'),其中,R表示RegionServer中的Region數。比如:hbase.hregion.memstore.flush.size=256MB,hbase.hregion.max.filesize=20GB,那麼第一次分割的大小為Min(1*1*256,20GB)=256MB,也就是在第一次大到256MB會分割成2個Region,後續以此公式類推計算。
  • KeyPrefixRegionSplitPolicy:可以保證相同字首的RowKey存放在同一個Region中,可以通過hbase.regionserver.region.split.policy屬性來指定分割政策。

6.磁盤合理規劃

  部署HBase叢集時,磁盤和記憶體的規劃是有計算公式的。随意配置設定可能造成叢集資源使用率不高導緻存在浪費的情況。公式如下:

# 通過磁盤次元的Region數和Java Heap次元的Region數來推導      Disk Size/(RegionSize*ReplicationFactor)=Java Heap*HeapFractionForMemstore/(MemstoreSize/2)      

  公式中對應的hbase-site.xml檔案中的屬性中,見下表:

Key Property
Disk Size 磁盤容量大小,一般一台伺服器有多塊磁盤
RegionSize hbase.hregion.max.filesize預設10G,推薦範圍在10GB~30GB
ReplicationFactor dfs.replication預設為3
Java Heap 配置設定給HBase JVM的記憶體大小
HeapFractionForMemstore hbase.regionserver.global.memstore.lowerLimit預設為0.4
MemstoreSize hbase.hregion.memstore.flush.size預設為128M

  在實際使用中,MemstoreSize空間打下隻使用了一半(1/2)的容量。 舉個例子,一個RegionServer的副本數配置為3,RegionSize為10G,HBase的JVM記憶體配置設定45G,HBase的MemstoreSize為128M,那此時根據公式計算得出理想的磁盤容量為45G*1024*0.4*2*10G*1024*3/128M=8.5T左右磁盤空間。如果此時,配置設定一個節點中挂載10個可用盤,共27T。那将有兩倍的磁盤空間不比對造成浪費。 為了提升磁盤比對度,可以将RegionSize值提升至30G,磁盤空間計算得出25.5T,基本和27T磁盤容量比對。

7.資料遷移

  對HBase叢集做跨叢集資料遷移時,可以使用Distcp方案來進行遷移。該方案需要依賴MapReduce任務來完成,是以在執行遷移指令之前確定新叢集的ResourceManager、NodeManager程序已啟動。同時,為了檢視遷移進度,推薦開啟proxyserver程序和historyserver程序,開啟這2個程序可以友善在ResourceManager業務檢視MapReduce任務進行的進度。 遷移的步驟并不複雜,在新叢集中執行distcp指令即可。具體操作指令如下所示:

# 在新叢集的NameNode節點執行指令     [hadoop@nna ~]$ hadoop distcp -Dmapreduce.job.queue.name=queue_0001_01 -update -skipcrccheck -m 100 hdfs://old_hbase:9000/hbase/data/tabname /hbase/data/tabname      

  為了遷移友善,可以将上述指令封裝成一個Shell腳本。具體實作如下所示:

#! /bin/bash     for i in `cat /home/hadoop/hbase/tbl`     do     echo $i     hadoop distcp -Dmapreduce.job.queue.name=queue_0001_01 -update -skipcrccheck -m 100 hdfs://old_hbase:9000/hbase/data/$i /hbase/data/$i     done     hbase hbck -repairHoles      

  将待遷移的表名記錄在/home/hadoop/hbase/tbl檔案中,一行代表一個表。内容如下所示:

hadoop@nna ~]$ vi /home/hadoop/hbase/tbl     # 表名清單     tbl1     tbl2     tbl3     tbl4      

  最後,在循環疊代遷移完成後,執行HBase指令“hbase hbck -repairHoles”來修複HBase表的中繼資料,如表名、表結構等内容,會從新注冊到新叢集的Zookeeper中。

8.總結

  HBase叢集中如果RegionServer上的Region數量很大,可以适當調整“hbase.hregion.max.filesize”屬性值的大小,來減少Region分割的次數。在執行HBase跨叢集資料遷移時,使用Distcp方案來進行,需要保證HBase叢集中的表是靜态資料,換言之,需要停止業務表的寫入。如果在執行HBase表中資料遷移時,表持續有資料寫入,導緻遷移異常,抛出某些檔案找不到。

9.結束語

  這篇部落格就和大家分享到這裡,如果大家在研究學習的過程當中有什麼問題,可以加群進行讨論或發送郵件給我,我會盡我所能為您解答,與君共勉。

聯系方式:

郵箱:[email protected]

Twitter:

https://twitter.com/smartloli

QQ群(Hadoop - 交流社群1):

424769183

溫馨提示:請大家加群的時候寫上加群理由(姓名+公司/學校),友善管理者稽核,謝謝!

熱愛生活,享受程式設計,與君共勉!

作者:哥不是小蘿莉 [ 關于我 ][ 犒賞

出處: http://www.cnblogs.com/smartloli/

轉載請注明出處,謝謝合作!