【2022持续更新】大数据最全知识点整理-HBase篇
大數(shù)據(jù)最全知識點整理-HBase篇
- 基礎(chǔ)問題:
- 1、Hbase是什么
- 2、Hbase架構(gòu)
- 3、Hbase數(shù)據(jù)模型
- 4、Hbase和hive的區(qū)別
- 5、Hbase特點
- 6、數(shù)據(jù)同樣存在HDFS,為什么HBase支持在線查詢,且效率比Hive快很多
- 7、Hbase適用場景
- 8、RowKey的設(shè)計原則
- 9、HBase中scan和get的功能以及實現(xiàn)的異同?
- 10、Scan的setCache和setBatch
- setCache
- setBatch
- 11、HBase 寫流程
- 12、HBase 讀流程
- 13、HBase中Zookeeper的作用
- 14、StoreFile(HFile)合并
- 作用
- minor(小合并)
- major(大合并)
- 15、Hbase協(xié)處理器
- observer
- Endpoint
- 協(xié)處理加載方式
- 16、WAL機(jī)制
- 17、Memstore
- 主要作用:
- 相關(guān)配置
- Memstore Flush
- 18、BloomFilter
- 19、BlockCache讀緩存
- LRUBlock Cache:
- SlabCache
- Bucket Cache
- 組合模式
- BlockCache 壓縮
- 20、Region拆分
- 拆分流程
- 自動拆分
- 手動拆分
- 21、Region合并
- 合并過程
- Merger類手動合并
- 熱合并
- 22、Region 負(fù)載均衡
- 23、Region預(yù)分區(qū)
- 24、一張表中定義多少個 Column Family 最合適
- 25、為什么不建議在 HBase 中使用過多的列族
- 26、直接將時間戳作為行健,在寫入單個region時會發(fā)生熱點問題,為什么
- 27、HBase中region太小和region太大的影響
- 28、每天百億數(shù)據(jù)如何寫入Hbase
- 29、HBase集群安裝注意事項?
- 30、Hbase數(shù)據(jù)熱點問題
- 31、HBase宕機(jī)恢復(fù)流程
- Master 宕機(jī)恢復(fù)
- regionServer宕機(jī)恢復(fù)
- 32、HBase性能優(yōu)化
- HDFS調(diào)優(yōu)
- 集群性能優(yōu)化
- 表層面優(yōu)化
- 讀優(yōu)化
- 寫優(yōu)化
基礎(chǔ)問題:
1、Hbase是什么
深入閱讀:可能是最易懂的Hbase架構(gòu)原理解析
2、Hbase架構(gòu)
Hbase架構(gòu)圖:
Zookeeper: Master 的高可用、RegionServer 的監(jiān)控、元數(shù)據(jù)的入口以及集群配置的維護(hù)等
HDFS: 提供底層數(shù)據(jù)支撐
Master
1、監(jiān)控RegionServer,進(jìn)行負(fù)載均衡
2、RegionServer故障轉(zhuǎn)移
3、處理元數(shù)據(jù)變更
4、處理region的分配或分裂
5、處理增刪改查請求
RegionServer
1.負(fù)責(zé)存儲HBase的實際數(shù)據(jù)
2.管理分配給它的Region
3.刷新緩存到HDFS
4.維護(hù)Hlog
5.執(zhí)行壓縮
6.負(fù)責(zé)處理Region分片
Region: 實際存儲數(shù)據(jù),HBase表會根據(jù)RowKey值被切分成不同的region存儲在RegionServer中,在一個RegionServer中可以有多個不同的region
Hlog: 預(yù)寫日志,用于記錄HBase的修改記錄,寫數(shù)據(jù)時,數(shù)據(jù)會首先寫入內(nèi)存經(jīng)MemStore排序后才能刷寫到StoreFile,有可能引起數(shù)據(jù)丟失,為了解決這個問題,數(shù)據(jù)會先寫入Hlog,然后再寫入內(nèi)存。在系統(tǒng)故障時,數(shù)據(jù)可以Hlog重建。
Store: StoreFile存儲在Store中,一個Store對應(yīng)HBase表中的一個列族。
MemStore: 寫緩存,由于StoreFile中的數(shù)據(jù)要求是有序的,所以數(shù)據(jù)是先存儲在MemStore中,排好序后,等到達(dá)刷寫時機(jī)才會刷寫到StoreFile,每次刷寫都會形成一個新的StoreFile。StoreFile過多會影響性能,此時可進(jìn)行compact操作
StoreFile: 這是在磁盤上保存原始數(shù)據(jù)的實際的物理文件,是實際的存儲文件。StoreFile是以Hfile的形式存儲在HDFS的。每個 Store 會有一個或多個StoreFile,數(shù)據(jù)在每個 StoreFile 中都是有序的(按照Rowkey的字典順序排序)。
3、Hbase數(shù)據(jù)模型
數(shù)據(jù)模型圖:
物理模型圖:
- Name Space
命名空間,類似于關(guān)系型數(shù)據(jù)庫的 DatabBase 概念,每個命名空間下有多個表。HBase有兩個自帶的命名空間,分別是 hbase 和 default,hbase 中存放的是 HBase 內(nèi)置的表,default 表是用戶默認(rèn)使用的命名空間。 - Row
HBase 表中的每行數(shù)據(jù)都由一個 RowKey 和多個 Column(列)組成,數(shù)據(jù)是按照 RowKey的字典順序存儲的,并且查詢數(shù)據(jù)時只能根據(jù) RowKey 進(jìn)行檢索,所以 RowKey 的設(shè)計十分重要。 - Column
HBase 表中的每行數(shù)據(jù)都由一個 RowKey 和多個 Column(列)組成,數(shù)據(jù)是按照 RowKey的字典順序存儲的,并且查詢數(shù)據(jù)時只能根據(jù) RowKey 進(jìn)行檢索,所以 RowKey 的設(shè)計十分重要。 - Time Stamp
用于標(biāo)識數(shù)據(jù)的不同版本(version),每條數(shù)據(jù)寫入時,如果不指定時間戳,系統(tǒng)會自動為其加上該字段,其值為寫入 HBase 的時間。 - Cell
HBase 中通過 row 和 columns 確定的為一個存貯單元稱為 cell。
由{rowkey, 列族:列, time Stamp} 唯一確定的單元。cell 中的數(shù)據(jù)是沒有類型的,全部是字節(jié)碼形式存貯(byte[]數(shù)組)。
4、Hbase和hive的區(qū)別
Hbase和Hive在大數(shù)據(jù)架構(gòu)中處在不同位置,Hbase主要解決實時數(shù)據(jù)查詢問題,Hive主要解決海量數(shù)據(jù)處理和計算問題,一般是配合使用。
Hbase: Hadoop database 的簡稱,也就是基于Hadoop數(shù)據(jù)庫,是一種NoSQL數(shù)據(jù)庫,主要適用于海量明細(xì)數(shù)據(jù)(十億、百億)的隨機(jī)實時查詢,如日志明細(xì)、交易清單、軌跡行為等。
Hive:Hive是Hadoop數(shù)據(jù)倉庫,嚴(yán)格來說,不是數(shù)據(jù)庫,主要是讓開發(fā)人員能夠通過SQL來計算和處理HDFS上的結(jié)構(gòu)化數(shù)據(jù),適用于離線的批量數(shù)據(jù)計算。
深入閱讀:一篇文章讓你了解Hive和HBase的區(qū)別
5、Hbase特點
張表中不同的行可以有截然不同的列;
格插入時的時間戳;
深入閱讀:可能是最易懂的Hbase架構(gòu)原理解析
6、數(shù)據(jù)同樣存在HDFS,為什么HBase支持在線查詢,且效率比Hive快很多
1、KV存儲,rowkey查詢,
2、blockCache讀緩存
3、數(shù)據(jù)存儲按照rowkey字典排序,使用插值查找
4、布隆過濾器改進(jìn)查找次數(shù)
7、Hbase適用場景
8、RowKey的設(shè)計原則
rowkey在設(shè)計上保證其唯一性。rowkey是按照字典順序排序存儲的,因此,設(shè)計rowkey的時候,要充分利用這個排序的特點,將經(jīng)常讀取的數(shù)據(jù)存儲到一塊,將最近可能會被訪問的數(shù)據(jù)放到一塊。
rowkey是一個二進(jìn)制碼流,可以是任意字符串,最大長度 64kb ,實際應(yīng)用中一般為10-100bytes,以byte[] 形式保存,一般設(shè)計成定長。建議越短越好,不要超過16個字節(jié),原因如下:數(shù)據(jù)的持久化文件HFile中是按照KeyValue存儲的,如果rowkey過長,比如超過100字節(jié),1000w行數(shù)據(jù),光rowkey就要占用100*1000w=10億個字節(jié),將近1G數(shù)據(jù),這樣會極大影響HFile的存儲效率;MemStore將緩存部分?jǐn)?shù)據(jù)到內(nèi)存,如果rowkey字段過長,內(nèi)存的有效利用率就會降低,系統(tǒng)不能緩存更多的數(shù)據(jù),這樣會降低檢索效率。目前操作系統(tǒng)都是64位系統(tǒng),內(nèi)存8字節(jié)對齊,控制在16個字節(jié),8字節(jié)的整數(shù)倍利用了操作系統(tǒng)的最佳特性。
如果rowkey按照時間戳的方式遞增,不要將時間放在二進(jìn)制碼的前面,建議將rowkey的高位作為散列字段,由程序隨機(jī)生成,低位放時間字段,這樣將提高數(shù)據(jù)均衡分布在每個RegionServer,以實現(xiàn)負(fù)載均衡的幾率。如果沒有散列字段,首字段直接是時間信息,所有的數(shù)據(jù)都會集中在一個RegionServer上,這樣在數(shù)據(jù)檢索的時候負(fù)載會集中在個別的RegionServer上,造成熱點問題,會降低查詢效率。
4)就近原則
rowkey是按照字典序存儲,設(shè)計rowkey時可以將經(jīng)常一起讀取的數(shù)據(jù)rowkey相鄰,在物理存儲時可以落在同一個region中,避免讀寫多個Region。
深入閱讀:HBase之rowkey設(shè)計原則和方法
9、HBase中scan和get的功能以及實現(xiàn)的異同?
scan 方法:按指定的條件獲取一批記錄
- setCaching 與 setBatch 方法提高速度(以空間換時間)。
- setStartRow 與 setEndRow 來限定范圍([start, end]start 是閉區(qū)間, end 是開區(qū)間)。范圍越小,性能越高。
- setFilter方法添加過濾器,這也是分頁、多條件查詢的基礎(chǔ)。
get方法:按指定RowKey 獲取唯一一條記錄。Get 的方法處理分兩種:
- 設(shè)置了 ClosestRowBefore 和沒有設(shè)置的 rowlock,主要是用來保證行的事務(wù)性,即每個 get 是以一個 row 來標(biāo)記的,一個 row 中可以有很多 family 和 column。
- 獲取當(dāng)前rowkey下指定version的數(shù)據(jù)。
10、Scan的setCache和setBatch
setCache
- 在默認(rèn)情況下,如果你需要從hbase中查詢數(shù)據(jù),在獲取結(jié)果ResultScanner時,hbase會在你每次調(diào)用ResultScanner.next()操作時對返回的每個Row執(zhí)行一次RPC操作。
- 即使你使用ResultScanner.next(int nbRows)時也只是在客戶端循環(huán)調(diào)用RsultScanner.next()操作,你可以理解為hbase將執(zhí)行查詢請求以迭代器的模式設(shè)計,在執(zhí)行next()操作時才會真正的執(zhí)行查詢操作,而對每個Row都會執(zhí)行一次RPC操作。
- 因此顯而易見的就會想如果我對多個Row返回查詢結(jié)果才執(zhí)行一次RPC調(diào)用,那么就會減少實際的通訊開銷。
- 這個就是hbase配置屬性“hbase.client.scanner.caching”的由來,設(shè)置cache可以在hbase配置文件中顯示靜態(tài)的配置,也可以在程序動態(tài)的設(shè)置。
- cache值得設(shè)置并不是越大越好,需要做一個平衡。
- cache的值越大,則查詢的性能就越高,但是與此同時,每一次調(diào)用next()操作都需要花費更長的時間,因為獲取的數(shù)據(jù)更多并且數(shù)據(jù)量大了傳輸?shù)娇蛻舳诵枰臅r間就越長,一旦你超過了maximum heap the client process 擁有的值,就會報outofmemoryException異常。
- 當(dāng)傳輸rows數(shù)據(jù)到客戶端的時候,如果花費時間過長,則會拋出ScannerTimeOutException異常。
setBatch
- 在cache的情況下,我們一般討論的是相對比較小的row,那么如果一個Row特別大的時候應(yīng)該怎么處理呢?要知道cache的值增加,那么在client process 占用的內(nèi)存就會隨著row的增大而增大。
- 在HBase中同樣為解決這種情況提供了類似的操作:Batch。
- 可以這么理解,cache是面向行的優(yōu)化處理,batch是面向列的優(yōu)化處理。
- 它用來控制每次調(diào)用next()操作時會返回多少列,比如你設(shè)置setBatch(5),那么每一個Result實例就會返回5列,如果你的列數(shù)為17的話,那么就會獲得四個Result實例,分別含有5,5,5,2個列。
11、HBase 寫流程
① Client 先訪問 zookeeper,找到 Meta 表,并獲取 Meta 表元數(shù)據(jù)。
② 確定當(dāng)前將要寫入的數(shù)據(jù)所對應(yīng)的 Region 和 RegionServer 服務(wù)器。
③ Client 向該 RegionServer 服務(wù)器發(fā)起寫入數(shù)據(jù)請求,然后 RegionServer 收到請求
并響應(yīng)。
④ Client 先把數(shù)據(jù)寫入到 HLog,以防止數(shù)據(jù)丟失。
⑤ 然后將數(shù)據(jù)寫入到 Memstore,在memstore中會對 rowkey進(jìn)行排序。
⑥ 如果 HLog 和 Memstore 均寫入成功,則這條數(shù)據(jù)寫入成功
⑦ 如果 Memstore 達(dá)到閾值,會把 Memstore 中的數(shù)據(jù) flush 到 Storefile 中。
⑧ 當(dāng) Storefile 越來越多,會觸發(fā) Compact 合并操作,把過多的 Storefile 合并成一個大
的 Storefile。
⑨ 當(dāng) Storefile 越來越大,Region 也會越來越大,達(dá)到閾值后,會觸發(fā) Split 操作,將
Region 一分為二。
12、HBase 讀流程
① RegionServer 保存著 meta 表以及表數(shù)據(jù),要訪問表數(shù)據(jù),首先 Client 先去訪問zookeeper,從 zookeeper 里面獲取 meta 表所在的位置信息,即找到這個 meta 表在哪個RegionServer 上保存著。
② 接著 Client 通過剛才獲取到的 RegionServer 的 IP 來訪問 Meta 表所在的RegionServer,從而讀取到 Meta,進(jìn)而獲取到 Meta 表中存放的元數(shù)據(jù)。
③ Client 通過元數(shù)據(jù)中存儲的信息,訪問對應(yīng)的 RegionServer,然后掃描所在RegionServer 的 Memstore 和 Storefile 來查詢數(shù)據(jù)。
④ 最后 RegionServer 把查詢到的數(shù)據(jù)響應(yīng)給 Client。
深入閱讀:Hbase的數(shù)據(jù)讀寫流程
13、HBase中Zookeeper的作用
14、StoreFile(HFile)合并
在HBase中,每當(dāng)memstore的數(shù)據(jù)flush到磁盤后,就形成一個storefile,當(dāng)storefile的數(shù)量越來越大時,會嚴(yán)重影響HBase的讀性能 ,HBase內(nèi)部的compact處理流程是為了解決MemStore Flush之后,storefile數(shù)太多,導(dǎo)致讀數(shù)據(jù)性能大大下降的一種自我調(diào)節(jié)手段,它會將文件按照策略進(jìn)行合并,提升HBase的數(shù)據(jù)讀性能。
作用
HBase中實現(xiàn)了兩種compaction的方式:
minor(小合并)
Minor操作只用來做部分文件的合并操作以及超過生存時間TTL的數(shù)據(jù),刪除標(biāo)記數(shù)據(jù)、多版本數(shù)據(jù)不進(jìn)行清除。
觸發(fā)條件:
把所有的文件都遍歷一遍之后每一個文件都去考慮。符合條件而進(jìn)入待合并列表的文件由新的條件判斷:
該文件 < (所有文件大小總和 - 該文件大小) * hbase.store.compaction.ratio比例因子。
major(大合并)
Major操作是對Region下的Store下的所有StoreFile執(zhí)行合并操作,順序重寫全部數(shù)據(jù),重寫過程中會略過做了刪除標(biāo)記的數(shù)據(jù),最終合并出一個HFile文件,并將原來的小文件刪除。會占用大量IO資源。
觸發(fā)條件:
Major是Minor升級而來的。如果本次Minor Compaction包含所有文件,且達(dá)到了足夠的時間間隔,則會被升級為Major Compaction。判斷時間間隔根據(jù)以下兩個配置項:
hbase.hregion.majorcompaction:major Compaction發(fā)生的周期,單位是毫秒,默認(rèn)值是7天。
hbase.hregion.majorcompaction.jitter majorCompaction:周期抖動參數(shù),0~1.0的一個指數(shù)。調(diào)整這個參數(shù)可以讓Major Compaction的發(fā)生時間更靈活,默認(rèn)值是0.5。
雖然有以上機(jī)制控制Major Compaction的發(fā)生時機(jī),但是由于Major
Compaction時對系統(tǒng)的壓力還是很大的,所以建議關(guān)閉自動Major Compaction,采用手動觸發(fā)的方式。
合并流程
獲取需要合并的HFile列表。
由列表創(chuàng)建出StoreFileScanner。HRegion會創(chuàng)建出一個Scanner,用這個Scanner來讀取本次要合并 的所有StoreFile上的數(shù)據(jù)。
把數(shù)據(jù)從這些HFile中讀出,并放到tmp目錄(臨時文件 夾)。
HBase會在臨時目錄中創(chuàng)建新的HFile,并使用之前建立的Scanner 從舊HFile上讀取數(shù)據(jù),放入新HFile。以下兩種數(shù)據(jù)不會被讀取出來:
1)如果數(shù)據(jù)過期了(達(dá)到TTL所規(guī)定的時間),那么這些數(shù)據(jù)不會 被讀取出來。
2)如果是majorCompaction,那么數(shù)據(jù)帶了墓碑標(biāo)記也不會被讀取 出來。
用合并后的HFile來替換合并前的那些HFile。
最后用臨時文件夾內(nèi)合并后的新HFile來替換掉之前的那些HFile文 件。過期的數(shù)據(jù)由于沒有被讀取出來,所以就永遠(yuǎn)地消失了。如果本次 合并是Major Compaction,那么帶有墓碑標(biāo)記的文件也因為沒有被讀取 出來,就真正地被刪除掉了。
15、Hbase協(xié)處理器
Hbase 作為列族數(shù)據(jù)庫最經(jīng)常被人詬病的特性包括:無法輕易建立“二級索引”,難以執(zhí)行求和、計數(shù)、排序等操作。比如,在0.92版本前,統(tǒng)計總行數(shù)需要使用Counter方法,執(zhí)行一次MapReduce Job才能得到。雖然 HBase 在數(shù)據(jù)存儲層中集成 了 MapReduce,能夠有效用于數(shù)據(jù)表的分布式計算。然而在很多情況下,做一些簡單的相加或者聚合計算的時候,如果直接將計算過程放置在regionServer端,能夠減少通訊開銷,從而獲得很好的性能提升。于是,HBase在0.92之后引入了協(xié)處理器(coprocessors),能夠輕易建立二次索引、復(fù)雜過濾器、求和、計數(shù)以及訪問控制等。
協(xié)處理器包括observer和endpoint
observer
類似于傳統(tǒng)數(shù)據(jù)庫中的觸發(fā)器,當(dāng)數(shù)據(jù)寫入的時候會調(diào)用此類協(xié)處理器中的邏輯。主要的作用是當(dāng)執(zhí)行被監(jiān)聽的一個操作的時候,可以觸發(fā)另一個我們需要的操作,比如說監(jiān)聽數(shù)據(jù)庫數(shù)據(jù)的增刪過程,我們可以在hbase數(shù)據(jù)庫插入數(shù)據(jù)或者刪除數(shù)據(jù)之前或之后進(jìn)行一系列的操作。
二級索引基于此觸發(fā)器構(gòu)建。
Endpoint
類似傳統(tǒng)數(shù)據(jù)庫中的存儲過程,客戶端可以調(diào)用Endpoint執(zhí)行一段 Server 端代碼,并將 Server 端代碼的結(jié)果返回給客戶端進(jìn)一步處理,常用于Hbase的聚合操作。 min、max、avg、sum、distinct、group by
協(xié)處理加載方式
協(xié)處理器的加載方式有兩種,我們稱之為靜態(tài)加載方式(Static Load)和動態(tài)加載方式 (Dynamic Load)。靜態(tài)加載的協(xié)處理器稱之為 System Coprocessor,動態(tài)加載的協(xié)處理器稱 之為 Table Coprocessor
靜態(tài)加載:
通過修改 hbase-site.xml 這個文件來實現(xiàn),啟動全局 aggregation,能過操縱所有的表上的數(shù)據(jù)。只需要添加如下代碼:
為所有 table 加載了一個 cp class,可以用”,”分割加載多個 class
注意: 該方法因為是全局的,所以在實際應(yīng)用中并不是很多,而另一種方法用的會更多一些
動態(tài)加載
啟用表 aggregation,只對特定的表生效。通過 HBase Shell 來實現(xiàn)。
①disable 指定表。hbase> disable ‘table名’;
②添加 aggregation
③重啟指定表 hbase> enable ‘table名’
16、WAL機(jī)制
數(shù)據(jù)在寫入HBase的時候,先寫WAL,再寫入緩存。通常情況下寫緩存延遲很低,WAL機(jī)制一方面是為了確保數(shù)據(jù)即使寫入緩存后數(shù)據(jù)丟失也可以通過WAL恢復(fù),另一方面是為了集群之間的復(fù)制。默認(rèn)WAL機(jī)制是開啟的,并且使用的是同步機(jī)制寫WAL。
如果業(yè)務(wù)不特別關(guān)心異常情況下部分?jǐn)?shù)據(jù)的丟失,而更關(guān)心數(shù)據(jù)寫入吞吐量,可考慮關(guān)閉WAL寫,這樣可以提升2~3倍數(shù)據(jù)寫入的吞吐量。
如果業(yè)務(wù)不能接受不寫WAL,但是可以接受WAL異步寫入,這樣可以帶了1~2倍性能提升。
HBase中可以通過設(shè)置WAL的持久化等級決定是否開啟WAL機(jī)制、以及HLog的落盤方式。
WAL的持久化等級分為如下四個等級:
- SKIP_WAL:只寫緩存,不寫HLog日志。這種方式因為只寫內(nèi)存,因此可以極大的提升寫入性能,但是數(shù)據(jù)有丟失的風(fēng)險。在實際應(yīng)用過程中并不建議設(shè)置此等級,除非確認(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)格的日志寫入等級,可以保證數(shù)據(jù)不會丟失,但是性能相對比較差。
除了在創(chuàng)建表的時候直接設(shè)置WAL存儲級別,也可以通過客戶端設(shè)置WAL持久化等級,代碼:put.setDurability(Durability.SYNC_WAL);
17、Memstore
hbase為了保證隨機(jī)讀取的性能,所以storefile的數(shù)據(jù)按照rowkey的字典序存儲。當(dāng)客戶端的請求在到達(dá)regionserver之后,為了保證寫入rowkey的有序性,不能將數(shù)據(jù)立刻寫入到hfile中,而是將每個變更操作保存在內(nèi)存中,也就是memstore中。memstore能夠保證內(nèi)部數(shù)據(jù)有序。當(dāng)某個memstore達(dá)到閾值后,會將Region的所有memstore都flush到hfile中(Flush操作為Region級別),這樣能充分利用hadoop寫入大文件的性能優(yōu)勢,提高寫入性能。
由于memstore是存放在內(nèi)存中,如果regionserver宕機(jī),會導(dǎo)致內(nèi)存中數(shù)據(jù)丟失。所有為了保證數(shù)據(jù)不丟失,hbase將更新操作在寫入memstore之前會寫入到一個WAL中。WAL文件是追加、順序?qū)懭氲?#xff0c;WAL每個regionserver只有一個,同一個regionserver上所有region寫入同一個的WAL文件。這樣當(dāng)某個regionserver失敗時,可以通過WAL文件,將所有的操作順序重新加載到memstore中。
主要作用:
-
更新數(shù)據(jù)存儲在 MemStore 中,使用 LSM(Log-Structured Merge Tree)數(shù)據(jù)結(jié)構(gòu)存儲,在內(nèi)存內(nèi)進(jìn)行排序整合。即保證寫入數(shù)據(jù)有序(HFile中數(shù)據(jù)都按照RowKey進(jìn)行排序),同時可以極大地提升HBase的寫入性能。
-
作為內(nèi)存緩存,讀取數(shù)據(jù)時會優(yōu)先檢查 MemStore,根據(jù)局部性原理,新寫入的數(shù)據(jù)被訪問的概率更大。
-
在持久化寫入前可以做某些優(yōu)化,例如:保留數(shù)據(jù)的版本設(shè)置為1,持久化只需寫入最新版本。
如果一個 HRegion 中 MemStore 過多(Column family 設(shè)置過多),每次 flush 的開銷必然會很大,并且生成大量的 HFile 影響后續(xù)的各項操作,因此建議在進(jìn)行表設(shè)計的時候盡量減少 Column family 的個數(shù)。
用戶可以通過shell命令分別對一個 Table 或者一個 Region 進(jìn)行 flush:
hbase> flush 'TABLENAME' hbase> flush 'REGIONNAME'相關(guān)配置
hbase.hregion.memstore.flush.size
默認(rèn)值:128M
MemStore 最大尺寸,當(dāng) Region 中任意一個 MemStore 的大小(壓縮后的大小)達(dá)到了設(shè)定值,會觸發(fā) MemStore flush。
hbase.hregion.memstore.block.multiplier
默認(rèn)值:2
Region 級別限制,當(dāng) Region 中所有 MemStore 的大小總和達(dá)到了設(shè)定值(hbase.hregion.memstore.block.multiplier * hbase.hregion.memstore.flush.size,默認(rèn) 2* 128M = 256M),會觸發(fā) MemStore flush。
hbase.regionserver.global.memstore.upperLimit
默認(rèn)值:0.4
Region Server 級別限制,當(dāng)一個 Region Server 中所有 MemStore 的大小總和達(dá)到了設(shè)定值(hbase.regionserver.global.memstore.upperLimit * hbase_heapsize,默認(rèn) 0.4 * RS堆內(nèi)存大小),會觸發(fā)Region Server級別的MemStore flush。
hbase.regionserver.global.memstore.lowerLimit
默認(rèn)值:0.38
與 hbase.regionserver.global.memstore.upperLimit 類似,區(qū)別是:當(dāng)一個 Region Server 中所有 MemStore 的大小總和達(dá)到了設(shè)定值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize,默認(rèn) 0.38 * RS堆內(nèi)存大小),會觸發(fā)部分 MemStore flush。
Flush 順序是按照 Region 的總 MemStore 大小,由大到小執(zhí)行,先操作 MemStore 最大的 Region,再操作剩余中最大的 Region,直至總體 MemStore 的內(nèi)存使用量低于設(shè)定值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize)。
hbase.regionserver.maxlogs
默認(rèn)值:32
當(dāng)一個 Region Server 中 HLog 數(shù)量達(dá)到設(shè)定值,系統(tǒng)會選取最早的一個 HLog 對應(yīng)的一個或多個 Region 進(jìn)行 flush。
當(dāng)增加 MemStore 的大小以及調(diào)整其他的 MemStore 的設(shè)置項時,也需要去調(diào)整 HLog 的配置項。否則,WAL的大小限制可能會首先被觸發(fā)。因而,將利用不到其他專門為Memstore而設(shè)計的優(yōu)化。
需要關(guān)注的 HLog 配置是 HLog 文件大小,由參數(shù) hbase.regionserver.hlog.blocksize 設(shè)置(默認(rèn)512M),HLog 大小達(dá)到上限,或生成一個新的 HLog
通過WAL限制來觸發(fā)Memstore的flush并非最佳方式,這樣做可能會會一次flush很多Region,盡管“寫數(shù)據(jù)”是很好的分布于整個集群,進(jìn)而很有可能會引發(fā)flush“大風(fēng)暴”。
hbase.regionserver.optionalcacheflushinterval
默認(rèn)值:3600000
HBase 定期刷新 MemStore,默認(rèn)周期為1小時,確保 MemStore 不會長時間沒有持久化。為避免所有的 MemStore 在同一時間都進(jìn)行 flush,定期的 flush 操作有 20000 左右的隨機(jī)延時。
Memstore Flush
為了減少 flush 過程對讀寫的影響,HBase 采用了類似于兩階段提交的方式,將整個 flush 過程分為三個階段:
-
prepare 階段:遍歷當(dāng)前 Region 中的所有 MemStore,將 MemStore 中當(dāng)前數(shù)據(jù)集 kvset 做一個快照 snapshot,然后再新建一個新的 kvset,后期的所有寫入操作都會寫入新的 kvset 中。整個 flush 階段讀操作讀 MemStore 的部分,會分別遍歷新的 kvset 和 snapshot。prepare 階段需要加一把 updateLock 對寫請求阻塞,結(jié)束之后會釋放該鎖。因為此階段沒有任何費時操作,因此持鎖時間很短。
-
flush 階段:遍歷所有 MemStore,將 prepare 階段生成的 snapshot 持久化為臨時文件,臨時文件會統(tǒng)一放到目錄.tmp下。這個過程因為涉及到磁盤IO操作,因此相對比較耗時。
-
commit 階段:遍歷所有的 MemStore,將 flush 階段生成的臨時文件移到指定的 Column family 目錄下,生成對應(yīng)的 Storefile(HFile) 和 Reader,把 Storefile 添加到 Store 的 Storefiles 列表中,最后再清空 prepare 階段生成的 snapshot。
18、BloomFilter
布隆過濾器是hbase中的高級功能,它能夠減少特定訪問模式(get/scan)下的查詢時間。不過由于這種模式增加了內(nèi)存和存儲的負(fù)擔(dān),所以被默認(rèn)為關(guān)閉狀態(tài)。
hbase支持如下類型的布隆過濾器:
如果用戶隨機(jī)查找一個rowkey,位于某個region中兩個開始rowkey之間的位置。對于hbase來說,它判斷這個行鍵是否真實存在的唯一方法就是加載這個region,并且掃描它是否包含這個鍵。當(dāng)我們get數(shù)據(jù)時,hbase會加載很多塊文件。
采用布隆過濾器后,它能夠準(zhǔn)確判斷該StoreFile的所有數(shù)據(jù)塊中,是否含有我們查詢的數(shù)據(jù),從而減少不必要的塊加載,增加hbase集群的吞吐率。
1、布隆過濾器的存儲在哪
開啟布隆后,HBase會在生成StoreFile時包含一份布隆過濾器結(jié)構(gòu)的數(shù)據(jù),稱其為MetaBlock;MetaBlock與DataBlock(真實的KeyValue數(shù)據(jù))一起由LRUBlockCache維護(hù)。所以,開啟bloomfilter會有一定的存儲及內(nèi)存cache開銷。大多數(shù)情況下,這些負(fù)擔(dān)相對于布隆過濾器帶來的好處是可以接受的。
2、采用布隆過濾器后,如何get數(shù)據(jù)
在讀取數(shù)據(jù)時,hbase會首先在布隆過濾器中查詢,根據(jù)布隆過濾器的結(jié)果,再在MemStore中查詢,最后再在對應(yīng)的HFile中查詢。
3、采用ROW還是ROWCOL
- 如果用戶只做行掃描,使用ROW即可,使用更加細(xì)粒度的ROWCOL會增加內(nèi)存的消耗。
- 如果大多數(shù)隨機(jī)查詢使用行加列作為查詢條件,Bloomfilter需要設(shè)置為ROWCOL。
- 如果不確定業(yè)務(wù)查詢類型,設(shè)置為row。
19、BlockCache讀緩存
一個RegionServer只有一個BlockCache。用來優(yōu)化讀取性能,不是數(shù)據(jù)存儲的必須組成部分。
BlockCache名稱中的Block指的是HBase的Block。BlockCache的工作原理跟其他緩存一樣:
讀請求到HBase之后先嘗試查詢BlockCache,如果獲取不到就去StoreFile和 Memstore中去獲取。如果獲取到了則在返回數(shù)據(jù)的同時把Block塊緩存到BlockCache中。BlockCache默認(rèn)是開啟的。
BlockCache的實現(xiàn)方案有以下幾種:
LRUBlock Cache:
近期最少使用算法。讀出來的block會被放到BlockCache中待 下次查詢使用。當(dāng)緩存滿了的時候,會根據(jù)LRU的算法來淘汰block。
SlabCache
這是一種堆外內(nèi)存的解決方案。不屬于JVM管理的內(nèi)存范圍,說白了,就是原始的內(nèi)存區(qū)域了。回收堆外內(nèi)存的時候JVM幾乎不會停頓,可以避免GC過程中遇見的系統(tǒng)卡頓與異常。
Bucket Cache
BucketCache借鑒SlabCache也用上了堆外內(nèi)存。不過它以下自己的特點:
-
相比起只有2個區(qū)域的SlabeCache,BucketCache一上來就分配了 14種區(qū)域。這 14種區(qū)域分別放的是大小為4KB、8KB、16KB、32KB、40KB、 48KB、56KB、64KB、96KB、128KB、192KB、256KB、384KB、 512KB的Block。而且這個種類列表還是可以手動通過設(shè)置 hbase.bucketcache.bucket.sizes屬性來定義
-
BucketCache的存儲不一定要使用堆外內(nèi)存,是可以自由在3種存 儲介質(zhì)直接選擇:堆(heap)、堆外(offheap)、文件 (file)。通過設(shè)置hbase.bucketcache.ioengine為heap、 offfheap或者file來配置。
-
每個Bucket的大小上限為最大尺寸的block * 4,比如可以容納 的最大的Block類型是512KB,那么每個Bucket的大小就是512KB * 4 = 2048KB。
-
系統(tǒng)一啟動BucketCache就會把可用的存儲空間按照每個Bucket 的大小上限均分為多個Bucket。如果劃分完的數(shù)量比你的種類還 少,比如比14(默認(rèn)的種類數(shù)量)少,就會直接報錯,因為每一 種類型的Bucket至少要有一個Bucket。
組合模式
把不同類型的Block分別放到 LRUCache和BucketCache中。
Index Block和Bloom Block會被放到LRUCache中。Data Block被直接放到BucketCache中,所以數(shù)據(jù)會去LRUCache查詢一下,然后再去 BucketCache中查詢真正的數(shù)據(jù)。其實這種實現(xiàn)是一種更合理的二級緩存,數(shù)據(jù)從一級緩存到二級緩存最后到硬盤,從小到大,存儲介質(zhì)也由快到慢。考慮到成本和性能的組合,比較合理的介質(zhì)是:LRUCache使用內(nèi)存->BuckectCache使用SSD->HFile使用機(jī)械硬盤。
BlockCache 壓縮
在開啟此功能后,數(shù)據(jù)塊會以它們on-disk的形式緩存到BlockCache。與默認(rèn)的模式不同點在于:默認(rèn)情況下,在緩存一個數(shù)據(jù)塊時,會先解壓縮然后存入緩存。而lazy BlockCache decompression 直接將壓縮的數(shù)據(jù)塊存入緩存。
如果一個RegionServer存儲的數(shù)據(jù)過多,無法適當(dāng)?shù)膶⒋蟛糠謹(jǐn)?shù)據(jù)放入緩存,則開啟這個功能后,可以提升50%的吞吐量,30%的平均延遲上升,增加80%垃圾回收,以及2%的整體CPU負(fù)載。
壓縮默認(rèn)關(guān)閉,若要開啟,可以在hbase-site.xml文件里設(shè)置 hbase.block.data.cachecompressed 為 true
20、Region拆分
一個Region就是一個表的一段Rowkey的數(shù)據(jù)集合。一旦 Region 的負(fù)載過大或者超過閾值時,它就會被分裂成兩個新的 Region。Region的拆分分為自動拆分和手動拆分。自動拆分可以采用不同的策略。
拆分流程
這個過程是由 RegionServer 完成的,其拆分流程如下。
自動拆分
Region的自動拆分主要根據(jù)拆分策略進(jìn)行,主要有以下幾種拆分策略:
-
ConstantSizeRegionSplitPolicy
0.94版本前唯一拆分策略,按照固定大小來拆分Region。Region 中的最大Store大于設(shè)置閾值(hbase.hregion.max.filesize:默認(rèn)10GB)觸發(fā)拆分。拆分點為最大Store的rowkey的順序中間值。
弊端: 切分策略對于大表和小表沒有明顯的區(qū)分。閾值(hbase.hregion.max.filesize)設(shè)置較大對大表友好,但小表有可能不會觸發(fā)分裂,極端情況下可能就1個。如果設(shè)置較小則對小表友好,但大表就會在整個集群產(chǎn)生大量的region,占用集群資源。 -
IncreasingToUpperBoundRegionSplitPolicy
0.94版本~2.0版本默認(rèn)切分策略。切分策略稍微有點復(fù)雜,基于ConstantSizeRegionSplitPolicy思路,一個region大小大于設(shè)置閾值就會觸發(fā)切分。但是這個閾值并不是固定值,而是會在一定條件下不斷調(diào)整,調(diào)整規(guī)則和region所屬表在當(dāng)前regionserver上的region個數(shù)有關(guān)系. -
KeyPrefixRegionSplitPolicy
在IncreasingToUpperBoundRegionSplitPolicy的基礎(chǔ)上增加了對拆分點(splitPoint,拆分點就是Region被拆分處的rowkey)的自定義,可以將rowKey的前多少位作為前綴。保證相同前綴的rowkey拆分至同一個region中。 -
DelimitedKeyPrefixRegionSplitPolicy
KeyPrefixRegionSplitPolicy根據(jù)rowkey的固定前幾位來進(jìn)行判 斷,而DelimitedKeyPrefixRegionSplitPolicy是根據(jù)分隔符來判斷的。比如你定義了前綴分隔符為_,那么host1_001和host12_999的前綴 就分別是host1和host12。 -
SteppingSplitPolicy
2.0版本默認(rèn)切分策略,相比 IncreasingToUpperBoundRegionSplitPolicy 簡化,基于當(dāng)前表的region個數(shù)進(jìn)行規(guī)劃,對于大集群中的大表、小表會比 IncreasingToUpperBoundRegionSplitPolicy更加友好,小表不會再產(chǎn)生大量的小region,而是適可而止。 -
BusyRegionSplitPolicy
-
此前的拆分策略都沒有考慮熱點問題。熱點問題就是數(shù)據(jù)庫中的Region被訪問的頻率并不一樣,某些Region在短時間內(nèi)被訪問的很頻繁,承載了很大的壓力,這些Region就是熱點Region。
它會通過拆分熱點Region來緩解熱點Region壓力,但也會帶來很多不確定性因素,因為無法確定下一個被拆分的Region是哪個。 -
DisabledRegionSplitPolicy
關(guān)閉策略,手動拆分。可控制拆分時間,選擇集群空閑時間
手動拆分
調(diào)用hbase shell的 split方法,split的調(diào)用方式如下:
split 'regionName' # format: 'tableName,startKey,id'比如:
split 'test_table1,c,1476406588669.96dd8c68396fda69'這個就是把test_table1,c,1476406588669.96dd8c68396fda69這個 Region從新的拆分點999處拆成2個Region。
21、Region合并
如果有很多Region,則MemStore也過多,數(shù)據(jù)頻繁從內(nèi)存Flush到HFile,影響用戶請求,可能阻塞該Region服務(wù)器上的更新操作。過多的 Region 會增加服務(wù)器資源的負(fù)擔(dān)。當(dāng)刪了大量的數(shù)據(jù),或Region拆分過程中產(chǎn)生了過多小Region,這時可以Region合并,減輕RegionServer資源負(fù)擔(dān)。
合并過程
Merger類手動合并
合并通過使用org.apache.hadoop.hbase.util.Merge類來實現(xiàn)。
例如把以下兩個Region合并:
就需要在Linux下(不需要進(jìn)入hbase shell)執(zhí)行以下命令:
hbase org.apache.hadoop.hbase.util.Merge test_table1 test_table1,b,1476406588669.39eecae03539ba0a63264c24130c2cb1. test_table1,c,1476406588669.96dd8c68396fda694ab9b0423a60a4d9.此方式需要停止整個Hbase集群,所以后來又增加了online_merge(熱合并)。
熱合并
hbase shell提供了一個命令叫online_merge,通過這個方法可以進(jìn)行熱合并,無需停止整個Hbase集群。
假設(shè)要合并以下兩個Region:
test_table1,a,1476406588669.d1f84781ec2b93224528cbb79107ce12. test_table1,b,1476408648520.d129fb5306f604b850ee4dc7aa2eed36.online_merge的傳參是Region的hash值。只需在hbase shell 中執(zhí)行以下命令:
merge_region 'd1f84781ec2b93224528cbb79107ce12', 'd129fb5306f604b850ee4dc7aa2eed36'22、Region 負(fù)載均衡
當(dāng) Region 分裂之后,Region 服務(wù)器之間的 Region 數(shù)量差距變大時,Master 便會執(zhí)行負(fù)載均衡來調(diào)整部分 Region 的位置,使每個 Region 服務(wù)器的 Region 數(shù)量保持在合理范圍之內(nèi),負(fù)載均衡會引起 Region 的重新定位,使涉及的 Region 不具備數(shù)據(jù)本地性。
Region 的負(fù)載均衡由 Master 來完成,Master 有一個內(nèi)置的負(fù)載均衡器,在默認(rèn)情況下,均衡器每 5 分鐘運行一次,用戶可以配置。負(fù)載均衡操作分為兩步進(jìn)行:首先生成負(fù)載均衡計劃表, 然后按照計劃表執(zhí)行 Region 的分配。
執(zhí)行負(fù)載均衡前要明確,在以下幾種情況時,Master 是不會執(zhí)行負(fù)載均衡的。
- 均衡負(fù)載開關(guān)關(guān)閉。
- Master 沒有初始化。
- 當(dāng)前有 Region 處于拆分狀態(tài)。
- 當(dāng)前集群中有 Region 服務(wù)器出現(xiàn)故障。
Master 內(nèi)部使用一套集群負(fù)載評分的算法,來評估 HBase 某一個表的 Region 是否需要進(jìn)行重新分配。這套算法分別從 Region 服務(wù)器中 Region 的數(shù)目、表的 Region 數(shù)、MenStore 大小、 StoreFile 大小、數(shù)據(jù)本地性等幾個維度來對集群進(jìn)行評分,評分越低代表集群的負(fù)載越合理。
確定需要負(fù)載均衡后,再根據(jù)不同策略選擇 Region 進(jìn)行分配,負(fù)載均衡策略有三種,如下表所示。
| RandomRegionPicker | 隨機(jī)選出兩個 Region 服務(wù)器下的 Region 進(jìn)行交換 |
| LoadPicker | 獲取 Region 數(shù)目最多或最少的兩個 Region 服務(wù)器,使兩個 Region 服務(wù)器最終的 Region 數(shù)目更加平均 |
| LocalityBasedPicker | 選擇本地性最強(qiáng)的 Region |
根據(jù)上述策略選擇分配 Region 后再繼續(xù)對整個表的所有 Region 進(jìn)行評分,如果依然未達(dá)到標(biāo)準(zhǔn),循環(huán)執(zhí)行上述操作直至整個集群達(dá)到負(fù)載均衡的狀態(tài)。
23、Region預(yù)分區(qū)
Hbase建表時默認(rèn)單region,所有數(shù)據(jù)都會寫入此region,超過閾值(hbase.Region.max.filesize,默認(rèn)10G)會此region會進(jìn)行拆分,分成2個region。在此過程中,會產(chǎn)生三個問題:
基于此我們可以在建表時進(jìn)行預(yù)分區(qū),創(chuàng)建多個空region,減少由于split帶來的資源消耗,從而提高HBase的性能。
預(yù)分區(qū)時會確定每個region的起始和終止rowky,rowkey設(shè)計時確保均勻的命中各個region,就不會存在寫熱點問題。當(dāng)然隨著數(shù)據(jù)量的不斷增長,該split的還是要進(jìn)行split。
24、一張表中定義多少個 Column Family 最合適
Column Family劃分標(biāo)準(zhǔn)一般根據(jù)數(shù)據(jù)訪問頻度,如一張表里有些列訪問相對頻繁,而另一些列訪問很少,這時可以把這張表劃分成兩個列族,分開存儲,提高訪問效率。
25、為什么不建議在 HBase 中使用過多的列族
HBase 中每張表的列族個數(shù)建議設(shè)在1~3之間,列族數(shù)過多可能會產(chǎn)生以下影響:
對Flush的影響
在 HBase 中,數(shù)據(jù)首先寫入memStore 的,每個列族都對應(yīng)一個store,store中包含一個MemStore。列族過多將會導(dǎo)致內(nèi)存中存在越多的MemStore;而MemStore在達(dá)到閾值后會進(jìn)行Flush操作在磁盤生產(chǎn)一個hFile文件。列族越多導(dǎo)致HFile越多。
由于Flush操作是Region 級別的,即Region中某個MemStore被Flush,同一個Region的其他MemStore也會進(jìn)行Flush操作。當(dāng)列族之間數(shù)據(jù)不均勻,比如一個列族有100W行,一個列族只有10行,會產(chǎn)生很多很多小文件,而且每次 Flush 操作也涉及到一定的 IO 操作。
?
此外列族數(shù)過多可能會觸發(fā)RegionServer級別的Flush操作;這將會阻塞RegionServer上的更新操作,且時間可能會達(dá)到分鐘級別。
對Split的影響
當(dāng)HBase表中某個Region過大會觸發(fā)split拆分操作。如果有多個列族,且列族間數(shù)據(jù)量相差較大,這樣在Region Spli時會導(dǎo)致原本數(shù)據(jù)量很小的HFil文件進(jìn)一步被拆分,從而產(chǎn)生更多的小文件。
對 Compaction 的影響
目前HBase的Compaction操作也是Region級別的,過多的列族且列族間數(shù)據(jù)量相差較大,也會產(chǎn)生不必要的 IO。
對HDFS的影響
HDFS 其實對一個目錄下的文件數(shù)有限制的。列族數(shù)過多,文件數(shù)可能會超出HDFS的限制。小文件問題也同樣會出現(xiàn)。
對RegionServer內(nèi)存的影響
一個列族在RegionServer中對應(yīng)于一個 MemStore。每個MemStore默認(rèn)占用128MB的buffer。如果列族過多,MemStore會占用RegionServer大量內(nèi)存。
26、直接將時間戳作為行健,在寫入單個region時會發(fā)生熱點問題,為什么
region 中的 rowkey 是有序存儲,若時間比較集中。就會存儲到一個 region 中,這樣一個 region 的數(shù)據(jù)變多,其它的 region 數(shù)據(jù)很少,加載數(shù)據(jù)就會很慢,直到 region 分裂,此問題才會得到緩解。
27、HBase中region太小和region太大的影響
hbase.hregion.max.filesize:此參數(shù)定義了單個region的最大數(shù)據(jù)量。
1)當(dāng)region太小,觸發(fā)split的機(jī)率增加,split過程中region會下線,影響訪問服務(wù)。
2)當(dāng)region太大,由于長期得不到split,會發(fā)生多次compaction,將數(shù)據(jù)讀一遍并重寫一遍到 hdfs 上,占用IO。降低系統(tǒng)的穩(wěn)定性與吞吐量。
hbase數(shù)據(jù)會首先寫入MemStore,超過配置后會flush到磁盤成為StoreFile,當(dāng)StoreFile的數(shù)量超過配置之后,會啟動compaction,將他們合并為一個大的StoreFile。
當(dāng)合并后的Store大于max.filesize時,會觸發(fā)分隔動作,將它切分為兩個region。hbase.hregion.max.filesize不宜過大或過小,經(jīng)過實戰(zhàn),
生產(chǎn)高并發(fā)運行下,最佳大小5-10GB!
推薦關(guān)閉某些重要場景的hbase表的major_compact!在非高峰期的時候再去調(diào)用major_compact,這樣可以減少split的同時,顯著提供集群的性能,吞吐量、非常有用。
28、每天百億數(shù)據(jù)如何寫入Hbase
1)百億數(shù)據(jù):證明數(shù)據(jù)量非常大;
2)存入HBase:證明是跟HBase的寫入數(shù)據(jù)有關(guān);
3)保證數(shù)據(jù)的正確:要設(shè)計正確的數(shù)據(jù)結(jié)構(gòu)保證正確性;
4)在規(guī)定時間內(nèi)完成:對存入速度是有要求的。
解決思路:
1)假設(shè)一整天60x60x24 = 86400秒都在寫入數(shù)據(jù),那么每秒的寫入條數(shù)高達(dá)100萬條,HBase當(dāng)然是支持不了每秒百萬條數(shù)據(jù)的,
所以這百億條數(shù)據(jù)可能不是通過實時地寫入,而是批量地導(dǎo)入。批量導(dǎo)入推薦使用BulkLoad方式,性能是普通寫入方式幾倍以上;
2)存入HBase:普通寫入是用JavaAPI put來實現(xiàn),批量導(dǎo)入推薦使用BulkLoad;
3)保證數(shù)據(jù)的正確:這里需要考慮RowKey的設(shè)計、預(yù)建分區(qū)和列族設(shè)計等問題;
4)還有region熱點的問題,如果你的hbase數(shù)據(jù)不是那種每天增量的數(shù)據(jù),建議跑個mapreduce對你的數(shù)據(jù)進(jìn)行各評判,看看如何能將數(shù)據(jù)盡可能均勻的分配到每個region中,當(dāng)然這需要預(yù)先分配region
29、HBase集群安裝注意事項?
① HBase需要HDFS的支持,因此安裝HBase前確保Hadoop集群安裝完成;
② HBase需要ZooKeeper集群的支持,因此安裝HBase前確保ZooKeeper集群安裝完成;
③ 注意HBase與Hadoop的版本兼容性;
④ 注意hbase-env.sh配置文件和hbase-site.xml配置文件的正確配置;
⑤ 注意regionservers配置文件的修改;
⑥ 注意集群中的各個節(jié)點的時間必須同步,否則啟動HBase集群將會報錯。
30、Hbase數(shù)據(jù)熱點問題
一、出現(xiàn)熱點問題原因
二、如何解決熱點問題
31、HBase宕機(jī)恢復(fù)流程
宕機(jī)分為 Master 宕機(jī)和 regionServer 宕機(jī)
Master 宕機(jī)恢復(fù)
1、Master主要負(fù)責(zé)實現(xiàn)集群的負(fù)載均衡和讀寫調(diào)度,沒有單點問題,所以集群中可以存在多個Master節(jié)點。
2、通過熱備方式實現(xiàn)Master高可用,并在zookeeper上進(jìn)行注冊
3、active master會接管整個系統(tǒng)的元數(shù)據(jù)管理任務(wù),zk以及meta表中的元數(shù)據(jù),相應(yīng)用戶的管理指令,創(chuàng)建、刪除、修改,merge region等
regionServer宕機(jī)恢復(fù)
集群中一臺RegionServer宕機(jī)并不會導(dǎo)致已經(jīng)寫入的數(shù)據(jù)丟失,HBase采用WAL機(jī)制保證,即使意外宕機(jī)導(dǎo)致Memstore緩存數(shù)據(jù)沒有落盤,也可以通過HLog日志恢復(fù)。 RegionServer宕機(jī)一定程度上會影響業(yè)務(wù)方的讀寫請求,因為zookeeper感知到RegionServer宕機(jī)事件是需要一定時間的,這段時間默認(rèn)會有3min。
引起RegionServer宕機(jī)的原因各種各樣,Full GC、網(wǎng)絡(luò)異常、官方Bug導(dǎo)致(close wait端口未關(guān)閉)等。
一旦RegionServer發(fā)生宕機(jī),Zookeeper感知后會通知Master,Master首先會將這臺RegionServer上所有Region移到其他RegionServer上,再將HLog分發(fā)給其他RegionServer進(jìn)行回放,完成之后再修改路由,業(yè)務(wù)方的讀寫才會恢復(fù)正常。整個過程都是自動完成的,并不需要人工介入。
宕機(jī)原因
1、Full Gc引起長時間停頓超過心跳時間
2、HBase對Jvm堆內(nèi)存管理不善,未合理使用堆外內(nèi)存
3、Jvm啟動參數(shù)配置不合理
4、業(yè)務(wù)寫入或吞吐量太大
5、網(wǎng)絡(luò)異常導(dǎo)致超時或RegionServer斷開集群連接
宕機(jī)檢測
通過Zookeeper實現(xiàn), 正常情況下RegionServer會周期性向Zookeeper發(fā)送心跳,一旦發(fā)生宕機(jī),心跳就會停止,超過一定時間(SessionTimeout)Zookeeper就會認(rèn)為RegionServer宕機(jī)離線,并將該消息通知給Master。
具體流程
master通過zk實現(xiàn)對RegionServer的宕機(jī)檢測。RegionServer會周期性的向zk發(fā)送心跳,超過一定時間,zk會認(rèn)為RegionServer離線,發(fā)送消息給master。
master重新分配宕機(jī)regionserver上的所有region,regionserver宕機(jī)后,所有region處于不可用狀態(tài),所有路由到這些region上的請求都會返回異常。 異常情況比較短暫,master會將這些region分配到其它regionserver上。
將HLog日志分分配至其他regionserver中,回放HLog日志補(bǔ)救數(shù)據(jù)。
恢復(fù)完成后修改路由,對外提供讀寫服務(wù)。
深入閱讀:HBase宕機(jī)恢復(fù)
32、HBase性能優(yōu)化
HDFS調(diào)優(yōu)
Hbase基于HDFS存儲,首先需要進(jìn)行HDFS的相關(guān)優(yōu)化。優(yōu)化內(nèi)容詳見《大數(shù)據(jù)面試題整理-HDFS篇》
集群性能優(yōu)化
表層面優(yōu)化
1)blocksize越大,配置壓縮算法,壓縮的效率就越好,有利于提升寫入性能;
2)但是由于讀數(shù)據(jù)以block塊為單位,所以越大的block塊,隨機(jī)讀的性能較差。
3)如果要提升寫入的性能,一般擴(kuò)大到128kb或者256kb,可以提升寫數(shù)據(jù)的效率,也不會太大影響隨機(jī)讀性能。
讀優(yōu)化
1)對于注重讀響應(yīng)時間的系統(tǒng),可以將 BlockCache設(shè)大些,加大緩存的命中率。
2)開啟BolckCache壓縮。
3)采用組合模式把不同類型的Block分別放到 LRUCache和BucketCache中,其中IndexBloom Block放到LRUCache中。Data Block放到BucketCache中,LRUCache使用內(nèi)存->BuckectCache使用SSD->HFile使用機(jī)械硬盤。
寫優(yōu)化
多線程并發(fā)寫: 客戶端開啟多個HTable寫線程,每個寫線程負(fù)責(zé)一個HTable對象的flush操作,這樣結(jié)合定時flush和寫buffer,可以即保證在數(shù)據(jù)量小的時候,數(shù)據(jù)可以在較短時間內(nèi)被flush,同時又保證在數(shù)據(jù)量大的時候,寫buffer一滿就即使進(jìn)行flush。
使用BulkLoad寫入: 在HBase中數(shù)據(jù)都是以HFile形式保存在HDFS中的,當(dāng)有大量數(shù)據(jù)需要寫入到HBase的時候,可以采用BulkLoad方式完成。通過使用MapReduce或者Spark直接生成HFile格式的數(shù)據(jù)文件,然后再通過RegionServer將HFile數(shù)據(jù)文件移動到相應(yīng)的Region上去。
合理設(shè)置WAL: 寫HBase時,數(shù)據(jù)需要先寫入WAL保障數(shù)據(jù)不丟失。如果業(yè)務(wù)不特別關(guān)心異常情況下部分?jǐn)?shù)據(jù)的丟失,而更關(guān)心數(shù)據(jù)寫入吞吐量,可開啟WAL異步寫入或考慮關(guān)閉WAL寫。
總結(jié)
以上是生活随笔為你收集整理的【2022持续更新】大数据最全知识点整理-HBase篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于Android中RSA数字签名的理解
- 下一篇: 线上慎用Java断言