1、前言算法
關於數據落地方面,HBase官網也有相關介紹。本文主要介紹一下實際工做中涉及的數據存儲方面的一些經驗和技巧,主要涉及表rowkey設計、數據落地方案數據庫
2、表設計apache
相對於MySQL等關係型數據庫而言,HBase也有相應的相似庫和表的概念,其中MySQL的庫對應於HBase的NameSpace (0.95以上版本才支持), 表對應於HBase的表。對於NameSpace來講,HBase默認有兩類:default和hbase, default中存放的實際數據的表,hbase中存放的是系統內建表,如meta元數據表。bash
2.1 ROWKEY設計架構
HBase表在設計過程當中,rowkey設計很關鍵,若是rowkey設計很差,可能會出現熱點、負載不均衡、數據冗餘等問題。常見的ROWKEY設計通常須要遵循幾個原則:app
1) rowkey要唯一: 組成rowkey的字段須要全局唯一,好比像支付訂單類的系統,通常存在交易單號,交易時間等,能夠把這兩個字段組合成rowkey, 這樣在scan數據時還能夠按單號還時間來批量掃描數據以提升效率分佈式
2) 避免熱點問題: 在考慮唯一性以後,還須要考慮熱點問題,hbase是分佈式存儲系統,數據存儲時按region維度進行管理,region會分配到各regionserver上,若是rowkey設計很差,會存在同一類型的數據會集中在某幾個region上,致使數據寫入和訪問時出現熱點現象,像這類問題很容易致使regionserver宕機現象,影響集羣穩定性。像咱們生產環境的下rowkey設計,還會考慮一個分桶規則,分桶的規則是好比將單號後三位做爲分桶號,同時在建表時指定SPLITS參數,預拆分表的region。oop
a. 建表時怎麼指定region數呢,以下建表語句,即指定表預先分配3個分桶,這樣以001,002,003結尾單號的數據會存儲到001,002,003分桶中,同時這些分桶會被隨機分配各到各臺regionserver。優化
create 'test', {SPLITS =>['001', '002', '003']}
b. rowkey設計形式相似於以下:分桶號#交易時間#交易單號 spa
000#2017-01-27 00:00:00#11111111000
3)業務需求:通常業務在查詢hbase數據時,會要求你的數據必須能實現多維度查詢和按時間段,用戶ID進行批量提取數據等。對於多維度查詢方面,hbase因不支持二級索引,致使實現這類多維度查詢有很大難度,在咱們集羣中,用了一個折中方案,就是將索引字段獨立出來建一個單獨的索引表,索引表的KEY值 爲索引字段加時間組合成rowkey, 索引表的value值爲數據表的rowkey值, 這樣經過索引字段先掃描索引表,獲得數據表的rowkey後,再掃主表,獲得具體的交易數據。這樣就間接實現相似二級索引功能。具體設計以下:
索引表設計: 索引表的rowkey主要是將單號和交易時間組合,同時爲避免單號存在熱點問題,將單號反轉後處理,以下面rowkey:
#單號:123456,交易時間:2017-01-27 00:00:00 rowkey: 654321#2017-01-27 00:00:00
value: 456#2017-01-27 00:00:00#123456
2.2 表設計
hbase表在設計時,須要評估業務表數據量的大小,像咱們的業務數據單表可能日均數據量能達到20億級別,若是在設計時只設計單表的話,那後續在數據維護、業務使用時將會碰到很大的麻煩,因此咱們考慮的是將同一類業務表,設計成按月分表,設計成按月分表的話,對某個月的表的操做能夠不影響其它月份的表,儘可能減小受影響的數據範圍,同時操做月表,數據也易遷移,使集羣受影響的程度儘可能減小。上面介紹到分桶的概念,對於按月分的表,根據數據量的大小,預先規劃region的數量,會使數據儘可能分佈均衡。
表設計時,還須要考慮列簇數量,列族的話不宜過多,1-3個爲好,越多列族相互之間受影響也越大,同時影響集羣數據穩定性。考慮到咱們生產環境的業務數據是從MySQL表過來的數據,因此只設計了一個列族,方便操做管理。表在建立時,會帶一些參數來優化數據存儲,以下所示, 會帶上hfile文件的最大size, region拆分規則,列族名,BloomFilter模式爲ROW模式,壓縮算法爲snappy, 塊大小,blockcache等。
create 'test', {METHOD => 'table_att', MAX_FILESIZE => '549755813888', METADATA => {'SPLIT_POLICY' => 'org.apache.hadoop.hbase.regionserver.DisabledRegionSplitPolicy'}}, {NAME => 'cf', DATA_BLOCK_ENCODING => 'DIFF', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'SNAPPY', MIN_VERSIONS => '0', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}, {SPLITS =>['001','002','003']}
3、數據落地方案
HBASE數據場景不少,業務產生的數據如何入到Hbase呢,對於實時數據而言,通常會用到一些組件,如kafaka, storm, spark等, 經過採集Agent將業務數據進行清洗,將數據規範成指定格式的消息記錄,而後寫入到Kafaka, 進行數據分發,再經過storm集羣進行數據消費到hbase, 這種模式也是業界很常見的模式。對於咱們的集羣,因爲業務數據過於龐大,業務對數據時效性也很高,因此數據通常先入MySQL, 經過binlog採集解析入到消息隊列再通過Storm集羣進行消費入hbase。這種架構的話,對於採集要求很高,不能有數據丟失,業界關於binlog實時採集國內比較有名的就是淘寶的canal組件,該組件能夠高效穩定採集業務DB的數據,並實時記錄binlog採集位置,一旦採集Agent機器故障,支持將任務切換到其它機器繼續採集,對於業務DB若是出現故障,能夠及時告警發現異常。通過canal清洗的數據進入到kafaka,kafaka的優勢我就不介紹了,網上不少資料介紹,Kafaka的數據再通過storm程序批量同步到HBase,實現實時數據入HBase這一方案。
因數據分析,業務查詢須要,需將存儲在MySQL的歷史數據也同步到HBase,但因歷史數據已無binlog, 因此須要考慮其它方案將數據同步到HBase, 對於這種場景,通常是用bulkload將數據同步到Hbase,咱們也是用bulkload,由於原生的bulkload使用仍是用些問題,沒法適應業務數據表和索引表的導入,因此本身部門專門定製了bulkload以適應咱們的業務場景。
4、總結
本文簡單的介紹了一下HBase表設計相關的經驗和數據落地方面的經驗,不少經驗都是在踩過坑以後纔有的優化,仍是那句話,沒有問題就沒有進步,但願後面少踩些坑。