一條資料HBase之旅,簡明HBase入門教程開篇

ylj007發表於2018-06-15

  這是HBase入門系列的第1篇文章,介紹HBase的資料模型、適用場景、叢集關鍵角色、建表流程以及所涉及的HBase基礎概念,本文內容基於HBase 2.0 beta2版本。本文既適用於HBase新手,也適用於已有一定經驗的HBase開發人員。

  一些常見的HBase新手問題

  ·什麼樣的資料適合用HBase來儲存?

     ·既然HBase也是一個資料庫,能否用它將現有系統中昂貴的Oracle替換掉?

  ·存放於HBase中的資料記錄,為何不直接存放於HDFS之上?

  ·能否直接使用HBase來儲存檔案資料?

  ·Region(HBase中的資料分片)遷移後,資料是否也會被遷移?

  ·為何基於Spark/Hive分析HBase資料時效能較差?

  開篇

  用慣了Oracle/MySQL的同學們,心目中的資料表,應該是長成這樣的:

一條資料HBase之旅,簡明HBase入門教程開篇

  這種表結構規整,每一行都有固定的列構成,因此,非常適合結構化資料的儲存。但在NoSQL領域,資料表的模樣卻往往換成了另外一種”畫風”:

一條資料HBase之旅,簡明HBase入門教程開篇

  行由看似”雜亂無章”的列組成,行與行之間也無須遵循一致的定義,而這種定義恰好符合半結構化資料或非結構化資料的特點。本文所要講述的HBase,就屬於該派系的一個典型代表。這些”雜亂無章”的列所構成的多行資料,被稱之為一個”稀疏矩陣”,而上圖中的每一個”黑塊塊”,在HBase中稱之為一個KeyValue。

  Apache HBase官方給出了這樣的定義:

  Apache HBase? is the hadoop database, a distributed , scalable , big data store .

  即:Apache HBase是基於Hadoop構建的一個 分散式 的、 可伸縮 的 海量資料儲存系統 。

  HBase常被用來存放一些結構簡單,但資料量非常大的資料(通常在TB級別以上),如歷史訂單記錄,日誌資料,監控Metris資料等等,HBase提供了簡單的基於Key值的快速查詢能力。

  HBase在國內市場已經取得了非常廣泛的應用,在搜尋引擎中,也可以看出來,HBase在國內呈現出了逐年上升的勢態:

一條資料HBase之旅,簡明HBase入門教程開篇

  從Apache HBase所關聯的github專案的commits統計資訊來看,也可以看出來該專案非常活躍:

一條資料HBase之旅,簡明HBase入門教程開篇

  (需要說明的一點:HBase中的每一次commit,都已經過社群Commiter成員嚴格的Review,在commit之前,一個Patch可能已經被修改了幾十個版本)

  令人欣喜的是,國內的開發者也積極參與到了HBase社群貢獻中,而且被社群接納了多名PMC以及Committer成員。

  本文將以 一條資料在HBase中的“旅程” 為線索,介紹HBase的核心概念與流程,幾乎每一部分都可以展開成一篇獨立的長文,但本文旨在讓讀者能夠快速的瞭解HBase的架構輪廓,所以很多特性/流程被被一言帶過,但這些特性在社群中往往經歷了漫長的開發過程。至於講什麼以及講到什麼程度,本文都做了艱難的取捨,在講解的過程中,將會穿插解答本文開始所提出的針對初學者的一些常見問題。

  本文適用於HBase新手,而對於具備一定經驗的HBase開發人員,相信本文也可以提供一些有價值的參考。本文內容基於HBase 2.0 beta 2版本,對比於1.0甚至是更早期的版本,2.0出現了大量變化,下面這些問題的答案與部分關鍵的變化相關(新手可以直接跳過這些問題):

  ·HBase meta Region在哪裡提供服務?

  ·HBase是否可以保證單行操作的原子性?

  ·Region中寫WAL與寫MemStore的順序是怎樣的?

  ·你是否遇到過Region長時間處於RIT的狀態? 你認為舊版本中Assignment Manager的主要問題是什麼?

  ·在面對Full GC問題時,你嘗試做過哪些優化?

  ·你是否深究過HBase Compaction帶來的“寫放大”有多嚴重?

  ·HBase的RPC框架存在什麼問題?

  ·導致查詢時延毛刺的原因有哪些?

  本系列文章的 整體行文思路 如下:

  ·介紹HBase資料模型

  ·基於資料模型介紹HBase的適用場景

  ·快速介紹叢集關鍵角色以及叢集部署建議

  ·示例資料介紹

  ·寫資料流程

  ·讀資料流程

  ·資料更新

  ·負載均衡機制

  HBase如何儲存小檔案資料

  這些內容將會被拆成幾篇文章。至於叢集服務故障的處理機制,叢集工具,周邊生態,效能調優以及最佳實踐等進階內容,暫不放在本系列文章範疇內。

  約定

  本文範圍內針對一些關鍵特性/流程,使用了加粗以及加下劃線的方式做了強調,如” ProcedureV2 “。這些特性往往在本文中僅僅被粗淺提及,後續計劃以獨立的文章來介紹這些特性/流程。

  術語縮寫 :對於一些程式/角色名稱,在本文範圍內可能通過縮寫形式來表述:

一條資料HBase之旅,簡明HBase入門教程開篇

  資料模型

  RowKey

  用來表示唯一一行記錄的 主鍵 ,HBase的資料是按照RowKey的 字典順序 進行全域性排序的,所有的查詢都只能依賴於這一個排序維度。

  通過下面一個例子來說明一下” 字典排序 “的原理:

  RowKey {“abc”, “a”, “bdf”, “cdf”, “defg”}按字典排序後的結果為{“a”, “abc”, “bdf”, “cdf”, “defg”}

  也就是說,當兩個RowKey進行排序時,先對比兩個RowKey的第一個位元組,如果相同,則對比第二個位元組,依此類推…如果在對比到第M個位元組時,已經超出了其中一個RowKey的位元組長度,那麼,短的RowKey要被排在另外一個RowKey的前面

  稀疏矩陣

  參考了Bigtable,HBase中一個表的資料是按照稀疏矩陣的方式組織的,”開篇”部分給出了一張關於HBase資料表的 抽象圖 ,我們再結合下表來加深大家關於”稀疏矩陣”的印象:

一條資料HBase之旅,簡明HBase入門教程開篇

  看的出來: 每一行中,列的組成都是靈活的,行與行之間並不需要遵循相同的列定義 , 也就是HBase資料表” schema-less “的特點。

  Region

  區別於Cassandra/DynamoDB的”Hash分割槽”設計,HBase中採用了”Range分割槽”,將Key的完整區間切割成一個個的”Key Range” ,每一個”Key Range”稱之為一個Region。

  也可以這麼理解:將HBase中擁有數億行的一個大表, 橫向切割 成一個個” 子表 “,這一個個” 子表 “就是 Region :

一條資料HBase之旅,簡明HBase入門教程開篇

  Region是HBase中負載均衡的基本單元,當一個Region增長到一定大小以後,會自動分裂成兩個。

  Column Family

  如果將Region看成是一個表的 橫向切割 ,那麼,一個Region中的資料列的 縱向切割 ,稱之為一個 Column Family 。每一個列,都必須歸屬於一個Column Family,這個歸屬關係是在寫資料時指定的,而不是建表時預先定義。

一條資料HBase之旅,簡明HBase入門教程開篇

  KeyValue

  KeyValue的設計不是源自Bigtable,而是要追溯至論文”The log-structured merge-tree(LSM-Tree)”。每一行中的每一列資料,都被包裝成獨立的擁有 特定結構 的KeyValue,KeyValue中包含了豐富的自我描述資訊:

一條資料HBase之旅,簡明HBase入門教程開篇

  看的出來,KeyValue是支撐”稀疏矩陣”設計的一個關鍵點:一些Key相同的任意數量的獨立KeyValue就可以構成一行資料。但這種設計帶來的一個顯而易見的缺點: 每一個KeyValue所攜帶的自我描述資訊,會帶來顯著的資料膨脹 。

  適用場景

  在介紹完了HBase的資料模型以後,我們可以回答本文一開始的前兩個問題:

  ·什麼樣的資料適合用HBase來儲存?

  ·既然HBase也是一個資料庫,能否用它將現有系統中昂貴的Oracle替換掉?

  HBase的資料模型比較簡單,資料按照RowKey排序存放,適合HBase儲存的資料,可以簡單總結如下:

  ·以 實體 為中心的資料

  ·實體可以包括但不限於如下幾種:

  描述這些實體的,可以有基礎屬性資訊、實體關係(圖資料)、所發生的事件(如交易記錄、車輛軌跡點)等等。

  ·自然人/賬戶/手機號/車輛相關資料

  ·使用者畫像資料(含標籤類資料)

  ·圖資料(關係類資料)

  ·以 事件 為中心的資料

  ·監控資料

  ·時序資料

  ·實時位置類資料

  ·訊息/日誌類資料

  上面所描述的這些資料,有的是結構化資料,有的是半結構化或非結構化資料。HBase的“稀疏矩陣”設計,使其應對非結構化資料儲存時能夠得心應手,但在我們的實際使用者場景中,結構化資料儲存依然佔據了比較重的比例。由於HBase僅提供了基於RowKey的單維度索引能力,在應對一些具體的場景時,依然還需要基於HBase之上構建一些專業的能力,如:

  ·OpenTSDB 時序資料儲存,提供基於Metrics+時間+標籤的一些組合維度查詢與聚合能力

  ·GeoMesa 時空資料儲存,提供基於時間+空間範圍的索引能力

  ·JanusGraph 圖資料儲存,提供基於屬性、關係的圖索引能力

  HBase擅長於儲存結構簡單的海量資料但索引能力有限,而Oracle等傳統關係型資料庫(RDBMS)能夠提供豐富的查詢能力,但卻疲於應對TB級別的海量資料儲存,HBase對傳統的RDBMS並不是取代關係,而是一種補充。

  HBase與HDFS

  我們都知道HBase的資料是儲存於HDFS裡面的,相信大家也都有這麼的認知:

  ·HBase是一個 分散式資料庫 ,HDFS是一個 分散式檔案系統

  理解了這一點,我們先來粗略回答本文已開始提出的其中兩個問題:

  ·HBase中的資料為何不直接存放於HDFS之上?

  HBase中儲存的海量資料記錄,通常在幾百Bytes到KB級別,如果將這些資料直接儲存於HDFS之上,會導致大量的小檔案產生,為HDFS的後設資料管理節點(NameNode)帶來沉重的壓力。

  ·檔案能否直接儲存於HBase裡面?

  如果是幾MB的檔案,其實也可以直接儲存於HBase裡面,我們暫且將這類檔案稱之為小檔案,HBase提供了一個名為MOB的特性來應對這類小檔案的儲存。但如果是更大的檔案,強烈不建議用HBase來儲存,關於這裡更多的原因,希望你在詳細讀完本文所有內容之後能夠自己解答。

  叢集角色

  關於叢集環境,你可以使用國內外大資料廠商的平臺,如Cloudera,Hontonworks以及國內的華為,都發行了自己的企業版大資料平臺,另外,華為雲、阿里雲中也均推出了全託管式的HBase服務。

  我們假設叢集環境已經Ready了,先來看一下叢集中的 關鍵角色 :

一條資料HBase之旅,簡明HBase入門教程開篇

  相信大部分人對這些角色都已經有了一定程度的瞭解,我們快速的介紹一下各個角色在叢集中的 主要 職責( 注意 :這裡不是列出所有的職責):

  ZooKeeper

  在一個擁有多個節點的分散式系統中,假設,只能有一個節點是主節點,如何快速的選舉出一個主節點而且讓所有的節點都認可這個主節點?這就是HBase叢集中存在的一個最基礎命題。

  利用ZooKeeper就可以非常簡單的實現這類”仲裁”需求,ZooKeeper還提供了基礎的事件通知機制,所有的資料都以 ZNode的形式存在,它也稱得上是一個”微型資料庫”。

  NameNode

  HDFS作為一個分散式檔案系統,自然需要檔案目錄樹的 後設資料 資訊,另外,在HDFS中每一個檔案都是按照Block儲存的,檔案與Block的關聯也通過 後設資料 資訊來描述。NameNode提供了這些 後設資料資訊的儲存 。

  DataNode

  HDFS的資料存放節點。

  RegionServer

  HBase的 資料服務節點 。

  Master

  HBase的管理節點,通常在一個叢集中設定一個主Master,一個備Master,主備角色的”仲裁”由ZooKeeper實現。 Master 主要職責 :

  ·負責管理所有的RegionServer

  ·建表/修改表/刪除表等DDL操作請求的服務端執行主體

  ·管理所有的資料分片(Region)到RegionServer的分配

  ·如果一個RegionServer當機或程式故障,由Master負責將它原來所負責的Regions轉移到其它的RegionServer上繼續提供服務

  ·Master自身也可以作為一個RegionServer提供服務,該能力是可配置的

  叢集部署建議

  如果基於物理機/虛擬機器部署,通常建議:

  RegionServer與DataNode聯合部署,RegionServer與DataNode按1:1比例設定。

  這種部署的優勢在於,RegionServer中的資料檔案可以儲存一個副本於本機的DataNode節點中,從而在讀取時可以利用HDFS中的” 短路徑讀取(Short Circuit) “來繞過網路請求,降低讀取時延。

一條資料HBase之旅,簡明HBase入門教程開篇

  管理節點獨立於資料節點部署

  如果是基於物理機部署,每一臺物理機節點上可以設定幾個RegionServers/DataNodes來提升資源使用率。

  也可以選擇基於容器來部署,如在HBaseCon Asia 2017大會知乎的演講主題中,就提到了知乎基於Kubernetes部署HBase服務的實踐。

  對於公有云HBase服務而言,為了降低總體擁有成本( TCO ),通常選擇” 計算與儲存物理分離 “的方式,從架構上來說,可能導致平均時延略有下降,但可以藉助於共享儲存底層的IO優化來做一些”彌補”。

  HBase叢集中的RegionServers可以按邏輯劃分為多個Groups,一個表可以與一個指定的Group繫結,可以將RegionServer Group理解成將一個大的叢集劃分成了多個邏輯子叢集,藉此可以實現多租戶間的隔離,這就是HBase中的 RegionServer Group 特性。

  示例資料

  以我們日常生活都熟悉的手機通話記錄的儲存為例,先簡單給出示例資料的欄位定義:

一條資料HBase之旅,簡明HBase入門教程開篇

  本文內容力求簡潔,僅給出了幾個簡單欄位。如下是”虛構”的樣例資料:

一條資料HBase之旅,簡明HBase入門教程開篇

  在本文大部分內容中所涉及的一條資料,是上面加粗的最後一行” MSISDN1 “為” 13400006666 “這行記錄。

  在本系列文章的流程圖中,我們將會使用一個 紅色的五角星 來表示該資料所在的位置。

  寫資料之前:建立連線

  Login

  在啟用了安全特性的前提下,Login階段是為了完成 使用者認證 (確定使用者的合法身份),這是後續一切 安全訪問控制 的基礎。

  當前Hadoop/HBase僅支援基於Kerberos的使用者認證,ZooKeeper除了Kerberos認證,還能支援簡單的使用者名稱/密碼認證,但都基於靜態的配置,無法動態新增使用者。如果要支援其它第三方認證,需要對現有的安全框架做出比較大的改動。

  建立Connection

  Connection可以理解為一個HBase叢集連線的抽象,建議使用ConnectionFactory提供的工具方法來建立。因為HBase當前提供了兩種連線模式:同步連線,非同步連線,這兩種連線模式下所建立的Connection也是不同的。我們給出ConnectionFactory中關於獲取這兩種連線的典型方法定義:

一條資料HBase之旅,簡明HBase入門教程開篇

  Connection中主要維護著兩類共享的資源:

  ·執行緒池

  ·Socket連線

  這些資源都是在真正使用的時候才會被建立,因此,此時的連線還只是一個”虛擬連線”。

  寫資料之前:建立資料表

  DDL操作的抽象介面 – Admin

  Admin定義了常規的DDL介面,列舉幾個典型的介面:

一條資料HBase之旅,簡明HBase入門教程開篇

  預設合理的資料分片 – Region

  分片數量會給讀寫吞吐量帶來直接的影響,因此,建表時通常建議由使用者主動指定劃分 Region分割點 ,來設定Region的數量。

  HBase中資料是按照RowKey的字典順序排列的,為了能夠劃分出合理的Region分割點,需要依據如下幾點資訊:

  ·Key的組成結構

  ·Key的資料分佈預估

  如果不能基於Key的組成結構來預估資料分佈的話,可能會導致資料在Region間的分佈不均勻

  ·讀寫併發度需求

  ·依據讀寫併發度需求,設定合理的Region數量

  ·為表定義合理的Schema

  既然HBase號稱”schema-less”的資料儲存系統,那何來的是schema? 的確,在資料庫正規化的支援上,HBase非常弱,這裡的Schema,主要指如下一些資訊的設定:

  ·NameSpace設定

  ·Column Family的數量

  每一個Column Family中所關聯的一些 關鍵配置 :

  ·Compression

  HBase當前可以支援Snappy,GZ,LZO,LZ4,Bzip2以及ZSTD壓縮演算法

  ·DataBlock Encoding

  HBase針對自身的特殊資料模型所做的一種壓縮編碼

  ·BloomFilter

  可用來協助快速判斷一條記錄是否存在

  ·TTL

  指定資料的過期時間

  ·StoragePolicy

  指定Column Family的儲存策略,可選配置有:

  “ALL_SSD”,”ONE_SSD”,”HOT”,”WARM”,”COLD”,”LAZY_PERSIST”

  HBase中並不需要預先設定Column定義資訊,這就是HBase schema-less設計的核心。

  Client傳送建表請求到Master

  建表的請求是通過RPC的方式由Client傳送到Master:

  ·RPC介面基於Protocol Buffer定義

  ·建表相關的描述引數,也由Protocol Buffer進行定義及序列化

  Client端側呼叫了Master服務的什麼介面,引數是什麼,這些資訊都被通過RPC通訊傳輸到Master側,Master再依據這些介面\引數描述資訊決定要執行的操作。2.0版本中,HBase目前已經支援基於Netty的 非同步RPC框架 。

  關於HBase RPC框架

  早期的HBase RPC框架,完全借鑑了Hadoop中的實現,那時,Netty專案尚不盛行。

  Master側接收到Client側的建表請求以後,一些主要操作包括:

  生成每一個Region的描述資訊物件HRegionInfo,這些描述資訊包括:Region ID, Region名稱,Key範圍,表名稱等資訊

  生成每一個Region在HDFS中的檔案目錄

  將HRegionInfo資訊寫入到記錄後設資料的hbase:meta表中。

  說明

  meta表位於名為”hbase”的namespace中,因此,它的全稱為”hbase:meta”。

  但在本系列文章範疇內,常將其縮寫為”meta”。

  整個過程中,新表的狀態也是記錄在hbase:meta表中的,而不用再儲存在ZooKeeper中。

  如果建表執行了一半,Master程式掛掉了,如何處理?這裡是由HBase自身提供的一個名為 Procedure(V2) 的框架來保障操作的事務性的,備Master接管服務以後,將會繼續完成整個建表操作。

  一個被建立成功的表,還可以被執行如下操作:

  Disable 將所有的Region下線,該表暫停讀寫服務

  Enable 將一個Disable過的表重新Enable,也就是上線所有的Region來正常提供讀寫服務

  Alter 更改表或列族的描述資訊

  Master分配Regions到各個RegionServers

  新建立的所有的Regions,通過 AssignmentManager 將這些Region按照輪詢(Round-Robin)的方式分配到每一個RegionServer中,具體的分配計劃是由 LoadBalancer 來提供的。

  AssignmentManager負責所有Regions的分配/遷移操作,Master中有一個定時執行的執行緒,來檢查叢集中的Regions在各個RegionServer之間的負載是否是均衡的,如果不均衡,則通過LoadBalancer生成相應的Region遷移計劃,HBase中支援多種負載均衡演算法,有最簡單的僅考慮各RegionServer上的Regions數目的負載均衡演算法,有基於遷移代價的負載均衡演算法,也有資料本地化率優先的負載均衡演算法,因為這一部分已經提供了外掛化機制,使用者也可以自定義負載均衡演算法。

  總結

  到目前為止,文章介紹瞭如下關鍵內容:

  ·HBase專案概述,呈現了HBase社群的活躍度以及搜尋引擎熱度等資訊

  ·HBase資料模型部分,講到了RowKey,稀疏矩陣,Region,Column Family,KeyValue等概念

  ·基於HBase的資料模型,介紹了HBase的適合場景(以實體/事件為中心的簡單結構的資料)

  ·介紹了HBase與HDFS的關係

  ·介紹了叢集的關鍵角色:ZooKeeper, Master, RegionServer,NameNode, DataNode

  ·叢集部署建議

  ·給出了一些示例資料

  寫資料之前的準備工作:建立叢集連線,建表(建表時應該定義合理的Schema以及設定合理的Region數量),建表由Master處理,新建立的Regions由Region AssignmentManager負責分配到各個RegionServer。

  下一篇文章將正式開始介紹寫資料的流程。

  本文作者:畢傑山

  致謝

  感謝 Apache HBase PMC成員Ted Yu,李鈺,張鐸對本文中與2.0版本相關特性/流程描述內容方面的Review,感謝王瓊、向巨集偉以及陳土炎等幾位同學給本文內容方面提出的寶貴意見。

  本文首發於: NoSQL漫談(nosqlnotes.com)

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31542492/viewspace-2156225/,如需轉載,請註明出處,否則將追究法律責任。

相關文章