HBase存儲及讀寫原理介紹

一、HBase介紹及其特點

        HBase是一個開源的非關係型分佈式數據庫,它參考了谷歌的BigTable建模,實現的編程語言爲Java。它是Apache軟件基金會的Hadoop項目的一部分,運行於HDFS文件系統之上,爲 Hadoop 提供類似於BigTable 規模的服務。因此,它可以容錯地存儲海量稀疏的數據。

        HBase是一個高可靠、高性能、面向列、可伸縮的分佈式數據庫,是谷歌BigTable的開源實現,主要用來存儲非結構化和半結構化的鬆散數據。HBase的目標是處理非常龐大的表,可以通過水平擴展的方式,利用廉價計算機集羣處理由超過10億行數據和數百萬列元素組成的數據表。

        Hadoop HDFS 是無法處理高速隨機寫入和讀取,也無法在不重寫文件的情況下對文件進行修改。HBase 正好解決了 HDFS 的缺點,因爲它使用優化的方式快速隨機寫入和讀取。此外,隨着數據呈指數增長,關係數據庫無法提供更好性能去處理海量的數據。HBase提供可擴展性和分區,以實現高效的存儲和檢索。

 

1.1、海量存儲

       Hbase適合存儲PB級別的海量數據,在PB級別的數據以及採用廉價PC存儲的情況下,能在幾十到百毫秒內返回數據。這與Hbase的極易擴展性息息相關。正式因爲Hbase良好的擴展性,才爲海量數據的存儲提供了便利。

1.2、列式存儲

       這裏的列式存儲其實說的是列族存儲,Hbase是根據列族來存儲數據的。列族下面可以有非常多的列,列族在創建表的時候就必須指定。

1.3、極易擴展

       Hbase的擴展性主要體現在兩個方面,一個是基於上層處理能力(RegionServer)的擴展,一個是基於存儲的擴展(HDFS)。通過橫向添加RegionSever的機器,進行水平擴展,提升Hbase上層的處理能力,提升Hbsae服務更多Region的能力。

1.4、高併發

       由於目前大部分使用Hbase的架構,都是採用的廉價PC,因此單個IO的延遲其實並不小,一般在幾十到上百ms之間。這裏說的高併發,主要是在併發的情況下,Hbase的單個IO延遲下降並不多。能獲得高併發、低延遲的服務。

1.5、稀疏

       稀疏主要是針對Hbase列的靈活性,在列族中,你可以指定任意多的列,在列數據爲空的情況下,是不會佔用存儲空間的。

二、HBase存儲

2.1 HBase數據模型

        2.1.1 與傳統關係型數據庫對比

         下圖是針對Hbase和關係型數據庫的基本的一個比較:

1)數據類型:關係數據庫採用關係模型,具有豐富的數據類型和存儲方式, HBase則採用了更加簡單的數據模型,它把數據存儲爲未經解釋的字符串。

2)數據操作:關係數據庫中包含了豐富的操作,其中會涉及複雜的多表連接。 HBase操作則不存在複雜的表與表之間的關係,只有簡單的插入、查詢、刪除、 清空等,因爲HBase在設計上就避免了複雜的表和表之間的關係。

3)存儲模式:關係數據庫是基於行模式存儲的。HBase是基於列存儲的,每個列族都由幾個文件保存,不同列族的文件是分離的。

4)數據索引:關係數據庫通常可以針對不同列構建複雜的多個索引,以提高數 據訪問性能。HBase只有一個索引——行鍵,通過巧妙的設計,HBase中的所有訪 問方法,或者通過行鍵訪問,或者通過行鍵掃描,從而使得整個系統不會慢下來 。

5)數據維護:在關係數據庫中,更新操作會用最新的當前值去替換記錄中原來 的舊值,舊值被覆蓋後就不會存在。而在HBase中執行更新操作時,並不會刪除數 據舊的版本,而是生成一個新的版本,舊有的版本仍然保留。

6)可伸縮性:關係數據庫很難實現橫向擴展,縱向擴展的空間也比較有限。相反,HBase和BigTable這些分佈式數據庫就是爲了實現靈活的水平擴展而開發的, 能夠輕易地通過在集羣中增加或者減少硬件數量來實現性能的伸縮。


        Table(表格)

    • 一個HBase表格由多行組成。

    Row Key:

    • 決定一行數據的唯一標識

    • RowKey是按照字典順序排序的。

    • Row key最多隻能存儲64k的字節數據。

    Column Family列族(CF1、CF2、CF3) & qualifier列:

    • HBase表中的每個列都歸屬於某個列族,列族必須作爲表模式(schema) 定義的一部分預先給出。如create ‘test’, ‘course’;

    • 列名以列族作爲前綴,每個“列族”都可以有多個列成員(column,每個列族中可以存放幾千~上千萬個列);如 CF1:q1, CF2:qw,新的列族成員(列)可以隨後按需、動態加入,Family下面可以有多個                                 Qualifier,所以可以簡單的理解爲,HBase中的列是二級列,也就是說Family是第一級列,Qualifier是第二級列。兩個是父子關係。

    • 權限控制、存儲以及調優都是在列族層面進行的;

    • HBase把同一列族裏面的數據存儲在同一目錄下,由幾個文件保存。

    • 目前爲止HBase的列族能能夠很好處理最多不超過3個列族。

    Timestamp時間戳:

    • 在HBase每個cell存儲單元對同一份數據有多個版本,根據唯一的時間 戳來區分每個版本之間的差異,不同版本的數據按照時間倒序排序,最新的數據版本排在最前面。

    • 時間戳的類型是64位整型。

    • 時間戳可以由HBase(在數據寫入時自動)賦值,此時時間戳是精確到毫 秒的當前系統時間。

    • 時間戳也可以由客戶顯式賦值,如果應用程序要避免數據版本衝突, 就必須自己生成具有唯一性的時間戳。

    Cell單元格:

    • 由行和列的座標交叉決定;

    • 單元格是有版本的(由時間戳來作爲版本);

    • 單元格的內容是未解析的字節數組(Byte[]),cell中的數據是沒有類型的,全部是字節碼形式存貯。

    • 由{row key,column(=<family> +<qualifier>),version}唯一確定的單元。

2.2 HBase 的架構設計

Client

• 包含訪問HBase的接口並維護cache來加快對HBase的訪問

Zookeeper

• 保證任何時候,集羣中只有一個master。HBase 會啓動多個 HMaster,並通過 ZooKeeper 選舉出一個主服務器

• 存貯所有Region的尋址入口。

• 實時監控Region server的上線和下線信息。並實時通知Master

• 存儲HBase的schema和table元數據

 Master

• 爲Region server分配region

• 負責Region server的負載均衡

• 發現失效的Region server並重新分配其上的region

• 管理用戶對table的增刪改操作

RegionServer

• Region server負責切分在運行過程中變得過大的region

• Region服務器負責存儲和維護分配給自己的Region,處理來自客戶端的讀寫請求, 客戶端並不是直接從Master主服務器上讀取數據,而是在獲得Region的存儲位置信息後,直接從Region服務器上讀取數據,      客戶端並不依賴Master,而是通過Zookeeper來獲得Region位置信息,大多數客戶 端甚至從來不和Master通信,這種設計方式使得Master負載很小。

HLog(WAL log):

      • HStore在系統正常工作的前提下是沒有問題的,但是在分佈式系統環境中,無法避免系統出錯或者宕機,因此一旦HRegionServer意外退出,MemStore中的內存數據將會丟失,這就需要引入HLog了。每個HRegionServer中都有一個HLog對象,HLog是一個實現Write Ahead Log的類,在每次用戶操作寫入MemStore的同時,也會寫一份數據到HLog文件中,HLog文件定期會滾動出新的,並刪除舊的文件(已持久化到StoreFile中的數據)。當HRegionServer意外終止後,HMaster會通過Zookeeper感知到,HMaster首先會處理遺留的 HLog文件,將其中不同Region的Log數據進行拆分,分別放到相應region的目錄下,然後再將失效的region重新分配,領取 到這些region的HRegionServer在Load Region的過程中,會發現有歷史HLog需要處理,因此會Replay HLog中的數據到MemStore中,然後flush到StoreFiles,完成數據恢復。

Region

• HBase自動把表水平劃分成多個區域(region),每個region會保存一個表裏面某段連續的數據;每個表一開始只有一個region,隨着數據不斷插 入表,region不斷增大,當增大到一個閥值的時候,region就會等分會 兩個新的region(裂變);

• 當table中的行不斷增多,就會有越來越多的region。這樣一張完整的表 被保存在多個Regionserver上。

Memstore 與 storefile

• 一個region由多個store組成,一個store對應一個CF(列族)

• store包括位於內存中的memstore和位於磁盤的storefile寫操作先寫入 memstore

• HStore存儲是HBase存儲的核心了,其中由兩部分組成,一部分是MemStore,一部分是StoreFiles。MemStore是Sorted Memory Buffer,用戶寫入的數據首先會放入MemStore,當MemStore滿了以後會Flush成一個StoreFile(底層實現是HFile),當StoreFile文件數量增長到一定閾值,會觸發Compact合併操作,將多個StoreFiles合併成一個StoreFile,合併過程中會進行版本合併和數據刪除,因此可以看出HBase其實只有增加數據,所有的更新和刪除操作都是在後續的compact過程中進行的,這使得用戶的寫操作只要進入內存中就可以立即返回,保證了HBase I/O的高性能。當StoreFiles Compact後,會逐步形成越來越大的StoreFile,當單個StoreFile大小超過一定閾值後,會觸發Split操作,同時把當前Region Split成2個Region,父Region會下線,新Split出的2個孩子Region會被HMaster分配到相應的HRegionServer上,使得原先1個Region的壓力得以分流到2個Region上。

三、Hbase的數據讀寫原理

3.1 Hbase尋址原理

3.1.1 -ROOT-表和.META.表的介紹

       HBase用-ROOT-表記錄.META.表的位置信息(即元數據信息),而.META.表記錄了用戶表Region的位置信息。爲了定位.META.表中各個Region的位置信息,把.META.表中所有Region的元數據保存在-ROOT-表中,最後由Zookeeper記錄-Root-表的位置信息。所以客戶端Client要先訪問ZK獲取-ROOT-表的位置,然後訪問-ROOT-表獲取.META.表的位置,最後根據.META.表中的信息確定用戶數據存放的位置。

3.2 -ROOT-表結構

       HBase的用-ROOT-表來記錄.META.的Region信息,就和.META.記錄用戶表的Region信息一模一樣。-ROOT-只會有一個Region。這麼一來Client端就需要先去訪問-ROOT-表。所以需要知道管理-ROOT-表的RegionServer的地址。這個地址被存在ZooKeeper中。默認的路徑是:/hbase/root-region-server

-ROOT-行記錄結構

3.3 META.表結構

.META.行記錄結構
3.4 兩個表的關係

        HBase的所有Region元數據被存儲在.META.表中,隨着Region的增多,.META.表中的數據也會增大,並分裂成多個新的Region。爲了定位.META.表中各個Region的位置,把.META.表中所有Region的元數據保存在-ROOT-表中,最後由Zookeeper記錄-ROOT-表的位置信息。所有客戶端訪問用戶數據前,需要首先訪問Zookeeper獲得-ROOT-的位置,然後訪問-ROOT-表獲得.META.表的位置,最後根據.META.表中的信息確定用戶數據存放的位置,如下圖所示。

 

        -ROOT-表永遠不會被分割,它只有一個Region,這樣可以保證最多隻需要三次跳轉就可以定位任意一個Region。爲了加快訪問速度,.META.表的所有Region全部保存在內存中。客戶端會將查詢過的位置信息緩存起來,且緩存不會主動失效。如果客戶端根據緩存信息還訪問不到數據,則詢問相關.META.表的Region服務器,試圖獲取數據的位置,如果還是失敗,則詢問-ROOT-表相關的.META.表在哪裏。最後,如果前面的信息全部失效,則通過ZooKeeper重新定位Region的信息。所以如果客戶端上的緩存全部是失效,則需要進行6次網絡來回,才能定位到正確的Region。

3.5 讀流程

1. Client訪問Zookeeper,查找-ROOT-表,獲取.META.表信息。
2. 從.META.表查找,獲取存放目標數據的Region信息,從而找到對應的RegionServer。
3. 通過RegionServer獲取需要查找的數據。
4. Regionserver的內存分爲MemStore和BlockCache兩部分,MemStore主要用於寫數據,BlockCache主要用於讀數據。讀請求先到MemStore中查數據,查不到就到BlockCache中查,再查不到就會到StoreFile上讀,並把讀的結果放入BlockCache。
讀取過程:client–>Zookeeper–>-ROOT-表–>META表–>RegionServer–>Region–>client

 3.6  寫流程

       1.Client通過Zookeeper調度獲取表的元數據信息;

  2.Cilent通過rpc協議與RegionServer交互,通過-ROOT-表與.META.表找到對應的對應的Region;

  3.將數據寫入HLog日誌中,如出現意外可以同通過HLog恢復信息;

  4.將數據寫入Region的MemStore中,當MemStore達到閾值開始溢寫,將其中的數據Flush成一個StoreFile;

  5.MemStore不斷生成新的StoreFile,當StoreFile的數量到達閾值後會出發Compact合併操作,將多個StoreFile合併成一個StoreFile;

  6.StoreFile文件會不斷增大,當達到閾值後會出發Split操作,把當前的Region且分爲兩個新的Region。父Region會下線,兩個子Region會被HMaster分配到相應的RegionServer。

        可以看出HBase只有增添數據,所有的更新和刪除操作都是在後續的Compact歷程中舉行的,使得用戶的寫操作只要進入內存就可以立刻返回,實現了HBase I/O的高性能。

 3.7 緩存的刷新

        •系統會週期性地把MemStore緩存裏的內容刷寫到磁盤的StoreFile文 件中,清空緩存,並在Hlog裏面寫入一個標記

•每次刷寫都生成一個新的StoreFile文件,因此,每個Store包含多個 StoreFile文件
•每個Region服務器都有一個自己的HLog 文件,每次啓動都檢查該文 件,確認最近一次執行緩存刷新操作之後是否發生新的寫入操作;如果發現更新,則先寫入MemStore,再刷寫到StoreFile,最後刪除舊的Hlog文件,開始爲用戶提供服務

 

參考文章:

http://archive.apache.org/dist/hbase/ hbase各版本

https://www.jianshu.com/p/e3b764871c68

https://blog.csdn.net/yyl424525/article/details/77505749

https://baike.baidu.com/item/HBase/7670213?fr=aladdin

https://www.jianshu.com/p/d27b31808c8a hbase shell操作

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