HBase的優化

一、HBase的優化

1,高可用

  在 HBase 中 HMaster 負責監控 HRegionServer 的生命周期,均衡 RegionServer 的負載,如果 HMaster 掛掉了,那麼整個 HBase 集群將陷入不健康的狀態,並且此時的工作狀態並不會維持太久。所以 HBase 支援對 HMaster 的高可用配置。

1.關閉 HBase 集群(如果沒有開啟則跳過此步)
  [xcc@linux01 hbase]$ bin/stop-hbase.sh
2.在 conf 目錄下創建 backup-masters 文件
  [xcc@linux01 hbase]$ touch conf/backup-masters
3.在 backup-masters 文件中配置高可用 HMaster 節點
  [xcc@linux01 hbase]$ echo linux02 > conf/backup-masters
4.將整個 conf 目錄 scp 到其他節點
  [xcc@linux01 hbase]$ scp -r conf/ linux02:/opt/module/hbase/
  [xcc@linux01 hbase]$ scp -r conf/ linux03:/opt/module/hbase/
5.打開頁面測試查看
  http://linux01:16010

2,預分區

  每一個region維護著StartRow與EndRow,如果加入的數據符合某個Region維護的RowKey範圍,則該數據交給這個Region維護。那麼按照這個原則,我們可以將數據所要投放的分區提前大致的規劃好,以提高HBase性能。

1.手動設定預分區
  Hbase> create 'staff1','info','partition1',SPLITS => ['1000','2000','3000','4000']
2.生成 16 進位序列預分區
  Hbase> create 'staff2','info','partition2',{NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}
3.按照文件中設置的規則預分區
創建 splits.txt 文件內容如下:
  aaaa
  bbbb
  cccc
  dddd
然後執行:
  Hbase> create 'staff3','partition3',SPLITS_FILE => 'splits.txt'
4.使用 JavaAPI 創建預分區
//自定義演算法,產生一系列 hash 散列值存儲在二維數組中
byte[][] splitKeys = 某個散列值函數
//創建 HbaseAdmin 實例
HBaseAdmin hAdmin = new HBaseAdmin(HbaseConfiguration.create());
//創建 HTableDescriptor 實例
HTableDescriptor tableDesc = new HTableDescriptor(tableName);
//通過 HTableDescriptor 實例和散列值二維數組創建帶有預分區的 Hbase 表 
hAdmin.createTable(tableDesc, splitKeys);

3,RowKey 設計

  一條數據的唯一標識就是RowKey,那麼這條數據存儲於哪個分區,取決於RowKey處於哪個預分區的區間內。設計RowKey的主要目的,就是讓數據均勻的分布於所有的region中,在一定程度上防止數據傾斜。RowKey的常用設計方案為:
  1)生成隨機數、hash、散列值
比如:
原 本 rowKey 為 1001 的 , SHA1 後 變 成 :
dd01903921ea24941c26a48f2cec24e0bb0e8cc7
原 本 rowKey 為 3001 的 , SHA1 後 變 成 :
49042c54de64a1e9bf0b33e00245660ef92dc7bd
原 本 rowKey 為 5001 的 , SHA1 後 變 成 :
7b61dec07e02c188790670af43e717f0f46e8913
在做此操作之前,一般我們會選擇從數據集中抽取樣本,來決定什麼樣的 rowKey 來 Hash
後作為每個分區的臨界值。

  2)字元串反轉

#這樣可以一定程度上散列put進來的數據
20200524000001
轉成 10000042500202 20200524000002 轉成 20000042500202

  3)字元串拼接

20170524000001_a12e
20170524000001_93i7

4,記憶體優化

  HBase 操作過程中需要大量的記憶體開銷,畢竟 Table 是可以快取在記憶體中的,一般會分配整個可用記憶體的 70%給 HBase 的 Java 堆。但是不建議分配非常大的堆記憶體,因為 GC 過程持續太久會導致 RegionServer 處於長期不可用狀態,一般 16~48G 記憶體就可以了,如果因為框架佔用記憶體過高導致系統記憶體不足,框架一樣會被系統服務拖死。

5,基礎優化

  1)允許在HDFS的文件中追加內容

  hdfs-site.xml、hbase-site.xml

屬性:dfs.support.append
解釋:開啟 HDFS 追加同步,可以優秀的配合 HBase 的數據同步和持久化。默認值為 true

  2)優化DataNode允許的最大文件打開數

  hdfs-site.xml

屬性:dfs.datanode.max.transfer.threads
解釋:HBase 一般都會同一時間操作大量的文件,根據集群的數量和規模以及數據動作,設置為 4096 或者更高。默認值:4096

  3)優化延遲高的數據操作的等待時間

  hdfs-site.xml

屬性:dfs.image.transfer.timeout
解釋:如果對於某一次數據操作來講,延遲非常高,socket 需要等待更長的時間,建議把該值設置為更大的值(默認 60000 毫秒),以確保 socket 不會被 timeout 掉。

  4)優化數據的寫入效率

  mapred-site.xml

屬性:mapreduce.map.output.compress
     mapreduce.map.output.compress.codec
解釋:開啟這兩個數據可以大大提高文件的寫入效率,減少寫入時間。第一個屬性值修改為true,第二個屬性值修改為:org.apache.hadoop.io.compress.GzipCodec 或者其他壓縮方式。

  5)設置RPC監聽數量

  hbase-site.xml

屬性:Hbase.regionserver.handler.count
解釋:默認值為 30,用於指定 RPC 監聽的數量,可以根據客戶端的請求數進行調整,讀寫請求較多時,增加此值。

  6)優化HStore文件大小

  hbase-site.xml

屬性:hbase.hregion.max.filesize
解釋:默認值 10737418240(10GB),如果需要運行 HBase 的 MR 任務,可以減小值,因為一個 region 對應一個 map 任務,如果單個 region 過大,會導致 map 任務執行時間過長。該值的意思就是,如果 HFile 的大小達到這個數值,則這個 region 會被切分為兩個 Hfile。

  7)優化HBase客戶端快取

  hbase-site.xml

屬性:hbase.client.write.buffer
解釋:用於指定 Hbase 客戶端快取,增大該值可以減少 RPC 調用次數,但是會消耗更多記憶體,反之則反之。一般我們需要設定一定的快取大小,以達到減少 RPC 次數的目的。

  8)指定scan.next掃描HBase所獲取的行數

  hbase-site.xml

屬性:hbase.client.scanner.caching
解釋:用於指定 scan.next 方法獲取的默認行數,值越大,消耗記憶體越大。

  9)flush、compact、split 機制

  當 MemStore 達到閾值,將 Memstore 中的數據 Flush 進 Storefile;compact 機制則是把 flush出來的小文件合併成大的 Storefile 文件。split 則是當 Region 達到閾值,會把過大的 Region。

hbase.hregion.memstore.flush.size:134217728  #128m

  這個參數的作用是當單個 HRegion 內所有的 Memstore 大小總和超過指定值時,flush該 HRegion 的所有 memstore。RegionServer 的 flush 是通過將請求添加一個隊列,模擬生產消費模型來非同步處理的。那這裡就有一個問題,當隊列來不及消費,產生大量積壓請求時,可能會導致記憶體陡增,最壞的情況是觸發 OOM。 

hbase.regionserver.global.memstore.upperLimit:0.4
hbase.regionserver.global.memstore.lowerLimit:0.38

  當 MemStore 使用記憶體總量達到hbase.regionserver.global.memstore.upperLimit 指定值時,將會有多個 MemStores flush 到文件中,MemStore flush 順序是按照大小降序執行的,直到刷新到 MemStore 使用記憶體略小於 lowerLimit

 

 

Tags: