HBase 入門筆記-數據落地篇
一、前言
關於數據落地方面,HBase官網也有相關介紹。本文主要介紹一下實際工作中涉及的數據存儲方面的一些經驗和技巧,主要涉及表rowkey設計、數據落地方案
二、表設計
相對於MySQL等關係型資料庫而言,HBase也有相應的類似庫和表的概念,其中MySQL的庫對應於HBase的NameSpace (0.95以上版本才支持), 表對應於HBase的表。對於NameSpace來說,HBase默認有兩類:default和hbase, default中存放的實際數據的表,hbase中存放的是系統內建表,如meta元數據表。
2.1 ROWKEY設計
HBase表在設計過程中,rowkey設計很關鍵,如果rowkey設計不好,可能會出現熱點、負載不均衡、數據冗餘等問題。常見的ROWKEY設計一般需要遵循幾個原則:
1) rowkey要惟一: 組成rowkey的欄位需要全局惟一,比如像支付訂單類的系統,一般存在交易單號,交易時間等,可以把這兩個欄位組合成rowkey, 這樣在scan數據時還可以按單號還時間來批量掃描數據以提高效率
2) 避免熱點問題: 在考慮惟一性之後,還需要考慮熱點問題,hbase是分散式存儲系統,數據存儲時按region維度進行管理,region會分配到各regionserver上,如果rowkey設計不好,會存在同一類型的數據會集中在某幾個region上,導致數據寫入和訪問時出現熱點現象,像這類問題很容易導致regionserver宕機現象,影響集群穩定性。像我們生產環境的下rowkey設計,還會考慮一個分桶規則,分桶的規則是比如將單號後三位作為分桶號,同時在建表時指定SPLITS參數,預拆分表的region。
a. 建表時怎麼指定region數呢,如下建表語句,即指定表預先分配3個分桶,這樣以001,002,003結尾單號的數據會存儲到001,002,003分桶中,同時這些分桶會被隨機分配各到各台regionserver。
create 『test『, {SPLITS =>[『001『, 『002『, 『003『]}
b. rowkey設計形式類似於如下:分桶號#交易時間#交易單號
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:00rowkey: 654321#2017-01-27 00:00:00value: 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『]}
三、數據落地方案
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以適應我們的業務場景。
四、總結
本文簡單的介紹了一下HBase表設計相關的經驗和數據落地方面的經驗,很多經驗都是在踩過坑之後才有的優化,還是那句話,沒有問題就沒有進步,希望後面少踩些坑。
推薦閱讀:
※《HBase實戰》第二章之數據模型問題集
※hdfs本身是不支持文件隨機插入數據。那麼hbase中隨機寫入記錄,在hdfs中是怎麼實現的呢?
※Hbase性能測試工具之YCSB
※HBase讀性能怎麼樣?
※hbase分散式集群搭建
TAG:HBase |