非關系性分布式數據庫:HBase
HBase是一個分布式的、面向列的開源數據庫,該技術來源于 Fay Chang 所撰寫的Google論文“Bigtable:一個結構化數據的分布式存儲系統”。就像Bigtable利用了Google文件系統(File System)所提供的分布式數據存儲一樣,HBase在Hadoop之上提供了類似于Bigtable的能力。HBase在列上實現了Bigtable 論文提到的壓縮算法、內存操作和布隆過濾器。Base是Apache Hadoop的數據庫,能夠對大型數據提供隨機、實時的讀寫訪問。HBase的目標是存儲并處理大型的數據。HBase的表能夠作為MapReduce任 務的輸入和輸出,可以通過Java API來存取數據,也可以通過REST、Avro或者Thrift的API來訪問。HBase不同于一般的關系數據庫,它是一個適合于非結構化數據存儲的 數據庫。另一個不同的是HBase基于列的而不是基于行的模式。
HBase 不同于一般的關系數據庫,它是一個適合于非結構化數據存儲的數據庫。所謂非結構化數據存儲就是說HBase是基于列的而不是基于行的模式,這樣方便讀寫大 數據內容。HBase是介于Map Entry(key & value)和DB Row之間的一種數據存儲方式。有點類似于現在流行的Memcache,但不僅僅是簡單的一個key對應一個 value,你很可能需要存儲多個屬性的數據結構,但沒有傳統數據庫表中那么多的關聯關系,這就是所謂的松散數據。簡單來說,你在HBase中的表創建的 可以看作是一張很大的表,而這個表的屬性可以根據需求去動態增加,在HBase中沒有表與表之間關聯查詢。你只需要告訴你的數據存儲到HBase的那個 column families 就可以了,不需要指定它的具體類型:char,varchar,int,tinyint,text等等。但是你需要注意HBase中不包含事務此類的功 能。與hadoop一樣,HBase目標主要依靠橫向擴展,通過不斷增加廉價的商用服務器,來增加計算和存儲能力。HBase中的表一般有這樣的特點:
- 大:一個表可以有上億行,上百萬列
- 面向列:面向列(族)的存儲和權限控制,列(族)獨立檢索。
- 稀疏:對于為空(null)的列,并不占用存儲空間,因此,表可以設計的非常稀疏。
HBase的優點:
- 列的可以動態增加,并且列為空就不存儲數據,節省存儲空間
- HBase自動切分數據,使得數據存儲自動具有水平scalability
- HBase可以提供高并發讀寫操作的支持
HBase的缺點:
- 不能支持條件查詢,只支持按照Row key來查詢
- 暫時不能支持Master server的故障切換,當Master宕機后,整個存儲系統就會掛掉
下圖是HBase在Hadoop Ecosystem中的位置:
HBase位于結構化存儲層,圍繞HBase,各部件對HBase的支持情況:
- HDFS:高可靠的底層存儲支持
- MapReduce:高性能的計算能力
- Zookeeper:穩定服務和failover機制
- Pig&Hive:高層語言支持,便于數據統計
- Sqoop:提供RDBMS數據導入,便于傳統數據庫向HBase遷移
HBase 的數據模型
HBase以表的形式存儲數據。表有行和列組成。列劃分為若干個列族(row family)
- Row Key: Table主鍵 行鍵 Table中記錄按照Row Key排序
- Timestamp:每次對數據操作對應的時間戳,也即數據的version number
- Column Family:列簇,一個table在水平方向有一個或者多個列簇,列簇可由任意多個Column組成,列簇支持動態擴展,無須預定義數量及類型,二進制存儲,用戶需自行進行類型轉換
Row Key
與nosql數據庫們一樣,row key是用來檢索記錄的主鍵。訪問HBase table中的行,只有三種方式:
- 通過單個row key訪問
- 通過row key的range
- 全表掃描
Row key行鍵 (Row key)可以是任意字符串(最大長度是 64KB,實際應用中長度一般為 10-100bytes),在HBase內部,row key保存為字節數組。存儲時,數據按照Row key的字典序(byte order)排序存儲。設計key時,要充分排序存儲這個特性,將經常一起讀取的行存儲放到一起。(位置相關性)。需要注意的:字典序對int排序的結果 是 1,10,100,11,12,13,14,15,16,17,18,19,2,20,21,…,9,91,92,93,94,95,96,97,98,99。 要保持整形的自然序,行鍵必須用0作左填充。行的一次讀寫是原子操作 (不論一次讀寫多少列)。這個設計決策能夠使用戶很容易的理解程序在對同一個行進行并發更新操作時的行為。
列族
HBase表中的每個列,都歸屬與某個列族。列族是表的schema的一部分(而列不是),必須在使用表之前定義。列名都以列族作為前綴。例如courses:history,courses:math都屬于courses 這個列族。
訪問控制、磁盤和內存的使用統計都是在列族層面進行的。實際應用中,列族上的控制權限能幫助我們管理不同類型的應用:我們允許一些應用可以添加新的 基本數據、一些應用可以讀取基本數據并創建繼承的列族、一些應用則只允許瀏覽數據(甚至可能因為隱私的原因不能瀏覽所有數據)。
時間戳
HBase中通過row和columns確定的為一個存貯單元稱為cell。每個 cell都保存著同一份數據的多個版本。版本通過時間戳來索引。時間戳的類型是 64位整型。時間戳可以由HBase(在數據寫入時自動 )賦值,此時時間戳是精確到毫秒的當前系統時間。時間戳也可以由客戶顯式賦值。如果應用程序要避免數據版本沖突,就必須自己生成具有唯一性的時間戳。每個 cell中,不同版本的數據按照時間倒序排序,即最新的數據排在最前面。為了避免數據存在過多版本造成的的管理 (包括存貯和索引)負擔,HBase提供了兩種數據版本回收方式。一是保存數據的最后n個版本,二是保存最近一段時間內的版本(比如最近七天)。用戶可以 針對每個列族進行設置。Cell由{row key, column(=
HBase的物理存儲
HBase中的所有數據文件都存儲在Hadoop HDFS文件系統上,格式主要有兩種:
- HFile HBase中KeyValue數據的存儲格式,HFile是Hadoop的二進制格式文件,實際上StoreFile就是對HFile做了輕量級包裝,即StoreFile底層就是HFile
- HLog File,HBase中WAL(Write Ahead Log) 的存儲格式,物理上是Hadoop的Sequence File
HFile
HFile的格式為:
HFile分為六個部分:
- Data Block 段–保存表中的數據,這部分可以被壓縮
- Meta Block 段 (可選的)–保存用戶自定義的kv對,可以被壓縮。
- File Info 段–Hfile的元信息,不被壓縮,用戶也可以在這一部分添加自己的元信息。
- Data Block Index 段–Data Block的索引。每條索引的key是被索引的block的第一條記錄的key。
- Meta Block Index段 (可選的)–Meta Block的索引。
- Trailer–這一段是定長的。保存了每一段的偏移量,讀取一個HFile時,會首先讀取Trailer,Trailer保存了每個段的起始位 置(段的Magic Number用來做安全check),然后,DataBlock Index會被讀取到內存中,這樣,當檢索某個key時,不需要掃描整個HFile,而只需從內存中找到key所在的block,通過一次磁盤io將整個 block讀取到內存中,再找到需要的key。DataBlock Index采用LRU機制淘汰。
HFile文件不定長,長度固定的塊只有兩個:Trailer和FileInfo
- Trailer中指針指向其他數據塊的起始點
- File Info中記錄了文件的一些Meta信息,例如:AVG_KEY_LEN, AVG_VALUE_LEN, LAST_KEY, COMPARATOR, MAX_SEQ_ID_KEY等
HFile的Data Block,Meta Block通常采用壓縮方式存儲,壓縮之后可以大大減少網絡IO和磁盤IO,隨之而來的開銷當然是需要花費cpu進行壓縮和解壓縮。目標Hfile的壓縮支持兩種方式:Gzip,Lzo。
Data Index和Meta Index塊記錄了每個Data塊和Meta塊的起始點。Data Block是HBase I/O的基本單元,為了提高效率,HRegionServer中有基于LRU的Block Cache機制。每個Data塊的大小可以在創建一個Table的時候通過參數指定,大號的Block有利于順序Scan,小號Block利于隨機查詢。 每個Data塊除了開頭的Magic以外就是一個個KeyValue對拼接而成, Magic內容就是一些隨機數字,目的是防止數據損壞。
HFile里面的每個KeyValue對就是一個簡單的byte數組。這個byte數組里面包含了很多項,并且有固定的結構。
- KeyLength和ValueLength:兩個固定的長度,分別代表Key和Value的長度
- Key部分:Row Length是固定長度的數值,表示RowKey的長度,Row 就是RowKey,Column Family Length是固定長度的數值,表示Family的長度,接著就是Column Family,再接著是Qualifier,然后是兩個固定長度的數值,表示Time Stamp和Key Type(Put/Delete)
- Value部分沒有這么復雜的結構,就是純粹的二進制數據
HLog File
HLog文件就是一個普通的Hadoop Sequence File,Sequence File 的Key是HLogKey對象,HLogKey中記錄了寫入數據的歸屬信息,除了table和region名字外,同時還包括 sequence number和timestamp,timestamp是“寫入時間”,sequence number的起始值為0,或者是最近一次存入文件系統中sequence number。HLog Sequece File的Value是HBase的KeyValue對象,即對應HFile中的KeyValue。
HBase 的系統架構
Client
包含訪問HBase的接口,client維護著一些cache來加快對HBase的訪問,比如regione的位置信息。
- 使用HBase RPC機制與HMaster和HRegionServer進行通信
- Client與HMaster進行通信進行管理類操作
- Client與HRegionServer進行數據讀寫類操作
Zookeeper
- 保證任何時候,集群中只有一個master,避免HMaster單點問題
- 存貯所有Region的尋址入口。
- 實時監控Region Server的狀態,將Region server的上線和下線信息實時通知給Master,HRegionServer把自己以Ephedral方式注冊到Zookeeper中,HMaster隨時感知各個HRegionServer的健康狀況
- 存儲HBase的schema,包括有哪些table,每個table有哪些column family,Zookeeper Quorum存儲-ROOT-表地址、HMaster地址
HMaster
HMaster沒有單點問題,HBase中可以啟動多個HMaster,通過Zookeeper的Master Election機制保證總有一個Master在運行,主要負責Table和Region的管理工作:
- 管理用戶對表的增刪改查操作
- 管理HRegionServer的負載均衡,調整Region分布
- Region Split后,負責新Region的分布,發現失效的region server并重新分配其上的region。
- 在HRegionServer停機后,負責失效HRegionServer上Region遷移
- 負責GFS上的垃圾文件回收
HRegionServer
HBase中最核心的模塊,主要負責響應用戶I/O請求,向HDFS文件系統中讀寫數據
- HRegionServer管理一些列HRegion對象
- 每個HRegion對應Table中一個Region,HRegion由多個HStore組成
- 每個HStore對應Table中一個Column Family的存儲
- Column Family就是一個集中的存儲單元,故將具有相同IO特性的Column放在一個Column Family會更高效
- HRegionServer負責切分在運行過程中變得過大的region
可以看到,client訪問HBase上數據的過程并不需要HMaster參與(尋址訪問zookeeper和HRegionServer,數據讀寫訪問HRegioneServer),HMaster僅僅維護者table和region的元數據信息,負載很低。
HStore
HBase存儲的核心。由MemStore和StoreFile組成。MemStore是Sorted Memory Buffer。用戶寫入數據的流程:
Client寫入 -> 存入MemStore,一直到MemStore滿 -> Flush成一個StoreFile,直至增長到一定閾值 -> 出發Compact合并操作 -> 多個StoreFile合并成一個StoreFile,同時進行版本合并和數據刪除 -> 當StoreFiles Compact后,逐步形成越來越大的StoreFile -> 單個StoreFile大小超過一定閾值后,觸發Split操作,把當前Region Split成2個Region,Region會下線,新Split出的2個孩子Region會被HMaster分配到相應的HRegionServer 上,使得原先1個Region的壓力得以分流到2個Region上。由此過程可知,HBase只是增加數據,有所得更新和刪除操作,都是在Compact 階段做的,所以,用戶寫操作只需要進入到內存即可立即返回,從而保證I/O高性能。
HLog
在分布式系統環境中,無法避免系統出錯或者宕機,一旦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,完成數據恢復。
HBase的訪問
- Native Java API,最常規和高效的訪問方式,適合Hadoop MapReduce Job并行批處理HBase表數據
- HBase Shell,HBase的命令行工具,最簡單的接口,適合HBase管理使用
- Thrift Gateway,利用Thrift序列化技術,支持C++,PHP,Python等多種語言,適合其他異構系統在線訪問HBase表數據
- REST Gateway,支持REST 風格的Http API訪問HBase, 解除了語言限制
- Pig,可以使用Pig Latin流式編程語言來操作HBase中的數據,和Hive類似,本質最終也是編譯成MapReduce Job來處理HBase表數據,適合做數據統計
- Hive,當前Hive的Release版本尚沒有加入對HBase的支持,但在下一個版本Hive 0.7.0中將會支持HBase,可以使用類似SQL語言來訪問HBase
參考鏈接:
- 官網:http://HBase.apache.org/
- Hadoop wiki:http://wiki.apache.org/hadoop/HBase
</div> 引用地址:http://www.biaodianfu.com/hbase.html