Hbase讀寫原理

Hbase的邏輯結(jié)構(gòu)

image.png

Hbase物理存儲結(jié)構(gòu)

image.png

不同列族分別存在不同的文件夾里寞酿。

數(shù)據(jù)模型

與MySQL比較

  • MySQL: DB->Table->列->數(shù)據(jù)
  • Hbase: NameSpace->Region(一個表可能對應(yīng)多個region)->列族->數(shù)據(jù)(列+value),列也算是數(shù)據(jù)酒朵。

首先Hbase是依賴于HDFS和zookeeper的厂庇。
Zookeeper分擔(dān)了Hmaster的一部分功能,客戶端進(jìn)行DML語句的時候青灼,都是先跟ZK交互徒役。
RegionServer管理了很多的Region(表),RegionServer里面的WAL(HLog)是預(yù)寫入日志田巴,功能是防止內(nèi)存中的數(shù)據(jù)沒有來的及落盤時丟失钠糊。在Region里面管理的Store管理的是列族,Store里面有Mem Store(內(nèi)存)壹哺,F(xiàn)lush之后抄伍,刪除內(nèi)存中的數(shù)據(jù),同時寫入文件StoreFile Hfile,Hfile 其實是在DataNode里面的管宵。


image.png

寫數(shù)據(jù)流程

Hbase的讀比寫慢截珍。
Hbase命名空間下有一張元數(shù)據(jù)表meta表和namespace表。meta表里面保存了要操作的表所在的位置等元數(shù)據(jù)箩朴。
(1)首先客戶端向zk請求元數(shù)據(jù)表所在的RegionServer岗喉,zk返回給客戶端meta表所在的regionServer。
(2)然后客戶端再去對應(yīng)的RegionServer查找meta表炸庞,找到真正要操作的表所在的regionServer钱床,同時把meta表的信息緩存下來,加快后續(xù)的查詢埠居。
(3)然后客戶端再向目標(biāo)表所在的RegionServer發(fā)送put請求诞丽。先把數(shù)據(jù)寫到Hlog里面,再寫到內(nèi)存MemStore,數(shù)據(jù)會在內(nèi)存排序拐格,然后向客戶端發(fā)送ack,到這里對于客戶端來說寫數(shù)據(jù)已經(jīng)結(jié)束了刑赶。再等到MemStore的刷寫時機(jī)后捏浊,將數(shù)據(jù)刷寫到Hfile.


寫數(shù)據(jù)流程

注:meta表所在的位置信息保存在zk的meta-region-server節(jié)點上,客戶端首先就是在這個節(jié)點上差詢meta表所在的RegionServer撞叨。meta表里面的信息就是表與其對應(yīng)的RegionServer的信息


meta表里的數(shù)據(jù):stu表存在hadoop102里面

這個stu表可能不止一條金踪,因為stu表可能數(shù)據(jù)量大了之后根據(jù)RowKey進(jìn)行了切分,并且可能會在不同的機(jī)器上牵敷。


meta表中的目標(biāo)表的信息

Hbase客戶端寫數(shù)據(jù)的源碼的過程胡岔,(1)也要先獲取lock(JUC的鎖)(2)更新時間戳(服務(wù)端的時間)(3)構(gòu)建WAL(還沒有寫到HDFS)(4)操作追加到WAL日志里面,不要同步(5)寫到內(nèi)存里面(6)釋放鎖(7)同步WAL到HDFS(8)如果WAL同步失敗了枷餐,置doRollBackMemStore為true靶瘸,回滾,從內(nèi)存里刪除keys

Flush流程

image.png

不同的列族是在不同的文件夾毛肋。
MemStore刷寫時機(jī):

設(shè)置參數(shù):
image.png

全局的MemStore的容量怨咪,默認(rèn)是堆內(nèi)存的40%。這個容量值會觸發(fā)flush操作润匙,所有的MemStore都要刷寫诗眨,flush操作會阻塞讀寫操作。
會刷寫并阻塞到到MemStore大小降到它的最大容量的95%


image.png

內(nèi)存中的文件在自動刷寫之前能夠存活的最長時間孕讳,默認(rèn)1h,按最后一次操作算匠楚。過了1h還沒有到容量巍膘,則自動刷寫。
image.png

設(shè)置單個Region的MemStore的容量芋簿,如果超過這單個Region就會刷寫峡懈,默認(rèn)是128M.
image.png

WAL日志的刷寫時機(jī):
可以設(shè)置日志的大小和數(shù)量,當(dāng)達(dá)到一定數(shù)量益咬,刷寫到HDFS

Hbase讀流程

(1)從zk找meta表所在的RegionServer
(2)從上述RegionServer里的meta表里找目標(biāo)表所在的RegionServer逮诲,同時把meta表緩存,加速后面的查詢幽告。
(3)向目標(biāo)表所在的RegionServer發(fā)送get請求梅鹦。可以從block Cache冗锁,MemStore還有StoreFile里面查齐唆,具體從哪查根據(jù)時間戳,查時間戳大的冻河,具體就都查然后merge取最新箍邮。
RegionServer里面有block Cache可以緩存磁盤的數(shù)據(jù),加速查詢叨叙。如果block Cache里面有锭弊,就將緩存和MemStore的數(shù)據(jù)merge然后取最新時間戳,沒有就是把磁盤讀的和MemStore里面的合并擂错。所以hbase大多數(shù)讀要走磁盤味滞,所以讀很慢。

StoreFile合并Compaction

每次刷寫會生成新的Hfile钮呀,Hfile很小并且數(shù)量多的時候會影響查詢的速度剑鞍。所以要進(jìn)行合并。合并分為minor Compaction和major Compaction


image.png

minor Compaction將臨近的若干較小的Hfile合并成一個較大的Hfile爽醋,不會清理過期和刪除的數(shù)據(jù)蚁署,major Compaction會將一個Store里面的所有Hfile合并成一個大的Hfile,并且會清理掉過期和刪除的數(shù)據(jù)蚂四。


image.png

compaction操作需要rewrite光戈,非常消耗資源,一般在業(yè)務(wù)低峰期手動執(zhí)行遂赠。

讀寫擴(kuò)展

數(shù)據(jù)的讀寫可以不依賴Hmaster田度,只需要指定zookeeper,但是Hmaster負(fù)責(zé)region調(diào)度的元數(shù)據(jù)
但是DDL語言是要有Hmaster的

什么時候會觸發(fā)數(shù)據(jù)的刪除

Flush和major Compact
(1)flush在同一個內(nèi)存中清除過期或刪除(刪除標(biāo)記也是一行數(shù)據(jù))的數(shù)據(jù)解愤,但是如果數(shù)據(jù)不同的版本分布在不同的memStroe镇饺,就不能清除。刪除的標(biāo)記在flush之后不會被刪送讲,但在后面的major compaction會把刪除標(biāo)記刪除掉奸笤。
(2)major compaction 會清除過期或刪除的數(shù)據(jù)惋啃。

Region Split

默認(rèn)情況下,每個Table起初只有一個Region监右,隨著數(shù)據(jù)的不斷寫入边灭,Region會自動拆分,兩個子Region開始都會在一個Regionserver里面健盒,但是出于負(fù)載均衡的考慮绒瘦,Hmaster有可能會將某個Region傳給其他的RegionServer。
Split的時機(jī):
(1)當(dāng)一個Region中的某個Store下的StoreFile的總大小查過某個值扣癣,由參數(shù)hbase.hregion.max.filesize設(shè)定(默認(rèn)10g)惰帽,該Region就會按照RowKey進(jìn)行拆分。
(2)在新版本中這個值是Min(R^2*"hbase.hregion.memStore.flush.size(128M)","hbase.hregion.max.filesize"),R是當(dāng)前RegionServer中屬于該Table的Region個數(shù)父虑。分region是按照RowKey切分的该酗。這會導(dǎo)致數(shù)據(jù)傾斜,就是因為切分的閾值在變化士嚎,導(dǎo)致切分之后的region數(shù)據(jù)量不均勻呜魄,導(dǎo)致熱點的問題。所以在建表的時候要做預(yù)分區(qū)莱衩,就是用RowKey規(guī)劃好多少個region爵嗅,不讓hbase自己的切分邏輯切分。
官方建議只用一個列族笨蚁,防止不同的列族之間數(shù)據(jù)不均勻操骡,單一列族數(shù)據(jù)量增多,導(dǎo)致全局的flush赚窃,數(shù)據(jù)量小的列族也要flush,這樣會形成很多小的storeFile岔激。

Hbase API

delete操作:
(1)設(shè)置RowKey:打的刪除標(biāo)記是deleteFamily勒极,刪除多個版本
(2)設(shè)置RowKey+Family:打的標(biāo)記是deleteFamily,刪除多個版本
(3)設(shè)置RowKey+family+column:有addColumn()和addColumns().addColumn是刪除最新的版本或者刪除指定時間戳的版本虑鼎,刪除標(biāo)記是delete標(biāo)記辱匿。addColumns是刪除所有的版本或者刪除指定時間戳或之前的版本,刪除標(biāo)記是deleteColumn
Delete的操作其實也是put操作炫彩,put的是刪除的標(biāo)記匾七。

Hbase優(yōu)化

高可用

在Hbase中HMaster負(fù)責(zé)監(jiān)控HRegionServer的生命周期,均衡RegionServer的負(fù)載江兢,如果HMaster掛掉了昨忆,那個整個Hbase集群將處于不健康的狀態(tài),并且此時的工作狀態(tài)不會維持太久杉允。所以Hbase支持對HMaster的高可用配置邑贴。
在Hbase的conf目錄下新建backup-masters文件席里,vim加入備份Master,比如slave01,slave02.在把文件分發(fā)到各個slave里拢驾,然后再啟動hbase 就能實現(xiàn)HMaster的高可用了奖磁。

預(yù)分區(qū)

每一個region維護(hù)著StartRow和EndRow,如果加入的數(shù)據(jù)符合某個region維護(hù)的RowKey范圍繁疤,則該數(shù)據(jù)交給這個region維護(hù)咖为。那么依照這個原則,我們可以將數(shù)據(jù)所要投放的分區(qū)提前大致的規(guī)劃好稠腊,以提高Hbase性能躁染。
(1)手動設(shè)定預(yù)分區(qū)

create 'staff','info','other',SPLITS =>['1000','2000','3000','4000']

手動設(shè)置RowKey分了5個region


手動分區(qū)

(2)生成16進(jìn)制序列預(yù)分區(qū)

create 'staff1','info','other',{NUMREGIONS=>15,SPLITALGO=>'HexStringSplit'}
image.png

(3)按照文件中設(shè)置的規(guī)則預(yù)分區(qū)
創(chuàng)建split.txt

aaaa
bbbb
cccc
dddd

然后執(zhí)行

create 'staff2','info','other',SPLITS_FILE=>'splits.txt'

這里如果文件里面給的分區(qū)鍵不是按照順序的,hbase會先幫我們把鍵排序麻养,然后按照鍵來分區(qū)褐啡。
(4)使用JavaAPI預(yù)分區(qū)
admin的創(chuàng)建表的方法有多個重載,可以只傳表的描述鳖昌,也可以加入分區(qū)的信息备畦。admin.createTable
規(guī)劃分區(qū)要考慮未來數(shù)據(jù)量和機(jī)器的規(guī)模。雖然提前做了分區(qū)许昨,但是最后如果分區(qū)大于了10G,還是會觸發(fā)split懂盐。假設(shè)一臺機(jī)器有100G磁盤,那么預(yù)分區(qū)盡量大于10個糕档,這樣就能避免預(yù)分區(qū)之后又觸發(fā)了大于10G的split莉恼。

RowKey的設(shè)計

(1)希望數(shù)據(jù)能夠盡量均勻的分配在多個分區(qū)里面(散列性)。
(2)唯一性
(3)長度原則(生產(chǎn)環(huán)境70到100位)
常見的設(shè)計方案:
(1)生產(chǎn)隨機(jī)數(shù)速那、hash俐银、散列值
(2)字符串反轉(zhuǎn)
(3)字符串拼接

RowKey設(shè)計案例

電信項目:
一次通話的記錄:13112341233->18998768771 2018-12-12 12:12:21 568
假設(shè)分300個區(qū)
分區(qū)鍵怎么設(shè)計:
(299個鍵)
000|
001|
...
298|
RowKey的前面一般會拼上000_,001_,...,298_
這樣做的好處是,根據(jù)前三位就能知道哪個分區(qū)端仰。
(1)我們希望手機(jī)號盡量分布在不同的分區(qū)捶惜,但是相同的手機(jī)號數(shù)據(jù)集中在同一個分區(qū),這樣方便查詢某個用戶的通話信息荔烧。000_13112341233
(2)因為每個人通話的需求不同吱七,也希望把同一個人的通話記錄也分布在不同的分區(qū)里面。000_13112341233_2019-12-12
哈希取余:[(13112341234^201912).hash]%299
假設(shè)要查詢某用戶2019年2月的通話記錄鹤竭,可以用13112341234201902做startRowkey踊餐,13112341234201903做endRowKey

內(nèi)存優(yōu)化

image.png

Hbase實戰(zhàn)

微博。
1臀稚、需求
(1)微博內(nèi)容的瀏覽
(2)用戶社交:關(guān)注用戶吝岭,取關(guān)用戶
(3)拉取關(guān)注人的微博用戶
2、設(shè)計表
(1)微博內(nèi)容表Content
行鍵:用戶id+時間戳
(2)用戶關(guān)系表
因為正常情況一個用戶的粉絲和關(guān)注都不多,可以用一行存儲關(guān)注和粉絲的情況苍碟。
行鍵:用戶id
(3)初始化頁面的表(顯示關(guān)注的人的最近三條微博)


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酒觅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子微峰,更是在濱河造成了極大的恐慌舷丹,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜓肆,死亡現(xiàn)場離奇詭異颜凯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)仗扬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門症概,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人早芭,你說我怎么就攤上這事彼城。” “怎么了退个?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵募壕,是天一觀的道長。 經(jīng)常有香客問我语盈,道長舱馅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任刀荒,我火速辦了婚禮代嗤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缠借。我一直安慰自己干毅,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布泼返。 她就那樣靜靜地躺著硝逢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪符隙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天垫毙,我揣著相機(jī)與錄音霹疫,去河邊找鬼。 笑死综芥,一個胖子當(dāng)著我的面吹牛丽蝎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼屠阻,長吁一口氣:“原來是場噩夢啊……” “哼红省!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起国觉,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤吧恃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后麻诀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痕寓,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年蝇闭,在試婚紗的時候發(fā)現(xiàn)自己被綠了呻率。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡呻引,死狀恐怖礼仗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情逻悠,我是刑警寧澤元践,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站蹂风,受9級特大地震影響卢厂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惠啄,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一慎恒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧撵渡,春花似錦融柬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至节腐,卻和暖如春外盯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背翼雀。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工饱苟, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人狼渊。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓箱熬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子城须,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345