深入浅出mfc_深入浅出HBase系列(一)
前言
近期采用kylin+superset方案解決公司多維自助查詢分析的問題,大家都知道kylin將預(yù)計(jì)算的結(jié)果寫入HBase中以加快多維數(shù)據(jù)的查詢速度,所以不可避免需要對(duì)HBase進(jìn)行各種調(diào)優(yōu),調(diào)優(yōu)過程中帶著學(xué)習(xí)的目的深入研究了HBase的相關(guān)機(jī)制,想到以前非常喜歡臺(tái)灣侯捷先生的名著《深入淺出MFC》以及李維先生的《Inside VCL》,所以把這系列取名深入淺出,當(dāng)然這里主要是想記錄過程,非常粗糙,權(quán)做拋磚引吧。
言歸正傳,先講原理:
一、HBase原理解析
1、HBase的架構(gòu)設(shè)計(jì)及基本的數(shù)據(jù)結(jié)構(gòu)
1.1服務(wù)器節(jié)點(diǎn)架構(gòu)
圖1.1.1 HBase節(jié)點(diǎn)架構(gòu)1.1.1 Client
包含訪問HBase的接口,維護(hù)著一些Cache來加快對(duì)HBase的訪問,比如緩存regione的位置信息等;
1.1.2 Zookeeper
保證任何時(shí)候,集群中只有一個(gè)master;存貯所有Region的尋址入口Root Region的位置;實(shí)時(shí)監(jiān)控Region Server的狀態(tài),將Region server的上線和下線信息實(shí)時(shí)通知給Master;存儲(chǔ)Hbase的schema,包括有哪些table,每個(gè)table有哪些column family;
1.1.3 Master
主要負(fù)責(zé)Region的分配與重分配;RegionServer的負(fù)載均衡;處理Schema更新(新建表、修改表結(jié)構(gòu)等)的請(qǐng)求等;不參與HBase的讀寫數(shù)據(jù)過程;
圖1.1.3.1 HBase Master&RegionServer1.1.4 RegionServer
一個(gè)RegionServer對(duì)應(yīng)一個(gè)節(jié)點(diǎn),Regionserver是調(diào)度者,維護(hù)多個(gè)Region,處理對(duì)這些Region的IO,負(fù)責(zé)切分在運(yùn)行過程中變得過大的Region,一個(gè)Region只能屬于一個(gè)Regionserver,Regionserver可以自動(dòng)調(diào)整Region所在的服務(wù)器;底層數(shù)據(jù)是持久化在HDFS上的;
1.1.5 Client
訪問hbase上數(shù)據(jù)的過程并不需要master參與(尋址訪問zookeeper和region server,數(shù)據(jù)讀寫訪問regione server),master僅僅維護(hù)者table和region的元數(shù)據(jù)信息,負(fù)載很低;
1.2數(shù)據(jù)結(jié)構(gòu)模型
1.2.1整體結(jié)構(gòu)
數(shù)據(jù)結(jié)構(gòu)層面整體是這樣的:
圖1.2.1.1 HBase數(shù)據(jù)結(jié)構(gòu)(V1)1.2.2 Region與HFile
一個(gè)Table表會(huì)被橫向分成多個(gè)Region,一個(gè)Region只屬于一個(gè)RegionServer,一個(gè)RegionServe管理多個(gè)Region,Region邏輯結(jié)構(gòu)如下;
圖1.2.2.1 Region的邏輯結(jié)構(gòu)每個(gè)Region是一個(gè)rowkey段內(nèi)的行記錄集合,在邏輯上對(duì)應(yīng)多個(gè)Store,一個(gè)Store在邏輯上對(duì)應(yīng)一個(gè)MemStore和多個(gè)StoreFile,StoreFile對(duì)應(yīng)物理存儲(chǔ)文件HFile。
寫入Hbase的數(shù)據(jù)可能是隨機(jī)的,如果直接寫入磁盤文件可能會(huì)系性能低下,因此,引入MemStore內(nèi)存結(jié)構(gòu)來存儲(chǔ)來自客戶端的寫入或更新操作,因?yàn)槭谴鎯?chǔ)在內(nèi)存,所以直接在 MemStore 里面進(jìn)行隨機(jī)寫是非常高效的。同時(shí),存儲(chǔ)在 MemStore 里面的數(shù)據(jù)也是按照 RowKey 進(jìn)行排序的,MemStore的數(shù)據(jù)會(huì)在滿足一定參數(shù)閾值的時(shí)候觸發(fā) Flush 操作,存儲(chǔ)在 MemStore 里面的數(shù)據(jù)就直接寫到一個(gè) HFile 里面,這樣就解決了隨機(jī)寫性能低下的問題。
圖1.2.2.2 Memstore&StoreFile&Hfile的關(guān)系1.2.3 StoreFile的結(jié)構(gòu)
StoreFile具體分為幾部分(見下圖):
圖1.2.3.1 HFile中各段的指向(V1)比較重要的是Trailer這個(gè)段,其結(jié)構(gòu)見下圖:
圖1.2.3.2 Trailer具體結(jié)構(gòu)(V1)Trailer這一段長度是固定的,保存了每一段的偏移量。讀取一個(gè)HFile時(shí),會(huì)首先讀取Trailer,Trailer保存了每個(gè)段的起始位置(段的Magic Number用來做安全check),然后,Data Index會(huì)被讀取到內(nèi)存中,這樣,當(dāng)檢索某個(gè)key時(shí),不需要掃描整個(gè)HFile,而只需從內(nèi)存中找到key所在的block,通過一次磁盤io將整個(gè) block讀取到內(nèi)存中,再找到需要的key。
1.2.4 HLog
由于MemStore 是存儲(chǔ)在內(nèi)存的,所以如果對(duì)應(yīng)的 RegionServer 突然掛掉了,那么沒有 Flush 的數(shù)據(jù)就被丟失了,為了解決這個(gè)問題,HBase 引入了 HLog(WAL)(write-ahead-log)機(jī)制,所有的更新在寫入 MemStore 之前先寫到 HLog(WAL) 里面,HLog(WAL)是直接存儲(chǔ)在 HDFS 上的,但寫入時(shí)是順序?qū)?#xff0c;也就是直接Append到文件的后面,因此寫入性能非常高,通過這種機(jī)制,即使對(duì)應(yīng)的 RegionServer 掛了,但是由于 HLog(WAL)的存在,數(shù)據(jù)還是可以恢復(fù)。
HLog又叫WAL log(Write ahead log),類似mysql中的binlog,用來做災(zāi)難恢復(fù)。HLog記錄數(shù)據(jù)的所有變更,一旦數(shù)據(jù)修改,就可以從HLog中進(jìn)行恢復(fù)。每個(gè)Region Server維護(hù)一個(gè)HLog,而不是每個(gè)Region一個(gè),這樣不同region(來自不同table)的日志會(huì)混在一起,這樣做的目的是不斷追加單個(gè)文件,相對(duì)于同時(shí)寫多個(gè)文件而言,可以減少磁盤尋址次數(shù),從而提高對(duì)table的寫性能。帶來的問題是,如果一臺(tái)region server下線,為了恢復(fù)其上的region,需要將region server上的log進(jìn)行拆分,然后分發(fā)到其它region server上進(jìn)行恢復(fù)。
WAL 文件里面的數(shù)據(jù)組織形式和 HFile 里面的是完全不一樣的。WAL 文件里面包含一系列的修改,每條修改代表單個(gè) put 或 delete。這些編輯數(shù)據(jù)包含當(dāng)前修改是對(duì)應(yīng)哪個(gè) Region 的。編輯數(shù)據(jù)是按照時(shí)間編寫的,因此所有的修改都是以追加的形式寫到 WAL 文件的末尾。由于 WAL 里面的數(shù)據(jù)是按照修改時(shí)間編寫的,所以寫 WAL 文件不會(huì)發(fā)生隨機(jī)寫,這樣可以大大提高寫 WAL 的操作。
當(dāng) WAL 文件越來越大,這個(gè)文件最終是會(huì)被關(guān)閉的,然后再創(chuàng)建一個(gè)新的 active WAL 文件用于存儲(chǔ)后面的更新。這個(gè)操作稱為 rolling WAL 文件。一旦 WAL 文件發(fā)生了 Rolled,這個(gè)文件就不會(huì)再發(fā)生修改。
默認(rèn)情況下,WAL 文件的大小達(dá)到了 HDFS 塊大小的 50%(HBase 2.0.0 之前是 95%,詳見 HBASE-19148),這個(gè) WAL 文件就會(huì)發(fā)生 roll 操作。 我們可以通過 hbase.regionserver.logroll.multiplier 參數(shù)控制達(dá)到塊大小的多少百分比就發(fā)生 roll。我們也可以通過 hbase.regionserver.hlog.blocksize 參數(shù)來控制塊大小(注意,這個(gè)塊大小不是 HDFS 的塊大小)。除了文件大小能觸發(fā) rolling,HBase 也會(huì)定時(shí)去 Rolling WAL 文件,這個(gè)時(shí)間是通過 hbase.regionserver.logroll.period 參數(shù)實(shí)現(xiàn)的,默認(rèn)是一小時(shí)。這兩個(gè)策略滿足一個(gè)就可以出發(fā) WAL 的 Rolling 操作。
WAL 文件的大小對(duì)于 HBase 恢復(fù)是有影響的,因?yàn)?HBase 在使用 WAL 文件恢復(fù)數(shù)據(jù)的時(shí)候,對(duì)應(yīng)的 Region 是無法提供服務(wù)的,所以盡量保持少一些的 WAL 文件。
一個(gè) RegionServer 會(huì)包含多個(gè) Region 的,HBase 并不為每個(gè) Region 使用一個(gè) WAL,而是整個(gè) RegionServer 里面的 Regions 共用一個(gè) WAL 日志。同時(shí),只有一個(gè) WAL 文件處于 active 狀態(tài)。
WAL 在 HDFS 上的目錄命名格式如下:
/hbase/WALs/<host>,<port>,<startcode>
/hbase/WALs/192.168.1.103,16020,1542292581331
WAL 文件名稱命名格式如下:
/hbase/WALs/<host>,<port>,<startcode>/<host>%2C<port>%2C<startcode>.<timestamp>
/hbase/WALs/192.168.1.103,16020,1542292581331/192.168.1.103%2C16021%2C1547646103879.1547646379202
1.2.5 HFile V1的問題
HFile V1的問題主要是:Region Open的時(shí)候,需要加載所有的Data Block Index數(shù)據(jù),另外,第一次讀取時(shí)需要加載所有的Bloom Filter數(shù)據(jù)到內(nèi)存中。一個(gè)HFile中的Bloom Filter的數(shù)據(jù)大小可達(dá)百M(fèi)B級(jí)別,一個(gè)RegionServer啟動(dòng)時(shí)可能需要加載數(shù)GB的Data Block Index數(shù)據(jù)。這在一個(gè)大數(shù)據(jù)量的集群中,幾乎無法忍受。(測(cè)算Data Block index到底有多大,具體測(cè)算可見附錄)。
1.2.6 HFile V2的一些說明
HFile V2.0之后有了一些變化,主要變化如下兩圖:
圖1.2.6.1 HFile V2結(jié)構(gòu)圖1.2.6.2 HFile V2中各段的指向HFile V2設(shè)計(jì)的初衷是期望顯著降低RegionServer啟動(dòng)時(shí)加載HFile的時(shí)延,更希望解決一次全量加載數(shù)百M(fèi)B級(jí)別的BloomFilter數(shù)據(jù)帶來的時(shí)延過大的問題。由上面圖可以看到主要采用了對(duì)索引進(jìn)行了分層處理以解決索引數(shù)據(jù)過大的問題。
好,到此位置講清楚了HBase的基本組織架構(gòu)和數(shù)據(jù)結(jié)構(gòu),下一章我們?cè)敿?xì)講講HBase的讀寫流程,敬請(qǐng)關(guān)注探討,如果覺得有用,別忘了關(guān)注點(diǎn)贊哦!
總結(jié)
以上是生活随笔為你收集整理的深入浅出mfc_深入浅出HBase系列(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Word】如何把代码优美的插入word
- 下一篇: 【编程】位(bit)、字节(byte)和