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的數據。負載均衡
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
其它相關內容待補充