1. 程式人生 > >Hbase的詳細介紹及底層原理

Hbase的詳細介紹及底層原理

一、hbase介紹

  1. hbase的產生背景:
    當資料量過於龐大的時候 資料的快速查詢是很難實現的
    GFS-------分散式儲存的
    MAPERREDUCE------分散式計算的
    BIGTABLE------分散式資料庫 快速查詢
  2. hbase是什麼?
    hbase是一個分散式的列式儲存資料庫 nosql的資料庫
    1)no sql hbase不支援標準sql 不支援sql語句的,基於hbase之上對外提供標準sql的元件 phoenix
    2)ont only sql
    列式儲存 :面向列的儲存
    存數的時候是以’列’為單位進行儲存的 假設hbase中儲存的資料 stuid,name,sex,age,department 每一個‘列’會單獨儲存一個物理檔案
    一行的資料會分割在多個檔案中儲存。 優點:
    mysql進行資料查詢的時候
    select id,name from stu; 減少資料查詢的時候的資料的掃描範圍 提示查詢效能 儲存的時候比較方便。
    mysql、oracle、sqlserver…傳統的關係型資料庫 面向行儲存的
    mysql:user----name,password,host 同一行的資料肯定在一個物理儲存檔案中,同一行資料是不會被拆分儲存的。
    hbase的設計思想
    面向列儲存 可以實現一個進實時的查詢一個分散式(儲存資料量的)資料庫。

1.HBase是什麼?
hbase是一種Nosql的分散式資料儲存系統。具有可靠性,高能性,列儲存,可伸縮的徵,可以對大型資料進行實時、隨機的讀寫訪問。

2.應用場景

  1. 需要儲存半結構化和非結構化資料時
  2. 記錄中含null
  3. 需要儲存變動歷史記錄的資料
  4. 資料量超大的資料

3.Hbase的注意事項:

  • 1.Hbase只能通過主鍵(rowkey)和主鍵的range來檢索資料
  • 2.不支援join
  • 3.不支援複雜的事務
  • 4.只能支援資料型別:byte[]陣列

4.HBase中表的特點

  • 1.大 :

  • 2.面向列:通過列進行檢索

  • 3.稀疏:空的(null)的資料所在的列,不佔儲存空間

  • 4.無模式:包含的列的個數可以不一致,也可以不確定,可以隨機指定

5.HBase表的結構(相當於四維表,row key 和family對應的資料是一個二維表(列和記錄))

  • 1)行鍵:就是用來訪問HBase中的行 ,相當於Sql中的主鍵。 Hbase會對錶中的資料按照行鍵進行排序(字典順序)。

  • 2)列簇:就是一組列的集合,在建表的時候指定

6、Hbase的叢集結構(主從架構)
在這裡插入圖片描述

region:是hbase對錶進行切割的單位。
hmaster:是hbase功能上的主節點,不是狀態的主節點,如果master宕機,增刪改不能用,查詢可以使用。在region進行切分的時候負責負載均衡
regionserver:hbase中真正負責管理region的伺服器。
zookeeper:負責叢集節點之間的上下線感知
HDFS:儲存hbase的表。


在這裡插入圖片描述

二、Hbase的API

1.基本套路

/**
	 * 這是hbase的java api的第一個程式碼
	 * @throws IOException 
	 * */
	
	public static void main(String[] args) throws IOException {
		/*
		 * 獲取一個配置物件
		 * 
		 * 要點:獲取配置資訊之後,就一定要告訴這個配置物件,說接下來要建立的連線是哪個hbase叢集的連線
		 * 
		 * */
		Configuration config = HBaseConfiguration.create();
		config.set("hbase.zookeeper.quorum", "qyl01:2181,qyl02:2181,qyl03:2181");
		/**
		 * 通過配置物件建立連線
		 * */
		Connection connection = ConnectionFactory.createConnection(config);
         /**
          * 通過連接獲取管理員物件
          * */
		Admin admin=connection.getAdmin();
		/**
 * 通過管理員物件就可以對錶進行各種操作
		 * */
		HTableDescriptor[] listTables = admin.listTables();
		/**
		 * 針對結果進行處理
		 * */
		for(HTableDescriptor list:listTables){
			System.out.println(list.getNameAsString());
		}
		connection.close();
	}

2.資料的匯入和匯出
1)hbase資料寫入hdfs形成一個結構化的二維表

思路:(用scan)
用TableMaprReduceUtill類的initTableMapperJob方法獲取habse表中的每一行的result(通過scan查詢),
將其結果作為Map中的value值,然後用Cell接收,通過CellUtil中的方法獲取每一行的rowkey和family等,寫入到hdfs中(整個過程不需要reduce的參與)

2)將hdfs上的資料轉成hbase(用put)

思路:map方法獲取表的資料
 reduce將表中的資料以表中的第一個欄位為rowkey,其餘欄位為列,寫入到一個hbase表特定的列簇中.

3)mysql 資料匯入到 hbase

jdbc:mysql://hadoop01/mytest
 --username root 
 --password root 
 --table student 
 --hbase-table studenttest1
  --column-family name 
  --hbase-row-key id

4)hbase 資料匯入到 mysql(沒有直接的命令)
可以把hbase的資料匯入到hdfs中,然後再匯入到mysql中。

5)HBase整合hive

create external table mingxing(rowkey string, base_info map<string, string>, extra_info 
map<string, string>) 

建立的欄位型別為map型別

select * from mingxing;
select rowkey,base_info['name'] from mingxing;
select rowkey,extra_info['province'] from mingxing;
select rowkey,base_info['name'], extra_info['province'] from mingxing;

三、HBase的底層原理

1、系統架構
在這裡插入圖片描述
1.HBase有兩張特殊的表:

  • .META:記錄使用者所有表拆分出來的Region對映的資訊,META可以有多個Region
    -ROOT-:記錄.META表的Region資訊, -ROOT-只有一個Region

各個元件的職責:
Client的職責:

  • client訪問使用者資料前需要先訪問Zookeeper,找到-ROOT-表的Region所在的位置後訪問-ROOT-表,接著訪問.MATE表,最後找到使用者資料的位置去訪問。

Zookeeper職責:

  • 1.為Hbase提供選舉機制,選舉Mster
    2.儲存定址入口(-ROOT-的位置)
    3.實時監控RegionServer的狀態,通過建立讀鎖
    4.儲存Hase的Schema,表,檢視等

Master的職責:

  • 1.為RegionServer分配Region
    2.負責RegionServe的負載均衡
    3.發現失效的RegionServer並重新分配其上的Region
    4.處理資料庫物件的更新請求

RegionServer職責:

  • 1.負責真正的讀寫請求
    2.負責和底層的檔案系統HDFS的互動,儲存資料到HDFS
    3.負責Store和HFile的合併工作

2、物理架構
在這裡插入圖片描述

  • 1、Table 中的所有行都按照 RowKsey 的字典序排列。
  • 2、Table 在行的方向上分割為多個 HRegion。
  • 3、HRegion 按大小分割的(預設 10G),每個表一開始只有一個 HRegion,隨著資料不插入表,HRegion 不斷增大,當增大到一個閥值的時候,HRegion 就會等分會兩個新的HRegion。當表中的行不斷增多,就會有越來越多的 HRegion。
  • 4、HRegion 是 Hbase 中分散式儲存和負載均衡的最小單元。最小單元就表示不同的 HRegion可以分佈在不同的 HRegionServer 上。但一個 HRegion 是不會拆分到多個 server 上的。
  • 5、HRegion 雖然是負載均衡的最小單元,但並不是物理儲存的最小單元。事實上,HRegion由一個或者多個 Store 組成,每個
    Store 儲存一個 Column Family。每個 Strore 又由一個MemStore 和 0 至多個 StoreFile 組成

StoreFile和Hfile結構
StoreFile 以 HFile 格式儲存在 HDFS 上,請看下圖 HFile 的資料組織格式:
在這裡插入圖片描述
HFile 分為六個部分:

  1. Data Block 段–儲存表中的資料,這部分可以被壓縮
  2. Meta Block 段 (可選的)–儲存使用者自定義的 kv 對,可以被壓縮。
  3. File Info 段–Hfile 的元資訊,不被壓縮,使用者也可以在這一部分新增自己的元資訊。
  4. Data Block Index 段–Data Block 的索引。每條索引的 key 是被索引的 block 的第一條記錄的 key。
  5. Meta Block Index 段 (可選的)–Meta Block 的索引。
  6. Trailer 段–這一段是定長的。儲存了每一段的偏移量,讀取一個 HFile 時,會首先讀取 Trailer,

Trailer儲存了每個段的起始位置(段的Magic Number用來做安全check),然後,DataBlockIndex會被讀取到記憶體中,這樣,當檢索某個 key 時,不需要掃描整個 HFile,而只需從記憶體中找到key所在的block,通過一次磁碟io將整個block讀取到記憶體中,再找到需要的key。DataBlockIndex 採用 LRU 機制淘汰。
HFile 的 Data Block,Meta Block 通常採用壓縮方式儲存,壓縮之後可以大大減少網路 IO 和磁碟 IO,隨之而來的開銷當然是需要花費 cpu 進行壓縮和解壓縮。
目標 Hfile 的壓縮支援兩種方式:Gzip,LZO。

3、定址機制
在這裡插入圖片描述
流程:

  • 第 1 步:Client 請求 ZooKeeper 獲取.META.所在的 RegionServer 的地址。
  • 第 2 步:Client 請求.META.所在的 RegionServer 獲取訪問資料所在的 RegionServer
    地址,Client會將.META.的相關資訊 cache 下來,以便下一次快速訪問。
  • 第 3 步:Client 請求資料所在的 RegionServer,獲取所需要的資料。

四、HBase高階應用

.1、建表高階屬性
下面幾個 shell 命令在 HBase 操作中可以起到很到的作用,且主要體現在建表的過程中,看
下面幾個 create 屬性
1、 BLOOMFILTER(布隆過濾器)

  • 預設是 NONE 是否使用布隆過慮及使用何種方式,布隆過濾可以每列族單獨啟用 使用
    HColumnDescriptor.setBloomFilterType(NONE | ROW | ROWCOL)
    對列族單獨啟用布隆Default = ROW 對行進行布隆過濾 對 ROW,行鍵的雜湊在每次插入行時將被新增到布隆 對 ROWCOL,行鍵 列族 + 列族修飾的雜湊將在每次插入行時新增到布隆 使用方法: create ‘table’,{NAME => ‘baseinfo’ BLOOMFILTER => ‘ROW’} 作用:用布隆過濾可以節省讀磁碟過程,可以有助於降低讀取延遲

2、 VERSIONS(版本號)

  • 預設是 1 這個引數的意思是資料保留 1 個 版本,如果我們認為我們的資料沒有這麼大
    的必要保留這麼多,隨時都在更新,而老版本的資料對我們毫無價值,那將此引數設為 1能 節約 2/3 的空間
    使用方法: create ‘table’,{ NAME => ‘baseinfo’ VERSIONS=>‘2’}

3、 COMPRESSION(壓縮)
預設不使用壓縮,建議採用SNAPP壓縮演算法
設定:create ‘table’,{NAME=>‘info’,COMPRESSION=>‘SNAPPY’}
在這裡插入圖片描述

2、表設計
1、列簇設計
追求的原則是:在合理範圍內能儘量少的減少列簇就儘量減少列簇。
最優設計是:將所有相關性很強的 key-value 都放在同一個列簇下,這樣既能做到查詢效率最高,也能保持儘可能少的訪問不同的磁碟檔案

2、RowKey 設計
HBase 中,表會被劃分為 1…n 個 Region,被託管在 RegionServer 中。Region 二個重要的
屬性:StartKey 與 EndKey 表示這個 Region 維護的 rowKey 範圍,當我們要讀/寫資料時,如果 rowKey 落在某個 start-end key 範圍內,那麼就會定位到目標 region 並且讀/寫到相關的資料

RowKey設計的三原則
一、 rowkey 長度原則

  • Rowkey 是一個二進位制碼流,Rowkey 的長度被很多開發者建議說設計在 10~100 個位元組,不過建議是越短越好,不要超過 16
    個位元組。

原因如下:

  • 1、資料的持久化檔案 HFile 中是按照 KeyValue 儲存的,如果 Rowkey 過長比如 100 個字 節,1000 萬列資料光
    Rowkey 就要佔用 100*1000 萬=10 億個位元組,將近 1G 資料,這會極大影響 HFile 的儲存效率;
  • 2、MemStore 將快取部分資料到記憶體,如果 Rowkey 欄位過長記憶體的有效利用率會降低,
    系統將無法快取更多的資料,這會降低檢索效率。因此 Rowkey 的位元組長度越短越好。
  • 3、目前作業系統是都是 64 位系統,記憶體 8 位元組對齊。控制在 16 個位元組,8 位元組的整數 倍利用作業系統的最佳特性。

二、rowkey 雜湊原則

  • 如果 Rowkey 是按時間戳的方式遞增,不要將時間放在二進位制碼的前面,建議將 Rowkey 的高位作為雜湊欄位,由程式迴圈生成,低位放時間欄位,這樣將提高資料均衡分佈在每個 Regionserver 實現負載均衡的機率。如果沒有雜湊欄位,首欄位直接是時間資訊將產生所有 新資料都在一個 RegionServer
    上堆積的熱點現象,這樣在做資料檢索的時候負載將會集中 在個別 RegionServer,降低查詢效率。

三、 rowkey 唯一原則

  • 必須在設計上保證其唯一性。rowkey 是按照字典順序排序儲存的,因此,設計 rowkey
    的時候,要充分利用這個排序的特點,將經常讀取的資料儲存到一塊,將最近可能會被訪問的資料放到一塊。