[平台建設] HBase平台建設實踐
背景
由於公司業務場景的需要,我們需要開發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 hbase hbase hbck -fixMeta "aaa:user_test"
sudo -u hbase 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跨集群表元資訊及數據遷移實踐進行總結.