Hbase入門(四)——表結構設計-RowKey
- 2019 年 10 月 8 日
- 筆記
Hbase的表結構設計與關係型資料庫有很多不同,主要是Hbase有Rowkey和列族、timestamp這幾個全新的概念,如何設計表結構就非常的重要。
創建
Hbase就是通過 表 Rowkey 列族 timestamp確定一行數據。
這與關係型資料庫完全不同:
屬性 | HBase | RDBMS |
---|---|---|
數據類型 | 只有字元串 | 豐富的數據類型 |
數據操作 | 簡單的增刪改查 不支援join | 各種函數和表連接 |
存儲模式 | 基於列式存儲 | 基於表格結構和行式存儲 |
數據保護 | 更新後仍然保留舊版本 | 替換 |
可伸縮性 | 輕易的增加節點,兼容性高 | 需要中間層,犧牲功能 |
所以Hbase需要考慮的因素有:
1、這個表應該有多少列族
2、列族使用什麼數據
3、每個列族有多少列
4、列名是什麼
5、單元應該存放什麼數據
6、每個單元存儲多少時間版本
7、Rowkey結構是什麼,應該包含什麼資訊
需要注意的點:
1、Join
Hbase中沒有join 所以需要大表結構 行記錄加關鍵字 解決這個問題
2、Rowkey
Rowkey設計非常重要 由於Hbase是有序的 需要考慮前綴後綴問題
可以通過Hbase Shell和 Java Api創建:
Configuration config = HBaseConfiguration.create(); Admin admin = new Admin(conf); TableName table = TableName.valueOf("myTable"); admin.disableTable(table); HColumnDescriptor cf1 = ...; admin.addColumn(table, cf1); // adding new ColumnFamily HColumnDescriptor cf2 = ...; admin.modifyColumn(table, cf2); // modifying existing ColumnFamily admin.enableTable(table);
Rowkey設計
Rowkey是不可分割的位元組數組,按字典序存儲在表中。
由於:Region基於Rowkey為一個區間的行提供服務 HFile在硬碟上存儲有序的行 所以Rowkey就極大的影響了Hbase的性能。
Rowkey就是索引,如果不清楚Rowkey就只能掃描全表,那麼性能將會大幅度下降。
這裡用影片熱度排行榜舉例:
1、Rowkey是以字典序從大到小
原生Hbase只支援從小到大排序,要想實現從大到小,可以採用 Rowkey=Integer.MAX_VALUE-Rowkey的方式,在應用層再轉回來完成需求。
2、Rowkey盡量散列
Rowkey要盡量散列,這樣可以保證數據不在一個Region上,從而避免了讀寫的集中。
比如我們可以設計 userid_videoid 拼接字元串 這樣的話user就會不均勻。
有三種辦法解決: 反轉userid 散列userid 將userid取模後進行MD5加密 取前6位加入userid中
3、Rowkey長度要盡量短
Rowkey過長,存儲開銷會大。
Rowkey過長,會導致記憶體的利用率降低,進而降低索引命中率。
列族
列族是一些列的集合,一個列族所有成員都有同樣的前綴,比如courses:history 和 courses:math都是courses列族的成員。冒號是分隔符。列族前綴必須是可輸出字元,列可由任意位元組數組組成。
列族必須在表建立的時候聲明,列則不需要特別聲明,用戶隨時可以創建新列。
經驗法則:
- 目標是把 region 的大小限制在 10 到 50 GB 之間。
- 目標是限制 cell 的大小在 10 MB 之內,如果使用的是 mob類型,限制在 50 MB 之內。否則,考慮把 cell 的數據存儲在 HDFS 中,並在 HBase 中存儲指向該數據的指針。
- 典型的 scheme 每張表包含 1 到 3 個列族。HBase 表設計不應當和 RDBMS 表設計類似。
- 對於擁有 1 或 2 個列族的表來說,50-100 個 region 是比較合適的。請記住, region 是列族的連續段。
- 保持列族名稱儘可能短。每個值都會存儲列族的名稱(忽略前綴編碼)。它們不應該像典型 RDBMS 那樣,是自文檔化,描述性的名稱。
- 如果你正在存儲基於時間的機器數據或者日誌資訊,並且 row key 是基於設備 ID 或者服務 ID + 時間,最終會出現這樣一種情況,即更舊的數據 region 永遠不會有額外寫入。在這種情況下,最終會存在少量的活動 region 和大量不會再有新寫入的 region。對於這種情況,可以接受更多的 region 數量,因為資源的消耗只取決於活動 region。
- 如果只有一個列族會頻繁寫,那麼只讓這個列族佔用記憶體。當分配資源的時候注意寫入模式。
實例
店鋪與商品
店鋪shop 商品 item 是多對多的關係
RDBMS表結構設計:
商鋪表:
列名 | 列含義 |
---|---|
id | 主鍵 |
name | 店鋪名稱 |
address | 所在地 |
regdate | 註冊日期 |
商品表:
列名 | 列含義 |
---|---|
id | 主鍵 |
name | 商品名稱 |
price | 價格 |
details | 商品詳情 |
title | 展示名稱 |
關係表:
列名 | 列含義 |
---|---|
shop_id | 店鋪主鍵 |
item_id | 商品主鍵 |
type | 關聯類型 |
Hbase表結構設計:
店鋪表:
商品表:
微博用戶與粉絲
用戶與粉絲是一對多
RDBMS表結構設計:
用戶表:
列名 | 列含義 |
---|---|
id | 主鍵 |
nickname | 用戶名 |
粉絲對應表:
列名 | 列含義 |
---|---|
user_id | 用戶id |
fans_id | 粉絲id |
Hbase表結構設計:
更多實時計算,Hbase,Flink,Kafka等相關技術博文,歡迎關注實時流式計算