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