背景
由於公司業務場景的需要,我們需要開發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。在此過程中,會產生兩個問題:
- 資料往一個region上寫,會有寫熱點問題。
- 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>
給其他業務組授權都採用超級賬戶進行
下面是許可權對照表:
授權流程:
使用者如何進行HBase操作以及平臺如何進行認證和鑑權?
我們開發了一個很簡單的SDK
SDK 實現
SDK 主要的功能就是進行認證和授權、以及獲取相關叢集的連線資訊的操作。
整體流程:
與公司內部系統打通
主要工作就是開發平臺使用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跨叢集表元資訊及資料遷移實踐進行總結.