? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Hbase寫入性能優(yōu)化
背景
??? HBase是一個(gè)nosql數(shù)據(jù)庫咽笼,既然是數(shù)據(jù)庫忙菠,就會(huì)涉及到增刪改查阶女,而且hbase一般是海量數(shù)據(jù)場(chǎng)景下使用颖系,使用的不好就會(huì)出現(xiàn)性能問題士骤,這里我將自己總結(jié)的一些經(jīng)驗(yàn)分享給大家科雳,僅供參考根蟹。
1.數(shù)據(jù)格式
??? io是影響性能的主要方面,數(shù)據(jù)要經(jīng)過client提交給server端糟秘,然后再持久化到磁盤简逮,數(shù)據(jù)本身越小性能越高。
??? hbase可以通過rowkey快速查詢蚌堵,也可以通過filter進(jìn)行過濾搜索(不建議使用买决,性能很差),其他不需要查詢的數(shù)據(jù)可以盡可能的減小吼畏,比如將其他數(shù)據(jù)進(jìn)行壓縮(同時(shí)需考慮解壓縮的性能開銷)督赤,一般我們用protobuf進(jìn)行編碼后再進(jìn)行存儲(chǔ)(編碼后會(huì)不方便查看,但比存json性能高泻蚊,反序列化性能也比json好)躲舌;另外,在定義cloumn時(shí)性雄,也盡可能短没卸,不要使用超長(zhǎng)字符串定義屬性。
2.啟用表壓縮
??? 啟用表壓縮可以很大程度節(jié)約磁盤秒旋,一般采用LZO或者snappy進(jìn)行壓縮约计,如果是json數(shù)據(jù),壓縮效率可以達(dá)到90%迁筛。
3.啟用分表策略?
??? 超大表在使用時(shí)會(huì)存在諸多不便煤蚌,region非常多,不按rowkey的數(shù)據(jù)訪問性能極差细卧,一些數(shù)據(jù)導(dǎo)出功能基本不可用尉桩,數(shù)據(jù)遷移要命等都是致命問題。
?? hbase不像elasticsearch天生就支持分表贪庙,因此需要自己定義分表策略蜘犁,可以根據(jù)數(shù)據(jù)的規(guī)模和使用途徑,按業(yè)務(wù)類型或者年止邮,月这橙,日等進(jìn)行分表奏窑,分表會(huì)帶來幾個(gè)問題:
(1)無法知道某個(gè)用戶(假設(shè)存的是用戶數(shù)據(jù))是否產(chǎn)生過數(shù)據(jù),因?yàn)榉植荚诤芏啾砝镂隽担@個(gè)時(shí)候如果要查詢數(shù)據(jù)良哲,需要定義查詢范圍,比如最近一個(gè)月或者6個(gè)月助隧。
(2)如果想查詢某個(gè)用戶最后一次上報(bào)數(shù)據(jù)筑凫,需要通過視圖,快照的方式彌補(bǔ)并村。
(3)由于分表之后會(huì)不斷創(chuàng)建新表巍实,需要注意寫熱點(diǎn)問題。
但分表的好處也不少:
(1)方便做數(shù)據(jù)老化哩牍,可以按天或者按月做數(shù)據(jù)刪除或者歸檔到磁帶棚潦。
(2)分表之后,新表的region相對(duì)要少的多膝昆,數(shù)據(jù)量也少的多丸边,再做數(shù)據(jù)掃描時(shí)效率要高。
(3)數(shù)據(jù)遷移和備份的效率要高荚孵,可以對(duì)單個(gè)表做遷移和備份妹窖。
4.啟用建表預(yù)分區(qū)
??? hbase建表是默認(rèn)只有一個(gè)region,也就是說所有的數(shù)據(jù)都會(huì)往一個(gè)region里面寫收叶,當(dāng)然可以通過region拆分策略分成多個(gè)region骄呼,但具體多少region才會(huì)匹配當(dāng)前服務(wù)器的能力?再加上如果啟用了分表策略判没,每次新建表的時(shí)候都會(huì)出現(xiàn)寫熱點(diǎn)蜓萄,這個(gè)時(shí)候會(huì)是致命的。
??? region預(yù)分區(qū)就是提前創(chuàng)建多個(gè)region澄峰,每個(gè)region有startkey和endkey嫉沽,不同的數(shù)據(jù)根據(jù)自己生成的rowkey會(huì)落入不同的region。具體分多少個(gè)region俏竞,可以根據(jù)集群的數(shù)量耻蛇,數(shù)據(jù)的并發(fā)等來決定,預(yù)分的region數(shù)不代表將來總的region數(shù)胞此,在預(yù)分的region達(dá)到region拆分的策略后還會(huì)進(jìn)行自動(dòng)拆分。
5.多線程寫入
??? 多線程寫入跃捣,一是可以充分利用client端物理資源漱牵,避免客戶端的邏輯處理,導(dǎo)致寫入性能卡在客戶端疚漆;二是可以快速寫滿buffer酣胀,快速的刷寫磁盤刁赦,一般我們采用線程池進(jìn)行寫操作,但同時(shí)要注意線程隊(duì)列的控制闻镶,避免OOM甚脉,對(duì)于客戶端的內(nèi)存容量,也需要適當(dāng)調(diào)高一些铆农。
6.批量異步提交
?? hbase1.x之后牺氨,有新的api支持異步提交,通過BufferedMutator API墩剖,每次提交List<Put>的數(shù)據(jù)猴凹。一般我們會(huì)結(jié)合kafka進(jìn)行實(shí)時(shí)數(shù)據(jù)存儲(chǔ),通過kafka的批量拉取特性岭皂,批量提交hbase郊霎。
7.hbase日志文件寫入(WAL)
????? WAL又可以理解HLOG操作,是保證數(shù)據(jù)可靠性的重要舉措爷绘,HLOG存儲(chǔ)在hdfs上书劝,當(dāng)出現(xiàn)宕機(jī)或者regionserver掛掉等場(chǎng)景,數(shù)據(jù)可以從hlog恢復(fù)土至。
???? WAL分異步和同步购对,也可以關(guān)閉,hbase默認(rèn)是同步寫hlog毙籽,為了提升性能洞斯,我們可以改為異步寫hlog或者不寫hlog(需要評(píng)估數(shù)據(jù)的重要性,短暫的少量數(shù)據(jù)丟失是否可以容忍)坑赡,WAL有以下幾種策略烙如。
SKIP_WAL:只寫緩存,不寫HLog日志毅否。這種方式因?yàn)橹粚憙?nèi)存亚铁,因此可以極大的提升寫入性能,但是數(shù)據(jù)有丟失的風(fēng)險(xiǎn)螟加。在實(shí)際應(yīng)用過程中并不建議設(shè)置此等級(jí)徘溢,除非確認(rèn)不要求數(shù)據(jù)的可靠性。
ASYNC_WAL:異步將數(shù)據(jù)寫入HLog日志中捆探。
SYNC_WAL:同步將數(shù)據(jù)寫入日志文件中然爆,需要注意的是數(shù)據(jù)只是被寫入文件系統(tǒng)中,并沒有真正落盤黍图,默認(rèn)曾雕。
FSYNC_WAL:同步將數(shù)據(jù)寫入日志文件并強(qiáng)制落盤。最嚴(yán)格的日志寫入等級(jí)助被,可以保證數(shù)據(jù)不會(huì)丟失剖张,但是性能相對(duì)比較差切诀。
同樣,除了在創(chuàng)建表的時(shí)候直接設(shè)置WAL存儲(chǔ)級(jí)別搔弄,也可以通過客戶端設(shè)置WAL持久化等級(jí)幅虑,代碼:
put.setDurability(Durability.SYNC_WAL);
8.關(guān)于Compaction
??? hbase默認(rèn)是自動(dòng)進(jìn)行Compaction,即hfile的自動(dòng)合并操作顾犹,合并會(huì)帶來較大的資源開銷倒庵,因此我們需要合理的Compaction策略,一個(gè)是Compaction文件數(shù)量的合理設(shè)置蹦渣,另一個(gè)是選擇凌晨等數(shù)據(jù)寫入較少的時(shí)候Compaction哄芜,需要采用手動(dòng)Compaction,禁用自動(dòng)Compaction柬唯。
???