一篇文章讀懂HBase,從安裝/架構/API全部剖析(圖文並茂)--未完待續

又是一週,這次給自己複習一下Hbase,算是寫的比較詳細的,當然比較晚了,還沒寫完,這兩天一定抽時間把它補完。
接下來進入正題:

1、Hbase的介紹

之前我們熟悉的數據庫,比如Mysql,屬於是關係型數據庫,但是它的單機單表的數據量還是有限,在700—1000萬條(網查的),但是在大數據框架中,這點數據量還是捉襟見肘,所以採用NOSQL數據庫

關係型數據庫:例如mysql、 Oracle
非關係型數據庫:HBase

注意:Hbase讀比寫慢,詳情請看Hbase的讀與寫流程

2、Hbase的安裝與配置

首先需要知道:Hbase的存儲是基於HDFS的,並且Hbase的元數據信息也存儲在Zookeeper中,所以zk與hadoop需要能夠正常啓動。

2.1 Zookeeper與Hadoop正常部署

zookeeper集羣的啓動:zk.sh start

Hadoop集羣的正常部署並啓動:hdfs.sh start

幫助提示:

zk的啓動命令:bin/zkServer.sh start

hdfs服務的啓動:sbin/start-dfs.sh

yarn啓動:sbin/start-yarn.sh

2.2 HBase的解壓

解壓Hbase到指定目錄:tar -zxvf hbase-1.3.1-bin.tar.gz -C /usr/local/

Hbase-1.3.1的安裝包:

2.3 HBase的配置文件

修改HBase對應的配置文件,位置:hbase的conf目錄下:

1)hbase-env.sh修改內容(配置環境變量):

export JAVA_HOME=/usr/local/opt/jdk1.8.0_144
export HBASE_MANAGES_ZK=false

這是因爲Hbase裏面有一個內置的zookeeper,所以我們在這裏關閉,使用我們自己的zookeeper集羣

2)hbase-site.xml添加以下內容:

<configuration>
<!-- 配置Hbase的數據存儲地址--><property><name>hbase.rootdir</name><value>hdfs://master102:9000/HBase</value></property>

    <!-- 配置Hbase的集羣分佈式爲true --><property><name>hbase.cluster.distributed</name><value>true</value></property>

  <!-- 0.98後的新變動,之前版本沒有.port,默認端口爲60000 --><property><name>hbase.master.port</name><value>16000</value></property>

    <!-- 配置zookeeper的集羣 --><property><name>hbase.zookeeper.quorum</name><value>master102,slaver103,slaver104</value></property>

    <!-- 配置Hbase在zookeeper中存儲數據的目錄(存儲元數據信息) --><property><name>hbase.zookeeper.property.dataDir</name><value>/usr/local/zookeeper-3.4.10/zkData</value></property>

</configuration>

3)regionservers(配置hbase集羣的節點):

master102
slaver103
slaver104

4)軟連接hadoop配置文件到HBase:

ln -s /usr/local/hadoop-2.7.2/etc/hadoop/core-site.xml /usr/local/hbase/conf/core-site.xml

 ln -s /usr/local/hadoop-2.7.2/etc/hadoop/hdfs-site.xml /usr/local/hbase/conf/hdfs-site.xml

2.4 HBase遠程發送到其他集羣

[later@master module]$ xsync hbase/

同步服務請參考:

2.5 Hbase服務的啓動

1.啓動方式

[later@master hbase]$ bin/hbase-daemon.sh start master
[later@master hbase]$ bin/hbase-daemon.sh start regionserver

2.啓動方式2

[later@master hbase]$ bin/start-hbase.sh

停止服務:

[later@master hbase]$ bin/stop-hbase.sh

特別注意:如果集羣之間的節點時間不同步,會導致regionserver無法啓動,拋出ClockOutOfSyncException異常。集羣時間同步請參考:

2.6 查看Hbase頁面

http://master102:16010

2.7 HBase Shell基本測試

1.進入HBase客戶端命令行

[later@master hbase]$ bin/hbase shell

2.查看幫助命令

hbase(main):001:0> help

3.查看當前數據庫中有哪些表

hbase(main):002:0> list

1.創建表

hbase(main):002:0> create ‘student’,‘info’

2.插入數據到表

hbase(main):003:0> put ‘student’,‘1001’,‘info:sex’,‘male’

hbase(main):004:0> put ‘student’,‘1001’,‘info:age’,‘18’

hbase(main):005:0> put ‘student’,‘1002’,‘info:name’,‘Janna’

hbase(main):006:0> put ‘student’,‘1002’,‘info:sex’,‘female’

hbase(main):007:0> put ‘student’,‘1002’,‘info:age’,‘20’

3.掃描查看錶數據

hbase(main):008:0> scan ‘student’

hbase(main):009:0> scan ‘student’,{STARTROW => ‘1001’, STOPROW => ‘1001’}

hbase(main):010:0> scan ‘student’,{STARTROW => ‘1001’}

4.查看錶結構

hbase(main):011:0> describe ‘student’

5.更新指定字段的數據

hbase(main):012:0> put ‘student’,‘1001’,‘info:name’,‘Nick’

hbase(main):013:0> put ‘student’,‘1001’,‘info:age’,‘100’

6.查看“指定行”或“指定列族:列”的數據

hbase(main):014:0> get ‘student’,‘1001’

hbase(main):015:0> get ‘student’,‘1001’,‘info:name’

7.統計表數據行數

hbase(main):021:0> count ‘student’

8.刪除數據

刪除某rowkey的全部數據:

hbase(main):016:0> deleteall ‘student’,‘1001’

刪除某rowkey的某一列數據:

hbase(main):017:0> delete ‘student’,‘1002’,‘info:sex’

9.清空表數據

hbase(main):018:0> truncate ‘student’

提示:清空表的操作順序爲先disable,然後再truncate。

10.刪除表

首先需要先讓該表爲disable狀態:

hbase(main):019:0> disable ‘student’

然後才能drop這個表:

hbase(main):020:0> drop ‘student’

提示:如果直接drop表,會報錯:ERROR: Table student is enabled. Disable it first.

11.變更表信息

將info列族中的數據存放3個版本:

hbase(main):022:0> alter ‘student’,{NAME=>‘info’,VERSIONS=>3}

hbase(main):022:0> get ‘student’,‘1001’,{COLUMN=>‘info:name’,VERSIONS=>3}

3、Hbase的架構

3.1 邏輯結構

在這裏插入圖片描述
上圖是用常見的二維表格在hbase中存儲的邏輯結構

每一行的數據是按照rowKey來查找的,其中,因爲該表可能列多,行多,所以我們

把多個列按照列族來管理,一個列族中包括多個列

把多個行按照Region來管理,一個Region中包括多行數據

把一個Region中的一個列族的數據叫做Store

3.2 物理存儲結構

上面說的是邏輯結構,那麼它實際上是如何存儲數據的

注意:在Hbase中增刪改數據,都會增加數據。只不過是type的不同
在這裏插入圖片描述
上圖體現的是一行數據是怎麼在Hbase中進行存儲的

在關係庫中,一個人的各種信息數據是以一行數據進行存儲的,但在Hbase中並不是按照一行來存儲的。而是把每個列的值都存爲1行,關鍵信息爲RowKey,列族信息,列名,時間戳,操作類型(添加這條數據時是刪除還是添加還是修改),值

  • ROW:HBase表中的每行數據都由一個RowKey和多個Column(列)組成,數據是按照RowKey的字典順序存儲的,並且查詢數據時只能根據RowKey進行檢索,所以RowKey的設計十分重要。

  • Column:HBase中的每個列都由Column Family(列族)和Column Qualifier(列限定符)進行限定,例如info:name,info:age。建表時,只需指明列族,而列限定符無需預先定義。

  • Time Stamp:用於標識數據的不同版本(version),每條數據寫入時,如果不指定時間戳,系統會自動爲其加上該字段,其值爲寫入HBase的時間。

  • Cell:由{rowkey, column Family:column Qualifier, time Stamp} 唯一確定的單元。

    cell中的數據是沒有類型的,全部是字節碼形式存貯。

  • Name Space:命名空間,類似於關係型數據庫的DatabBase概念,每個命名空間下有多個表。HBase有兩個自帶的命名空間,分別是“hbase”和“default”,“hbase”中存放的是HBase內置的表,“default”表是用戶默認使用的命名空間。

  • Region:表的切片。類似於關係型數據庫的表概念。不同的是,HBase定義表時只需要聲明列族即可,不需要聲明具體的列。這意味着,往HBase寫入數據時,字段可以動態、按需指定。因此,和關係型數據庫相比,HBase能夠輕鬆應對字段變更的場景。

3.3 架構原理

在這裏插入圖片描述
首先數據的存儲依賴於HDFS,爲HBase提供最終的底層數據存儲服務,同時爲HBase提供高可用的支持。

在Hbase的框架中,HMaster依賴於ZK,HMaster的作用管理數據的元數據(Hbase有一個meta表),類似於Hadoop中的NameNode

這裏假設:Hbase集羣有2個節點進行數據存儲

  • 每個節點都會有個進程HRegion Server,由Master進行管理,負載均衡。

  • 而HRegion Server爲Region的管理者,也就是其中包含着多個Region

  • Region是表的切片,所以Region中又有多個Store(列族的切片),也就是說同一個Region中的不同的Store來自於不同的列族

  • 在每個Store中,數據的存儲又依賴於內存區域:Mem Store,當內存達到一定的條件,就會刷寫到磁盤(刷寫機制見3.6),多次刷寫後就有了多個Store File,刷寫到磁盤的文件格式爲HFile

  • 考慮到多個刷寫出來的文件較多,所以進行合併,當合並後的文件過大的時候(默認達到10G切分),不便於查找,按照midRowKey將進行切分。

  • 最後Store File真正的存儲還是要依賴於HDFS,其中還有Hlog也存儲在HDFS(Hlog爲預寫入日誌,及時落盤,用於HBase恢復數據)

  • HMaster和HDFS進行通信,來向HMaster彙報存儲數據的元數據

術語解釋:

1)Region Server

Region Server爲Region的管理者,其實現類爲HRegionServer,主要作用如下:

對於數據的操作:get, put, delete;

對於Region的操作:splitRegion、compactRegion。

2)Master

Master是所有Region Server的管理者,其實現類爲HMaster,主要作用如下:

​ 對於表的操作:create, delete, alter

對於RegionServer的操作:分配regions到每個RegionServer,監控每個RegionServer的狀態,負載均衡和故障轉移。

3)Zookeeper

HBase通過Zookeeper來做Master的高可用、RegionServer的監控、元數據的入口以及集羣配置的維護等工作。

3.4 Hbase的寫流程

在這裏插入圖片描述

1)客戶端Client先訪問zookeeper,獲取hbase:meta表位於哪個RegionServer。

2)客戶端繼續訪問對應的RegionServer,獲取hbase:meta表,根據讀請求的namespace:table/rowkey,查詢出要寫入的目標數據位於哪個RegionServer中的哪個Region中。並將該table的region信息以及meta表的位置信息緩存在客戶端的meta cache(LRUcache方法,最近最常使用),方便下次訪問。

3)客戶端Client與目標RegionServer建立連接;

4)將數據順序寫入(追加)到WAL(也就是Hlog);

5)將數據寫入對應的MemStore,數據會在MemStore進行排序;

6)向客戶端發送ack;這個時候及時數據沒有落盤,用戶也可以查到。假如這個時候機器掛掉了,WAL也能幫助恢復

7)等達到MemStore的刷寫時機後,將數據刷寫到HFile。

3.5 讀流程

數據的讀操作與HMaster沒有關係
在這裏插入圖片描述

1)1-3步通寫流程

4)分別在Block Cache(讀緩存),MemStore和Store File(HFile)中查詢目標數據,並將查到的所有數據進行合併。此處所有數據是指同一條數據的不同版本(time stamp)或者不同的類型(Put/Delete)。

這裏的查詢過程:

先要同時讀取Block Cache(讀緩存)和MemStore,再檢索新落盤的文件,其中Block Cache緩存的是上一次落盤的文件

比如:同一個RowKey先寫入(張三,時間戳爲78),查找後緩存到Block Cache,過了幾個小時,它已經落盤爲文件,後寫入(李四,時間戳爲89),也落盤爲文件了,但沒進行查找,最後又寫入(王五,時間戳爲66),還在內存中

這個時候如果我們查找,理論上需要返回的是時間戳大的李四

查找過程:檢索內存,時間戳爲66,Block Cache緩存的是時間戳爲78的張三,而李四屬於是新落盤的文件,所以這個時候必須內存、緩存和文件都進行讀取,才能返回結果。

5) 將從文件中查詢到的數據塊(Block,HFile數據存儲單元,默認大小爲64KB)緩存到Block Cache。

6)將合併後的最終結果返回給客戶端

3.6 刷寫機制

1.當單個Region中的memstroe的總大小達到了(默認值128M),其所在region的所有memstore都會刷寫。

參數:hbase.hregion.memstore.flush.size(默認值128M)

2.當Region Server中memstore的總大小達到JVM堆內存的0.4時,region會按照其所有memstore的大小順序(由大到小)依次進行刷寫。這個時候會阻塞客戶端的寫操作,直到當前內存的數據量小於堆內存的0.4*0.95,也就是堆內存的0.38時,纔會打開寫操作。

原因:只有當一直髮生寫操作,memstore的總大小達到JVM堆內存的0.4,那麼這個時候開始了刷寫,但如果說開始刷寫後數據量還能達到JVM堆內存的0.38時,說明寫數據的速度比刷寫的速度快,如果不阻塞寫操作,容易把內存爆了,發生OOM。

參數:java**_**heapsize * hbase.regionserver.global.memstore.size(默認值0.4)

hbase.regionserver.global.memstore.size.lower.limit**(默認值0.95)

3.單個MemStore到達自動刷寫的時間(默認1小時,距離最後操作時間1小時),也會觸發memstore flush。

參數:hbase.regionserver.optionalcacheflushinterval(默認1小時)。

4.當WAL(也就是Hlog)文件的數量超過(默認值32),region會按照時間順序依次進行刷寫,直到WAL文件數量減小到hbase.regionserver.max.log以下(該屬性名已經廢棄,現無需手動設置,最大值爲32)。

3.7 StoreFile合併

在這裏插入圖片描述
由於memstore每次刷寫都會生成一個新的HFile,且同一個字段的不同版本(timestamp)和不同類型(Put/Delete)有可能會分佈在不同的HFile中,因此查詢時需要遍歷所有的HFile。爲了減少HFile的個數,以及清理掉過期和刪除的數據,會進行StoreFile Compaction。Compaction分爲兩種:

  • Minor Compaction:會將臨近的若干個較小的HFile合併成一個較大的HFile,但不會清理過期和刪除的數據,可能原來有10個文件,合併完後還有3個。
  • Major Compaction:會將一個Store下的所有的HFile合併成一個大HFile,並且會清理掉過期和刪除的數據。合併完後一定是隻有1個文件。(默認爲當一個Store下達到3個文件就會觸發合併,當一個Store下文件數達到10時就會暫緩刷寫,因爲這個時候刷寫的速度大於合併的速度)

3.7 Region Split

在這裏插入圖片描述

默認情況下,每個Table起初只有一個Region,隨着數據的不斷寫入,Region會自動進行拆分。剛拆分時,兩個子Region都位於當前的Region Server,但處於負載均衡的考慮,HMaster有可能會將某個Region轉移給其他的Region Server。

Region Split時機:

1.當1個region中的某個Store下所有StoreFile的總大小超過hbase.hregion.max.filesize(默認爲10G),該Region就會進行拆分(0.94版本之前)。

2.當1個region中的某個Store下所有StoreFile的總大小超過

Min(R^2 * “hbase.hregion.memstore.flush.size”,hbase.hregion.max.filesize"),該Region就會進行拆分,其中R爲當前Region Server中屬於該Table的個數(0.94版本之後)

4、Hbase的API

未完待續。。。

5、Hbase的優化

未完待續。。。

好了,關於Hbase的基本介紹就到這裏了,知識水平、經驗有限,可能有些細節沒講明白,歡迎大家指正。歡迎大家點贊、轉發、評論哈。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章