Hadoop相關知識整理系列之一:HBase基本架構及原理


1. HBase框架簡單介紹

HBase是一個分布式的、面向列的開源數據庫,它不同於一般的關系數據庫,是一個適合於非結構化數據存儲的數據庫。另一個不同的是HBase基於列的而不是基於行的模式。HBase使用和 BigTable非常相同的數據模型。用戶存儲數據行在一個表里。一個數據行擁有一個可選擇的鍵和任意數量的列,一個或多個列組成一個ColumnFamily,一個Fmaily下的列位於一個HFile中,易於緩存數據。表是疏松的存儲的,因此用戶可以給行定義各種不同的列。在HBase中數據按主鍵排序,同時表按主鍵划分為多個Region。

在分布式的生產環境中,HBase 需要運行在 HDFS 之上,以 HDFS 作為其基礎的存儲設施。HBase 上層提供了訪問的數據的 Java API 層,供應用訪問存儲在 HBase 的數據。在 HBase 的集群中主要由 Master 和 Region Server 組成,以及 Zookeeper,具體模塊如下圖所示:

簡單介紹一下 HBase 中相關模塊的作用:

  • Master
    HBase Master用於協調多個Region Server,偵測各個RegionServer之間的狀態,並平衡RegionServer之間的負載。HBaseMaster還有一個職責就是負責分配Region給RegionServer。HBase允許多個Master節點共存,但是這需要Zookeeper的幫助。不過當多個Master節點共存時,只有一個Master是提供服務的,其他的Master節點處於待命的狀態。當正在工作的Master節點宕機時,其他的Master則會接管HBase的集群。
  • Region Server
    對於一個RegionServer而言,其包括了多個Region。RegionServer的作用只是管理表格,以及實現讀寫操作。Client直接連接RegionServer,並通信獲取HBase中的數據。對於Region而言,則是真實存放HBase數據的地方,也就說Region是HBase可用性和分布式的基本單位。如果當一個表格很大,並由多個CF組成時,那么表的數據將存放在多個Region之間,並且在每個Region中會關聯多個存儲的單元(Store)。
  • Zookeeper
    對於 HBase 而言,Zookeeper的作用是至關重要的。首先Zookeeper是作為HBase Master的HA解決方案。也就是說,是Zookeeper保證了至少有一個HBase Master 處於運行狀態。並且Zookeeper負責Region和Region Server的注冊。其實Zookeeper發展到目前為止,已經成為了分布式大數據框架中容錯性的標准框架。不光是HBase,幾乎所有的分布式大數據相關的開源框架,都依賴於Zookeeper實現HA。

2. Hbase數據模型

2.1 邏輯視圖

基本概念:

  • RowKey:是Byte array,是表中每條記錄的“主鍵”,方便快速查找,Rowkey的設計非常重要;
  • Column Family:列族,擁有一個名稱(string),包含一個或者多個相關列;
  • Column:屬於某一個columnfamily,familyName:columnName,每條記錄可動態添加;
  • Version Number:類型為Long,默認值是系統時間戳,可由用戶自定義;
  • Value(Cell):Byte array。

2.2 物理模型:

  • 每個column family存儲在HDFS上的一個單獨文件中,空值不會被保存。
  • Key 和 Version number在每個column family中均有一份;
  • HBase為每個值維護了多級索引,即:<key, columnfamily, columnname, timestamp>;
  • 表在行的方向上分割為多個Region;
  • Region是Hbase中分布式存儲和負載均衡的最小單元,不同Region分布到不同RegionServer上。
  • Region按大小分割的,隨着數據增多,Region不斷增大,當增大到一個閥值的時候,Region就會分成兩個新的Region;
  • Region雖然是分布式存儲的最小單元,但並不是存儲的最小單元。每個Region包含着多個Store對象。每個Store包含一個MemStore或若干StoreFile,StoreFile包含一個或多個HFile。MemStore存放在內存中,StoreFile存儲在HDFS上。

疑問:每一個Region都只存儲一個ColumnFamily的數據,並且是該CF中的一段(按Row的區間分成多個 Region)?這個需要查證,每個Region只包含一個ColumnFamily可以提高並行性?然而,我只知道每個Store只包含一個ColumnFamily的數據。

2.3 ROOT表和META表

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。

一個完整分布式的HBase的組成示意圖如下,后面我們再詳細談其工作原理。

3. 高可用

3.1 Write-Ahead-Log(WAL)保障數據高可用

我們理解下HLog的作用。HBase中的HLog機制是WAL的一種實現,而WAL(一般翻譯為預寫日志)是事務機制中常見的一致性的實現方式。每個RegionServer中都會有一個HLog的實例,RegionServer會將更新操作(如 Put,Delete)先記錄到 WAL(也就是HLo)中,然后將其寫入到Store的MemStore,最終MemStore會將數據寫入到持久化的HFile中(MemStore 到達配置的內存閥值)。這樣就保證了HBase的寫的可靠性。如果沒有 WAL,當RegionServer宕掉的時候,MemStore 還沒有寫入到HFile,或者StoreFile還沒有保存,數據就會丟失。或許有的讀者會擔心HFile本身會不會丟失,這是由 HDFS 來保證的。在HDFS中的數據默認會有3份。因此這里並不考慮 HFile 本身的可靠性。

HFile由很多個數據塊(Block)組成,並且有一個固定的結尾塊。其中的數據塊是由一個Header和多個Key-Value的鍵值對組成。在結尾的數據塊中包含了數據相關的索引信息,系統也是通過結尾的索引信息找到HFile中的數據。

3.2 組件高可用

  • Master容錯:Zookeeper重新選擇一個新的Master。如果無Master過程中,數據讀取仍照常進行,但是,region切分、負載均衡等無法進行;
  • RegionServer容錯:定時向Zookeeper匯報心跳,如果一旦時間內未出現心跳,Master將該RegionServer上的Region重新分配到其他RegionServer上,失效服務器上“預寫”日志由主服務器進行分割並派送給新的RegionServer;
  • Zookeeper容錯:Zookeeper是一個可靠地服務,一般配置3或5個Zookeeper實例。

4. HBase讀寫流程

上圖是RegionServer數據存儲關系圖。上文提到,HBase使用MemStore和StoreFile存儲對表的更新。數據在更新時首先寫入HLog和MemStore。MemStore中的數據是排序的,當MemStore累計到一定閾值時,就會創建一個新的MemStore,並且將老的MemStore添加到Flush隊列,由單獨的線程Flush到磁盤上,成為一個StoreFile。與此同時,系統會在Zookeeper中記錄一個CheckPoint,表示這個時刻之前的數據變更已經持久化了。當系統出現意外時,可能導致MemStore中的數據丟失,此時使用HLog來恢復CheckPoint之后的數據。
StoreFile是只讀的,一旦創建后就不可以再修改。因此Hbase的更新其實是不斷追加的操作。當一個Store中的StoreFile達到一定閾值后,就會進行一次合並操作,將對同一個key的修改合並到一起,形成一個大的StoreFile。當StoreFile的大小達到一定閾值后,又會對 StoreFile進行切分操作,等分為兩個StoreFile。

4.1 寫操作流程

  • (1) Client通過Zookeeper的調度,向RegionServer發出寫數據請求,在Region中寫數據。
  • (2) 數據被寫入Region的MemStore,直到MemStore達到預設閾值。
  • (3) MemStore中的數據被Flush成一個StoreFile。
  • (4) 隨着StoreFile文件的不斷增多,當其數量增長到一定閾值后,觸發Compact合並操作,將多個StoreFile合並成一個StoreFile,同時進行版本合並和數據刪除。
  • (5) StoreFiles通過不斷的Compact合並操作,逐步形成越來越大的StoreFile。
  • (6) 單個StoreFile大小超過一定閾值后,觸發Split操作,把當前Region Split成2個新的Region。父Region會下線,新Split出的2個子Region會被HMaster分配到相應的RegionServer上,使得原先1個Region的壓力得以分流到2個Region上。

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

4.2 讀操作流程

  • (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

其它相關內容待補充


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM