天天看點

Chapter4 分布式資料庫HBase

4.1概述

4.1.1從BigTable說起

HBase是BigTable的開源實作。

BigTable是一個分布式存儲系統,它最初是用于解決谷歌公司内部的大規模網頁所搜問題。

網頁搜尋可以分為兩個階段:

1.第一階段:建立整個網頁的索引。

通過爬蟲不斷的抓取各個網站的頁面,将網頁的每頁一行存儲到BigTable中。

在BigTable上運作MapReduce,MapReduce計算作業運作在整張表上,會生成索引,保證能夠快速搜尋相關網頁。

2.第二階段:搜尋網際網路網頁。

搜尋引擎接收使用者發起的查詢請求。

網絡搜尋應用通過查詢建立好的索引,從BigTable得到網頁。

最後将網頁搜尋結果傳回給使用者。

BigTable誕生之初主要就是滿足網際網路搜尋引擎的基本需求。但現如今,BigTable作為分布式存儲系統,不止用于網頁搜尋,還用于谷歌非常多的項目中,包括搜尋、地圖、财經、列印,以及一些社交網站、視訊共享網站、部落格系統等。

BigTable并非直接将底層磁盤作為存儲,它是架構在GFS(谷歌分布式檔案系統)基礎之上的,并使用GFS作為底層資料存儲。并且采用Chubby提供的協調管理服務。

Chapter4 分布式資料庫HBase

BigTable受到廣泛關注的原因包括:

1.它具有非常好的性能,可以支援PB級别的資料。

2.它具有非常好的可擴充性,可以用叢集去存儲幾千台伺服器,完成分布式存儲。

4.1.2HBase簡介

HBase是一個高可靠、高性能、面向列、可伸縮的分布式資料庫。

相比于隻能存儲完全非結構化資料的底層分布式檔案系統,HBase可以用來存儲非結構化和半結構化的松散資料。并且HBase的目标是通過水準擴充的方式,允許幾千台伺服器去存儲海量檔案,實作龐大的存儲規模。

HBase和BigTable的底層技術對應關系如下:

Chapter4 分布式資料庫HBase

關系型資料庫已經流行許多年了,況且Hadoop已經有了HDFS和MapReduce,為什麼需要HBase?

  1. Hadoop可以解決大規模資料的離線批量處理問題,但是Hadoop受限于Hadoop MapReduce程式設計架構的高延遲資料處理機制,随着資料的大規模爆炸式增長,Hadoop沒有辦法滿足大規模資料實時處理的需求。
  2. 傳統的關系型資料庫的擴充能力非常有限,對大規模資料的存儲能力不夠。即使分庫分表,也不能很好解決資料規模劇增導緻的系統擴充性和性能問題。
  3. 傳統的關系資料庫可以應對一定的資料結構變化,但是需要進行停機維護。
  4. HDFS面向的是批量通路模式,而非随機通路模式。

HBase與傳統的關系資料庫的主要差別有哪些?

  1. 資料類型方面

    傳統的關系資料庫使用的是經典的關系資料模型,具有豐富的資料類型和存儲方式。

    而HBase采用了更簡單的資料模型,把資料存儲為未經解釋的字元串,需要依靠程式開發人員解釋資料類型。

  2. 資料操作方面

    關系資料庫中定義了非常多的資料操作,比如更新、删除、查詢、多表連接配接等。

    而HBase隻有簡單的插入、查詢、删除、清空等操作,避免了複雜的表與表之間的關系。

  3. 存儲模式

    關系資料庫基于行模式存儲。

    而HBase基于列存儲,每個列族都由幾個檔案儲存,不同列族的檔案是分離的。

  4. 資料索引

    關系資料庫可以直接針對各個不同的列,建構非常複雜的索引,以快速定位到相關記錄。

    而HBase隻支援對行鍵進行索引,所有通路方法,要麼通過行鍵通路,要麼通過行鍵掃描。

  5. 資料維護

    在關系資料庫中進行資料更新操作的時候,原來的舊值會被新值替換掉。

    而HBase不存在替換操作,不會擅長舊的版本,而是生成一個新的版本,并且每生成一個新版本就會生成一個時間戳辨別新版本。直到過了設定的期限之後,系統才會在背景把它清理掉。

  6. 可伸縮性

    關系資料庫很難實作水準擴充,最多實作縱向擴充,比如增加CPU、單核變雙核、雙核變四核、增加記憶體條、增加磁盤。但縱向擴充的空間也是有限的。

    而HBase借助于分布式叢集存儲海量資料,能夠輕易的通過在叢集中增加或者減少硬體數量來實作性能的伸縮。

4.1.3HBase通路接口

Chapter4 分布式資料庫HBase
類型 使用場合
原生Java API Hadoop MapReduce作業并行批處理HBase表資料
Shell指令 HBase管理使用
Thrift Gateway方式 其他異構系統線上通路HBase表資料
REST Gateway 支援REST風格的Http API通路HBase
Pig 資料統計
資料倉庫産品Hive 以類似SQL語言的方式通路HBase

4.2HBase資料模型

4.2.1HBase資料模型概述

HBase是一個稀疏的多元度的排序的映射表。這張表的索引是四個元素:行鍵、列族、列限定符、時間戳。

Chapter4 分布式資料庫HBase

HBase中,每一個值都是未經解釋的字元串,也就是Bytes數組。

使用者在表中存儲資料時,一個行可以有一個行鍵和任意多個列。

表的水準方向由一個或多個列族組成,一個列族可以包含任意多個列,相同列族中的資料存儲在一起。

列族支援動态擴充(增加、減少等),是以無序事先定義好列的數量和類型。

HBase執行資料更新操作時,會保留舊的版本。這是因為HBase基于HDFS存儲資料,而HDFS隻支援追加不支援修改。是以HBase隻能生成一個新的版本并追加時間戳,然後根據時間戳找到新的版本。

HBase中很多資料是備援存儲的,通過犧牲空間追求更高的效率。

4.2.2基本概念

表:HBase使用表組織資料,表由若幹個行和列構成,每個列可以包含多個列族。

行:每個行由唯一的辨別符rowKey(行鍵)來辨別。

列族:列族是HBase存儲的基本單元,不同列族存儲在不同檔案中。一個HBase表被劃分成多個列族的集合,列族是基本的通路控制單元。

列限定符(列):列族中的資料通過列定位。

單元格:是具體存儲資料的地方。通過行、列族、列,就可以唯一的确定一個單元格。單元格中存儲的資料類型都是未經解釋的字元串。

時間戳:資料需要更新,新的版本會通過時間戳進行區分。是以一個單元格中有很多版本的資料儲存在系統中。

Chapter4 分布式資料庫HBase

資料坐标:在傳統關系資料庫中,隻需要通過行、列兩個次元就可以确定唯一資料(如Excel)。而HBase采用四維坐标定位,必須确定行鍵、列族、列限定符、時間戳。

Chapter4 分布式資料庫HBase

4.2.3概念視圖和實體視圖

在設計HBase 的時,在概念上和底層的存儲是有區分的。

HBase資料的概念視圖舉例如下:

在這個例子中,僅僅有一個行鍵"com.cnn.www",唯一的辨別一行。在行鍵中可能包含多個列族,在這裡第一個列族是contents、第二個列族是anchor。一個列族也可以包含多個列,在這裡t1、t2、t3對應的是contents列族。

每一行在不同的時間版本插入資料時,并不是插入所有的相關列。比如在t1時,隻在列族contents下面的html列中有資料。在t5時間戳下,隻在列族anchor下有資料,anchor:cnnsi.com=“CNN"表示的是:anchor是列族、cnnsi.com是列的名稱、存儲的内容是"CNN”。

Chapter4 分布式資料庫HBase

從上面的概念視圖中,可以看到HBase是稀疏表,很多單元是空的。然而,在底層中,HBase并不是以這種方式存儲的。

HBase資料的實體視圖舉例如下:

在底層存儲時,以列族為機關存儲,把行鍵、時間戳、列族單獨拿出來存儲。

底層實體存儲并沒有像上面一樣,存儲很多空值。

Chapter4 分布式資料庫HBase

4.2.4面向列的存儲

HBase的存儲方式和傳統的關系型資料庫的存儲方式是存在很大差別的。傳統的關系資料庫采用面向行的方式進行存儲,而HBase采用面向列的方式進行存儲。

Chapter4 分布式資料庫HBase

面向行的存儲的優點:

  1. 對于傳統的事務型操作,需要每次插入一條資料的時候,比如一條購物記錄。一次會寫入一條完整的記錄,将購物記錄的各項資訊存入資料庫。
  2. 采用面向行存儲的原因是之前我們使用的大都是OLTP(事務型操作)系統,每一次都生成一個完整的記錄。需要一次寫入完整字段。

面向行的存儲的缺點:

  1. 對于行式存儲來講,如果想分析某一列資料,為了得到這一列資料,必須先掃描資料庫中第一行,再掃描第二行。便利整個資料庫才能得到完整的列資料。
  2. 目前通常是針對某一列進行分析,使用行式存儲代價過大。
  3. 而列式存儲通常是按一個列去存儲,且每列中的資料類型通常是相似的,是以可以帶來很高的資料壓縮率。這是行式做不到的,因為行式存儲,一行中的不同字段的差别非常大,不可能達到很高的資料壓縮率。

如果事務型操作比較多 -> 使用行式存儲

如果企業以分析型應用為主 -> 使用列式存儲

HBase資料庫采用列式存儲。

4.3HBase實作原理

4.3.1HBase的功能元件

HBase包括三個最核心的功能元件:

  1. 庫函數:通常用于連結每個用戶端
  2. Master伺服器:充當管家的作用

    Master伺服器可以實作對HBase表中的分區資訊進行維護和管理。

    Master伺服器維護了一個Region伺服器清單,通過它可以知道整個叢集中有哪些Region伺服器在工作。

    Master伺服器也負責對Region進行配置設定,一個表要進行分區分成多個Region,每個Region被配置設定到哪個Region伺服器上由它決定。

    Master伺服器還負責負載均衡。

  3. 多個Region伺服器:負責存儲不同的Region

    一個大的表會被分成多個不同的Region,這個Region就由Region伺服器進行維護和管理。

    用戶端要通路資料的時候,也是直接和Region伺服器進行資料的存取(用戶端不會直接從Master處擷取資料,一般是直接獲得整個Region的位置資訊後,直接和相應的Region伺服器互動。)

    用戶端并不依賴Master擷取位置資訊,而是通過Zookeeper擷取Region位置資訊。大多數用戶端甚至從不和Master通信,減小了負載。

4.3.2表和Region

一個HBase表在起初資料量很小,隻有一個Region。但是,随着資料不斷的增加,Region會逐漸增大,增大到一定程度後,一個Region會分裂成多個新的Region。并且這種分裂過程是十分迅速的,在分開的瞬間修改資料的指向資訊即可,實際的資料還是存儲在舊的Region中,通路的時候還是通路舊的Region中的資料。一直到合并過程,把存儲檔案異步的寫到獨立的檔案之後,才會讀取新的檔案。

Chapter4 分布式資料庫HBase

在2006年之前,Region大小為100MB到200MB。但是到目前,一個Region的最佳大小配置為1GB到2GB。

注意,拆分時對于同一個Region,不會被拆分到不同的Region伺服器上去。

Chapter4 分布式資料庫HBase

4.3.3Region的定位

HBase設計了三層結構實作Region的尋址和定位,實作原理如下:

  1. 建構一個中繼資料表,假設這個中繼資料表隻有兩列。第一列是Region的id,第二列是Region伺服器的id。
  2. HBase最開始建構時有一個映射表,這個映射表被稱為.META.表(用于存儲中繼資料)。
  3. 随着Region的不斷分類,映射條目逐漸增多,使得.META.表也需要分成多個Region進行存儲。
  4. 為了記錄所有中繼資料的具體位置,還需要另外一個表——根資料表(-ROOT-表)。但注意,HBase不允許-ROOT-表進行分裂,-ROOT-表最多隻能有一個Region。
  5. -ROOT-表的位址在程式中是被寫死的,在Zookeeper檔案中記錄了-ROOT-表的位置。
Chapter4 分布式資料庫HBase

HBase的三層結構中各層次的名稱和作用:

Chapter4 分布式資料庫HBase

為了加快通路速度,.META.表的全部Region都會被儲存在記憶體中。

假設.META.表的每行(一個映射條目)在記憶體中大約占用1KB,并且每個Region限制為128MB。那麼,上面的三層結構可以儲存的使用者資料表的Region數目的計算方法是:

一個-ROOT-表最多隻能有一個Region,也就是最多隻能有128MB,按照 每行(一個映射條目)占用1KB記憶體計算,128MB空間可以容納 128MB/1KB=217行。

也就是說,一個-ROOT-表可以尋址217個.META.表的Region。

同理,每個.META.表的 Region可以尋址的使用者資料表的Region個數是

128MB/1KB=217。

最終,三層結構可以儲存的Region數目是(128MB/1KB) × (128MB/1KB)= 234個Region。這個數目遠遠超過企業的實際需求。

用戶端通路資料時的"三級尋址":為了加速尋址,用戶端會緩存位置資訊。同時,需要解決緩存失效問題(采用惰性機制,隻有發現某個緩存不能正确找到資料的時候才會更新緩存,使用三級尋址找到Region的ID再次緩存下來)。

4.4HBase運作機制

4.4.1HBase系統架構

從HBase系統架構示意圖課件,HBase的資料存儲并非直接和底層存儲打交道,而是借助于HDFS完成資料存儲的。

Chapter4 分布式資料庫HBase

1.用戶端:包含通路HBase的接口。并且為了加快通路速度,用戶端會在自己的緩存中維護已經通路過的Region位置資訊。

2.Zookeeper伺服器:實作協同管理服務。被大量用于分布式系統,提供配置維護、域名服務、分布式同步服務。在HBase中,作為管家存在,負責維護和管理整個HBase叢集,可以幫助選舉出一個Master作為叢集的總管,并保證任何時刻總有一個唯一的Master在運作,避免了Master的單點失效問題。

Chapter4 分布式資料庫HBase

3.Master(主伺服器):負責整個HBase中表及Region的管理工作,包括管理使用者對表的增删改查、對不同的Region伺服器進行負載均衡、負責調整分裂/合并後Region的分布、負責重新配置設定故障/失效的Region伺服器。

4.Region伺服器:負責使用者資料的存儲和管理。使用者讀資料的時候就是和Region伺服器互動。

4.4.2Region伺服器工作原理

每一台Region伺服器中可以存儲10~1000個Region,這些Region共用一個公用的HLog檔案。在進行存儲時,每一個Region中的每一個列族會構成一個單獨的Store,注意Store中的資料不是直接寫到底層,而是先寫入緩存MemStore中,緩存滿了之後再重新整理寫入StoreFile(在底層借助HDFS存儲,檔案格式是HFile)中去。

Chapter4 分布式資料庫HBase

使用者資料讀寫過程

1.寫資料:

  • 使用者寫入資料時,需要去被配置設定到的相應的Region伺服器上執行。
  • 首先寫入到緩存MemStore中。 為了保證資料的安全和恢複性,還要寫日志到HLog中。
  • 隻有保證HLog中的資料已經被完整的寫入磁盤後,才允許調用傳回給用戶端。

2.讀資料:

  • 讀資料時,Region伺服器也會首先通路MemStore緩存,因為最新的資料都在MemStore中,而非磁盤的StoreFile中。
  • 如果在MemStore緩存找不到,再去磁盤的StoreFile中找相關資料。

緩存的重新整理

系統會周期性的把MemStore緩存裡的内容刷寫到磁盤的StoreFile檔案中,清空緩存,并在HLog日志中寫入一個标記。

由于每次刷寫都生成一個新的StoreFile檔案,是以每個Store包含多個StoreFile檔案。

每個Region伺服器都有一個自己的HLog日志檔案(是所有Region公用的),每次啟動時都檢查該檔案,确認最近一次執行緩存重新整理操作之後是否發生新的寫入操作。如果發現更新,則先寫入MemStore,再刷寫到StoreFile,最後删除舊的HLog檔案,開始為使用者提供服務。

StoreFile的合并

由于每一次刷寫都會生成一個新的StoreFile,如果數量非常多,會影響查找速度。

當StoreFile數目達到一定程度的時候,會合并成一個大的StoreFile。

這種合并是非常耗費資源的,隻有磁盤中刷寫生成的StoreFile數量達到一定門檻值後,才會啟動合并操作。

然而,StoreFile可能會随着合并不斷增大。大到一定程度的時候又會觸發分裂操作(HBase的Region分裂就發生在這裡)。一個父Region被分裂成兩個子Region。

Chapter4 分布式資料庫HBase

4.4.3HLog工作原理

HBase通過建構一個叢集去管理資料,是典型的分布式環境,底層又是非常廉價的低端機,是以故障是難免的,并且必須采取手段應對故障。HBase中采用日志HLog保證系統恢複。

HBase為每個Region伺服器配置了公共的HLog檔案(是一種預寫式日志),使用者更新資料時必須先寫入日志,然後才能寫入MemStore緩存。直到MemStore緩存内容對應的日志已經寫入磁盤,緩存内容才能被刷寫磁盤。

ZooKeeper負責監視Region伺服器叢集,當它發現某個Region伺服器發生故障的時候,會通知Master。

Master會處理故障Region伺服器遺留的HLog檔案(包含故障Region伺服器上各個Region的日志記錄)。

由于多個Region共用一個HLog,是以需要根據每條日志記錄所屬的Region對象,對HLog資料進行拆分,分别放到相應Region對象的目錄下。然後将失效的Region重新配置設定到可用的Region伺服器中,并把與該Region對象相關的HLog日志記錄發送給相應的Region伺服器。

Region伺服器領取到配置設定給自己的Region對象以及相關的HLog記錄之後,會重新執行一遍日志記錄中的各種操作,把日志記錄中的資料寫入到MemStore緩存中,然後重新整理到磁盤的StoreFile檔案中,完成資料恢複。

一個Region伺服器中所有Region共用一個HLog日志:

優點是可以提高對表的寫操作性能。

缺點是一旦發生故障,進行恢複的時候需要進行日志拆分。

4.5HBase應用方案

4.5.1HBase實際應用中的性能優化方法

1.行鍵

HBase中按照行鍵索引資料,而行鍵按照字典序存儲。是以可以把最近可能被通路的資料放在一起,舉例如下:

如果想把時間靠近的資料都存在一起,可以考慮将時間戳作為行鍵的一部分,然而按照升序排序的話,越到後面時間戳會越來越大。考慮到長整形變量是64位,可以使用系統最大的整型值減去時間戳,讓排序順序反轉。也就是說将Long.MAX_VALUE - timestamp作為行鍵。這樣可以保證最新寫的資料可以被很快命中。

2.提升讀寫性能

如果對實時性要求比較高,想把資料放入緩存中,以提升讀寫性能。可以在建立表時,通過設定HColumnDescriptor.setInMemory選項為true,就可以把相關的表放到Region伺服器的緩存中,根據需要決定是否放入緩存。

3.最大版本

在建立表時,通過設定HColumnDescriptor.setMaxVersions(int MaxVersions),以限制最大版本數。如果僅僅想儲存最新版本的資料,将參數設定為1即可。

4.生存時間

在建立表時,通過設定HColumnDescriptor.setTimeToLive(int TimeToLive)設定表中存儲資料的生命周期,一旦超過生命周期就成為過期資料,會被系統自動删除。

比如,如果隻需要最近兩天的資料,可以設定為setTimeToLive(2 * 24 * 60 * 60)

4.5.2HBase性能檢測

有四種常用工具可以幫助進行HBase性能檢測:

1.Master-status

2.Ganglia

3.OpenTSDB

4.Ambari

Master-status:是HBase自帶的工具。通過Web界面的方式可以查詢HBase運作狀态,直接在浏覽器中輸入位址即可檢視。

Ganglia:是UC Berkeley發起的一個開源叢集監視項目,用于監控系統性能,也支援對HBase進行性能監控。

OpenTSDB:可以從大規模的叢集中擷取相關的性能參數,進行存儲索引,然後以可視化的方式提供給管理者。

Ambari:是Hadoop架構上的一個産品,作用是建立、管理、監視Hadoop的叢集。

4.5.3在HBase上建構SQL引擎

建構SQL引擎的好處:

1.易使用:目前大部分從業人員還是更了解SQL,SQL也更容易了解。

2.減少編碼:SQL語句非常簡潔,是非過程語言,可以減少代碼量。

在HBase上建構SQL引擎有兩種常用方法:

  1. Hive整合HBase

    從Hive0.6.0版本開始,已經具備了和HBase的整合功能,它們的接口互相通信就可以實作對HBase的通路。

  2. Phoenix

    Phoenix是知名的SaaS服務供應商Salesforce的産品。這個Salesforce.com公司開源了一個項目叫Phoenix,它是建構在Apache HBase之上的一個SQL中間層,開發者可以通過它在HBase上執行SQL查詢。

4.5.4建構HBase二級索引

二級索引,也稱輔助索引。在關系資料庫中,可以對學号字段建立主索引(Primary key),然後對姓名和成績字段建構多個二級索引。

然而,原生的HBase産品不支援對各個列建構相關的索引,預設隻支援對行鍵rowKey進行索引。

是以,在HBase中想通路某一行,僅有三種方式:

1.通過單個行鍵通路

2.定一個行鍵的開始點和結束點去通路區間資料

3.隻能進行全表掃描,對整個HBase表順序掃一遍

實際應用中,通常需要針對不同的列建構索引。是以,HBase0.92版本後引入了一個新特性叫做Coprocessor,用于幫助HBase建構二級索引。

一些産品包括:Hindex、HBase+Redis、HBase+solr

Coprocessor解析

利用Coprocessor,可以建構二級索引。

Coprocessor提供了兩個實作:endpoint和observer。endpoint相當于關系型資料庫的存儲過程,而observer相當于觸發器。

observer允許在記錄put前後做一些處理。是以,可以在插入資料的時候同步寫入索引表。在這種情況下,在HBase資料庫中就有主表、索引表。索引表是通過Coprocessor機制,額外開發的二級索引(可以針對其他列)

Chapter4 分布式資料庫HBase

這種建構方式的優點:非侵入性:引擎建構在HBase之上,既沒有對HBase進行任何改動,也不需要上層應用作出任何妥協。

缺點:每插入一條資料需要向索引表插入資料,耗時是雙倍的,對HBase叢集的壓力也是雙倍的。

Hindex:是華為公司使用Java開發的,專門針對HBase資料庫。支援多個表索引,也支援多個列索引,也支援基于部分列值的索引。

HBase+Redis:Redis是一種鍵值資料庫産品,能高效的管理鍵值對。由Redis資料庫在緩存中管理索引,再定期把索引更新到HBase底層資料中。避免了頻繁更新索引引起的耗時等問題。

Chapter4 分布式資料庫HBase

HBase+Solr:Solr是高性能、基于Lucene的全文搜尋伺服器。Solr建構的是其他列和行鍵rowKey之間的對應關系。通過輸入其他列中某一個值,可以快速找到這一行對應的行鍵,再根據行鍵在HBase中查找資料。

Chapter4 分布式資料庫HBase

繼續閱讀