[平臺建設] HBase平臺建設實踐

chaplinthink發表於2021-12-27

背景

由於公司業務場景的需要,我們需要開發HBase平臺,主要需要以下功能:

  • 建表管理
  • 授權管理
  • SDK實現
  • 與公司內部系統打通

我們使用的HBase 版本:

HBase 1.2.0-cdh5.16.2

Hadoop: 2.6.0-cdh5.16.2

目前主要應用場景:

  • 實時計算如商品、商家等維度表
  • 去重邏輯
  • 中介軟體服務等監控資料
  • 使用者畫像

平臺建設

建表管理

1.指定名稱空間

HBase系統預設定義了兩個預設的namespace:

  • hbase:系統內建表,包括namespace和meta表
  • default:使用者建表時未指定namespace的表都建立在此

我們需要根據業務組進行定義名稱空間,方便維護管理

2.支援多叢集,不同業務組根據需要選擇相應叢集

3.指定表名

4.指定列族

因為列族在建立表的時候是確定的,列名以列族作為字首,按需可動態加入,如: cf:name, cf:age

cf 就是列族, name, age 就是列名

5.設定生存時間TTL

一旦達到過期時間,HBase將自動刪除行

6.支援預分割槽

HBase預設建表時有一個region,這個region的rowkey是沒有邊界的,即沒有startkey和endkey,在資料寫入時,所有資料都會寫入這個預設的region,隨著資料量的不斷增加,此region已經不能承受不斷增長的資料量,會進行split,分成2個region。在此過程中,會產生兩個問題:

  1. 資料往一個region上寫,會有寫熱點問題。
  2. region split會消耗寶貴的叢集I/O資源。

基於此可以控制在建表的時候,建立多個空region,並確定每個region的起始和終止rowkey,這樣只要我們的rowkey設計能均勻的命中各個region,就不會存在寫熱點問題。自然split的機率也會大大降低。當然隨著資料量的不斷增長,該split的還是要進行split。像這樣預先建立hbase表分割槽的方式,稱之為預分割槽.

預分割槽的實現,參考HBase的shell指令碼實現.

相關程式碼:

Configuration configuration = conn.getConfiguration();
RegionSplitter.SplitAlgorithm hexStringSplit = RegionSplitter.newSplitAlgoInstance(configuration, splitaLgo);
splits = hexStringSplit.split(numRegions);

指定分割演算法以及預分割槽的數目

分割演算法主要三種:

  • HexStringSplit: rowkey是十六進位制的字串作為字首的
  • DecimalStringSplit: rowkey是10進位制數字字串作為字首的
  • UniformSplit: rowkey字首完全隨機

其他配置:

   HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(cf);
   //指定版本,設定成一個即可
   hColumnDescriptor.setMaxVersions(1);
   //指定列族過期時間,介面配置最小單位天,HBase TTL時間單位為秒
   Long ttl = TimeUnit.DAYS.toSeconds(expireDays);
   hColumnDescriptor.setTimeToLive(ttl.intValue());
   //啟用壓縮演算法
   hColumnDescriptor.setCompressionType(Compression.Algorithm.SNAPPY);
   //進行compaction的時候使用壓縮演算法
   hColumnDescriptor.setCompactionCompressionType(Compression.Algorithm.SNAPPY);
   //讓資料塊快取在LRU快取裡面有更高的優先順序
   hColumnDescriptor.setInMemory(true);
   //bloom過濾器,過濾加速
   hColumnDescriptor.setBloomFilterType(BloomType.ROW);
   descriptor.addFamily(hColumnDescriptor);

最終呼叫 admin.createTable進行建表

建表的時候,注意要檢測名稱空間存在,不存在進行建立名稱空間,還有建表的時候自動給相應的業務組進行授權。

表結構檢視、資料預覽、表刪除等功能通過HBase java API 就可以實現, 這裡不介紹了.

授權管理

先說HBase如何實現鑑權?

我們採用HBase ACL 鑑權機制,具體配置如下:

<property>
      <name>hbase.superuser</name>
      <value>admin</value>
</property>
<property>
    <name>hbase.coprocessor.region.classes</name>    
    <value>org.apache.hadoop.hbase.security.access.AccessController</value> 
</property>
  <property>
    <name>hbase.coprocessor.master.classes</name>
    <value>org.apache.hadoop.hbase.security.access.AccessController</value>
  </property>
 <property>
      <name>hbase.security.authorization</name>
      <value>true</value>
  </property>

給其他業務組授權都採用超級賬戶進行

下面是許可權對照表:

TBvHoD.png

授權流程:

TDp6XR.png

使用者如何進行HBase操作以及平臺如何進行認證和鑑權?

我們開發了一個很簡單的SDK

SDK 實現

SDK 主要的功能就是進行認證和授權、以及獲取相關叢集的連線資訊的操作。

整體流程:

TDEAsg.png

與公司內部系統打通

主要工作就是開發平臺使用HBase任務如何打通認證鑑權等,因為都是基於業務組提交任務,所以很容易實現滿足需求

針對外部服務在容器內使用HBase, 在主機名沒有做DNS 正反向解析之前,需要在容器內配置hosts。

叢集資料遷移

主要場景是我們需要將老叢集的資料遷移到新叢集,要實現跨叢集遷移。

老叢集版本: HBase: 1.2.0-cdh5.12.0 Hadoop: 2.6.0-cdh5.12.0

新叢集版本: HBase: 1.2.0-cdh5.16.2 Hadoop: 2.6.0-cdh5.16.2

使用Distcp方案來進行,一般選擇業務低峰期去做, ,需要保證HBase叢集中的表是靜態資料,需要停止業務表的寫入

具體步驟

(1) 在新叢集中HDFS 使用者下執行distcp命令

在新叢集的NameNode節點執行命令

hadoop distcp -Dmapreduce.job.queue.name=default -pug -update -skipcrccheck -m 100 hdfs://ip:8020/hbase/data/aaa/user_test /hbase/data/aaa/user_test

(2) 執行HBase命令來修復HBase表的後設資料,如表名、表結構等內容,會重新註冊到新叢集的Zookeeper中。

sudo -u admin  hbase hbck -fixMeta  "aaa:user_test"

sudo -u admin hbase hbck -fixAssignments "aaa:user_test"

(3)驗證資料:

scan 'aaa:user_test' ,{LIMIT=>10}

(4) 舊叢集表刪除:

#!/bin/bash 
exec sudo -u admin  hbase shell <<EOF 
disable 'aaa:user_test'
drop 'aaa:user_test' 
EOF

為了遷移方便,可以將上述命令封裝成一個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

總結

本文主要對HBase平臺建設的實踐總結,主要包括建立HBase表相關屬性配置的實現,以及認證鑑權的多租戶設計思路介紹,同時對HBase跨叢集表元資訊及資料遷移實踐進行總結.

相關文章