HBase 優化拆分和合併

2021-10-07 00:01:25 字數 3072 閱讀 4870

摘錄自《hbase 權威指南》

hbase 內建的處理拆分和合併的機制一般是合理的,並且它們按照預期處理任務,但在某些情況下,還是需要按照應用需求對這部分功能進行優化以獲得額外的效能改善。

通常 hbase 是自動處理 region 拆分的:一旦它們達到了既定的閾值,region 將被拆分成兩個,之後它們可以接受新的資料並繼續增長。這個預設行為能滿足大多數用例的需求。但是其中一種可能出現問題的情況被稱為「拆分/合併風暴」:當使用者的 region 大小以恆定的速度保持增長時,region 拆分會在同一時間發生,因為同時需要壓縮 region 中的儲存檔案,這個過程會重寫拆分之後的 region,這將會引起磁碟 i/o 上公升。

與其依賴 hbase 自動管理拆分,使用者還不如關閉這個行為然後手動呼叫 split 和 major_compact 命令。使用者可以通過設定這個集群的 hbase.hregion.max.filesize 值或者在列族級別把錶模式中對應引數設定成非常大的值來完成。為防止手動拆分無法執行,最好不要將其設定為 long.max_value。使用者最好將這個值設定為乙個合理上限,例如,100gb(如果觸發的話將會導致乙個小時的 major 合併)。

手動執行命令來拆分和壓縮 region 的好處是可以對它們進行時間控制。在不同 region 上交錯執行,這樣可以盡可能分散 i/o 負載,並且可以避免拆分/合併風暴。使用者可以實現乙個,呼叫 split() 和 majorcompact() 方法的客戶端,也可以使用 shell 命令互動地呼叫相關命令,或者使用 cron 定時地執行它們。

另外乙個手動管理拆分的優勢是使用者能夠更好地在任意時間控制哪些 region 可用。這對於使用者需要解決底層 bug 這種少數情況來說是十分有用的,例如,排查某乙個 region 的問題。在使用自動拆分時,使用者可能發現要檢查的 region 已經被兩個拆分後的子 region 替代了。這些子 region 有新的名字,並且客戶端需要大量的時間更新定位 region,這使得查詢所需要的資訊變得更加困難。

可以緩解這種現象的途徑就是手動地將熱點 region 按特定的邊界拆分成乙個或多個新 region,然後將子 region 負載分布到多個 region 伺服器上。使用者可以為 region 指定乙個拆分行鍵,即 region 被拆分為兩部分的位置;也可以指定 region 中任意的行鍵,這樣可以生成完全不同的兩個 region。這個只能在處理非完全連續的行鍵範圍時起作用,因為採用連續的行鍵時,過一段時間插入的資料總會集中到最近生成的幾個 region 上。

對於擁有很多 region 的表來說,大部分 region 分布並不均勻,即大多數 region 位於同乙個 region 伺服器上。這就意味著,即使用隨機的 key 來寫入資料,某一台 region 伺服器的負載仍大於其它的 region 伺服器。使用者可以從 hbase shell 或者使用 hbaseadmin 類中的 api,並通過 move() 函式顯示地把 region 從乙個 region 伺服器移動到另乙個 region 伺服器。另外乙個方法就是使用 unassgin() 方法或者 shell 命令簡單地從當前伺服器移除受影響的表的 region,master 會立即將其部署到其它 region 伺服器上。

管理拆分能夠在集群負載增加時有效地進行負載控制。但是,使用者仍然會面臨的乙個問題是,在使用者初始建立乙個新錶之後,使用者需要頻繁地拆分 region,因為建立的新錶通常只有乙個 region,不推薦讓單個 region 增長到太大。因此,在表建立時,最好就有較大數量的 region。使用者可以在建立表時指定需要的 region 數目來達到預拆分的目的。

管理介面中的 createtable() 方法和 shell 中的 create 命令都可以接受以列表形式提供的拆分行鍵作為引數,該引數在建立表的時候會被用來預拆分 region。

例如使用 shell 的 create 命令:

hbase(main):001:0> create 'testtable','cf1',

0 row(s)

in 1.4870 seconds

=> hbase::table - testtable

這將生成以下的 region,可以使用在hbase shell 下 scan 『hbase:meta』,filter => 「prefixfilter (『testtable』)」 檢視:

表名,region startkey,建立時間.hash值

testtable,,1591710550406.59ce5ddd99780faf22cf0ff39352774d.

testtable,row-100,1591710550406.d4e486efb83c91dc9c3066f4ffe4d3f7.

testtable,row-200,1591710550406.62a10ba62b27d3bc6625d8ec2b9f512e.

testtable,row-300,1591710550406.bc96221f395381cdb6329bd416fb7790.

testtable,row-400,1591710550406.845de79cc30bf9f1a27b0afe2fe7711a.

關於如何設定預拆分的 region 數量,使用者可以先按照每個伺服器 10 個 region 來進行預拆分,隨著時間的推移觀察資料的增長情況。先設定較少的 region 數目再稍後滾動拆分它們是一種更好的方法,因為過多的 region 通常會影響集群效能。另一種方法是,使用者可以基於 region 中最大儲存檔案大小來決定預拆分 region 的數目,隨著資料的增加,該大小會隨之一起增加。使用者希望最大的 region 正好能夠跳過 major 合併,否則使用者可能會面對前面提到的 compaction(壓縮) 風暴。

如果使用者將 region 預拆分的太小,可以通過增加 hbase.hregion.majorcompaction 的值來加大 major 合併的間隔。如果使用者的資料規模增加過大,使用者可以使用 regionsplitter 工具在所有 region 上通過網路 i/o 執行安全的滾動拆分。

使用手動拆分和預拆分是高階概念,需要使用者有謹慎的計畫並仔細監控操作時 hbase 系統的運**況。另一方面,這能夠避免全域性一致的資料增長造成的合併風暴,並可以通過手動拆分擺脫 region 熱點的困擾。

69 拆分和合併檔案

在將乙個檔案作為電子郵件的附件傳送時,由於附件的大小有限制,不能傳送太大的檔案。可以將較大的檔案分割為多個較小的檔案,傳送後再合併為乙個檔案,下邊兩個方法實現檔案的拆分和合併。首先是拆分方法,引數1是要拆分檔案的路徑 路徑包括檔名及副檔名 引數2是拆分後的檔名 無副檔名 檔名後邊由拆分方法自動增加序...

鍊錶的拆分和合併

單向鍊錶類 把乙個鍊錶的奇數字節點逆序取出,偶數字順序取出 最後合併 public class listsplit public static void listsplit linkedlist list1 newlinkedlist linkedlist list2 newlinkedlist 奇...

11 練習 檔案拆分和合併

1.練習 檔案拆分和合併 將 c aaa src.zip 20m大小的檔案拆分成每6m為乙個小檔案 src.zip 1 src.zip 2 src.zip 3 src.zip 4 將 c aaa src.zip 20m大小的檔案拆分成每6m為乙個小檔案 public class teststream...