HBase 寫吞吐場景資源消耗量化分析及優化
一、概述
HBase 是一個基於 Google BigTable 論文設計的高可靠性、高效能、可伸縮的分散式儲存系統。 網上關於 HBase 的文章很多,官方文件介紹的也比較詳細,本篇文章不介紹 HBase 基本的細節。
本文從 HBase 寫鏈路開始分析,然後針對少量隨機讀和海量隨機寫入場景入手,全方面量化分析各種資源的開銷, 從而做到以下兩點:
在這裡相信有許多想要學習大資料的同學,大家可以+下大資料學習裙:957205962,即可免費領取套系統的大資料學習教程
-
在給定業務量級的情況下,預先評估好叢集的合理規模
-
在 HBase 的眾多引數中,選擇合理的配置組合
二、HBase 寫鏈路簡要分析
HBase 的寫入鏈路基於 LSM(Log-Structured Merge-Tree), 基本思想是把使用者的隨機寫入轉化為兩部分寫入:
Memstore 記憶體中的 Map, 儲存隨機的隨機寫入,待 memstore 達到一定量的時候會非同步執行 flush 操作,在 HDFS 中生成 HFile 中。 同時會按照寫入順序,把資料寫入一份到 HDFS 的 WAL(Write Ahead Log)中,用來保證資料的可靠性,即在異常(當機,程式異常退出)的場景下,能夠恢復 Memstore 中還沒來得及持久化成 HFile 的資料。
三、Flush & Compaction
上一節中,介紹了 HBase 的寫路徑,其中 HFile 是 HBase 資料持久化的最終形態, 本節將介紹 HBase 如何生成 HFile 和管理 HFile。關於 HFile, 主要涉及到兩個核心操作:
-
Flushing
-
Compaction
上一節中提到,HBase 的寫入最先會放入記憶體中,提供實時的查詢,當 Memstore 中資料達到一定量的閾值(128MB),會通過 Flush 操作生成 HFile 持久化到 HDFS 中,隨著使用者的寫入,生成的 HFile 數目會逐步增多,這會影響使用者的讀操作,同時也會系統佔用(HDFS 層 block 的數目, regionserver 伺服器的檔案描述符佔用), region split 操作,region reopen 操作也會受到不同程度影響。
HBase 通過 Compaction 機制將多個 HFile 合併成一個 HFile 以控制每個 Region 內的 HFile 的數目在一定範圍內, 當然 Compaction 還有其他的作用,比如資料本地化率,多版本資料的合併,資料刪除標記的清理等等,本文不做展開。
另外還有一點需要知道的是,HBase 中 Flush 操作和 Compaction 操作和讀寫鏈路是由獨立執行緒完成的,互不干擾。
四、系統開銷定量分析
為了簡化計算,本節針對事件類資料寫吞吐型場景,對 HBase 系統中的開銷做定量的分析,做以下假設:
-
資料寫入的 Rowkey 是打散的,不存在寫熱點
-
資料寫入量及總量是可評估的,會對資料做預先分割槽,定量分析基於 region 分佈穩定的情況下
-
假設隨機讀的數目很小,小到可以忽略 IO 開銷,且對讀 RT 不敏感
-
資料沒有多版本,沒有刪除操作,compaction 不會減少資料量
-
HBase 寫入鏈路中不存在隨機磁碟,所以隨機 IOPS 不會成為瓶頸
-
一般大資料機型的多個 SATA 盤的順序寫吞吐大於萬兆網路卡
-
忽略掉 RPC 帶來的額外的頻寬消耗
4.1 系統變數
-
單條資料大小 -> s (bytes)
-
峰值寫 TPS -> T
-
HFile 副本數→ R1 (一般為3)
-
WAL 副本數 → R2 (一般為3)
-
WAL 資料壓縮比 → Cwal (一般是1)
-
HFile 壓縮比 → C (採用 DIFF + LZO, 日誌場景壓縮比一般為 0.2左右)
-
FlushSize → F (這裡跟 regionserver 的 memstore 記憶體容量,region 數目,寫入是否平均和 flushsize 的配置有關,簡化分析,認為記憶體是足夠的 128MB)
-
hbase.hstore.compaction.min → CT (預設是 3, 一般情況下,決定了歸併係數,即每次 9. compaction 參與的檔案數目,在不存在 compaction 積壓的情況下, 實際執行時也是在 3 左右)
-
資料生命週期 → TTL (決定資料量的大小,一般寫吞吐場景,日誌會有一定的儲存週期, 單位天)
-
單機資料量水位 → D ( 單位 T,這裡指 HDFS 上存放 HFile 資料的資料量平均分擔到每臺機器上)
-
MajorCompaction 週期 → M( hbase.hregion.majorcompaction 決定,預設 20 天)
以上 11 個引數,是本次量化分析中需要使用到的變數,系統資源方面主要量化以下兩個指標:
-
磁碟開銷
-
網路開銷
-
在這裡相信有許多想要學習大資料的同學,大家可以+下大資料學習裙:957205962,即可免費領取套系統的大資料學習教程
4.2 磁碟容量開銷量化分析
這裡只考慮磁碟空間方面的佔用,相關的變數有:
-
單條資料大小 s
-
峰值寫入 TPS
-
HFile 副本數 R1
-
HFile 壓縮比 c
-
資料生命週期 TTL
HFile 的磁碟容量量化公式
V = TTL * 86400 * T * s * C * R1
假設 s = 1000, TTL = 365, T = 200000, C = 0.2 , R1 = 3 的情況下,HFile 磁碟空間需求是:
-
V = 30 * 86400 * 200000 * 1000 * 0.2 * 3
-
= 311040000000000.0 bytes
-
= 282T
在這裡我們忽略了其他佔用比較小的磁碟開銷,比如:
-
WAL 的磁碟開銷,在沒有 Replication,寫入平均的情況下,WAL 的日誌量約定於 (hbase.master.logcleaner.ttl /1000) * s * TPS + totalMemstoreSize
-
Compaction 臨時檔案,Split 父 Region 檔案等臨時檔案
-
Snapshot 檔案
-
等等
4.3 網路開銷量化分析
HBase 中會造成巨大網路開銷的主要由一下三部分組成,他們是相互獨立,非同步進行的,這裡做個比方,HBase 這三個操作和人吃飯很像,這裡做個類比
迴歸正題,下面按照發生順序,從三個角度分別分析:
-
寫路徑
-
Flush
-
Compaction
4.3.1 寫路徑
寫路徑的網路開銷,主要是寫 WAL 日誌方面, 相關的變數有:
-
單條資料大小 s
-
峰值寫入 TPS
-
WAL 副本數 R2
-
WAL 壓縮比 Cwal
寫路徑中,產生的網路流量分為兩部分,一部分是寫 WAL 產生的流量,一部分是外部使用者 RPC 寫入的流量, In 流量和 Out 流量計算公式為:
NInWrite = T * s * Cwal * (R2 - 1) + (T * s )
NOutWrite = T * s * Cwal * (R2 - 1)
假設 T = 20W,s = 1000, Cwal = 1.0, R2 = 3
-
NInwrite = 200000 * 1000 * 1 * (3-1) + 200000 * 1000
-
-
= 600000000 bytes/s
-
-
= 572MB/s
-
-
NOutwrite = 200000 * 1000* 1 * (3-1)
-
-
= 400000000 bytes/s
-
-
= 381MB/s
4.3.2 Flush
Flush 的網路開銷,主要是生成 HFile 後,將 HFile 寫入到 HDFS 的過程,相關的變數有:
-
單條資料大小 s
-
峰值寫入 T
-
HFIle 副本數 R1
-
HFile 壓縮比 C
Flush 產生的 In 流量和 Out 流量計算公式為:
NInWrite = s * T * (R1 - 1) * C
NOutWrite = s * T * (R1 - 1) * C
假設 T = 20W, S = 1000, R1 = 3, C = 0.2
-
NInwrite = 200000 * 1000 * (3 - 1) * 0.2
-
-
= 80000000.0 bytes/s
-
-
=76.3MB/s
-
-
NOutwrite = 200000 * 1000 * (3 - 1) * 0.2
-
-
= 120000000.0 bytes/s
-
-
=76.3MB/s
4.3.3 Compaction
Compaction 比較複雜,在有預分割槽不考慮 Split 的情況下分為兩類:
-
Major Compaction
-
Minor Compaction
兩者是獨立的,下面將分別針對兩種 Compaction 做分析,最後取和。
4.3.3.1 Major Compaction
Major Compaction 的定義是由全部 HFile 參與的 Compaction, 一般在發生在 Split 後發生,或者到達系統的 MajorCompaction 週期, 預設的 MajorCompaction 週期為 20 天,這裡我們暫時忽略 Split 造成的 MajorCompaction 流量. 最終 Major Compaction 開銷相關的變數是:
-
單機資料量水位 D
-
HFIle 副本數 R1
-
MajorCompaction 週期 → M (預設 20 天)
這裡假設資料是有本地化的,所以 MajorCompaction 的讀過程,走 ShortCircuit,不計算網路開銷,並且寫 HFile 的第一副本是本地流量,也不做流量計算,所以 MajorCompaction 的網路流量計算公式是:
NInMajor = D * (R1 - 1) / M
NOutMajor = D * (R1 - 1) / M
假設 D = 10T, R1 = 3, M = 20
-
NInMajor = 10 * 1024 * 1024 * 1024 * 1024 * (3 - 1) / (20 * 86400)
-
-
= 12725829bytes/s
-
-
= 12MB/s
-
-
NOutMajor = 10 * 1024 * 1024 * 1024 * 1024 * (3 - 1) / (20 * 86400)
-
-
= 12725829bytes /s
-
-
= 12MB/s
4.3.3.2 Minor Compaction
量化之前,先問一個問題,每條資料在第一次 flush 成為 HFile 之後,會經過多少次 Minor Compaction?
要回答這個問題之前,要先了解現在 HBase 預設的 compaction 的檔案選取策略,這裡不展開,只做簡單分析,MinorCompaction 選擇的檔案物件數目,一般處於 hbase.hstore.compaction.min(預設 3)和 hbase.hstore.compaction.max(預設 10)之間, 總檔案大小小於 hbase.hstore.compaction.max.size(預設 Max), 如果檔案的 Size 小於 hbase.hstore.compaction.min.size(預設是 flushsize), 則一定會被選中; 並且被選中的檔案 size 的差距不會過大, 這個由引數 hbase.hstore.compaction.ratio 和 hbase.hstore.compaction.ratio.offpeak 控制,這裡不做展開。
所以,在 Compaction 沒有積壓的情況下,每次 compaction 選中的檔案數目會等於 hbase.hstore.compaction.min 並且檔案 size 應該相同量級, 對穩定的表,對每條資料來說,經過的 compaction 次數越多,其檔案會越大. 其中每條資料參與 Minor Compaction 的最大次數可以用公式 math.log( 32000 / 25.6, 3) = 6 得到
這裡用到的兩個變數是:
-
FlushSize 預設是 128 MB
-
HFile 壓縮比例,假設是 0.2
所以剛剛 Flush 生成的 HFile 的大小在 25.6MB 左右,當集齊三個 25.6MB 的 HFile 後,會觸發第一次 Minor Compaction, 生成一個 76.8MB 左右的 HFile。
對於一般情況,單個 Region 的檔案 Size 我們會根據容量預分割槽好,並且控制單個 Region 的 HFile 的總大小 在 32G 以內,對於一個 Memstore 128MB, HFile 壓縮比 0.2, 單個 Region 32G 的表,上表中各個 Size 的 HFile 數目不會超過 2 個(否則就滿足了觸發 Minor Compaction 的條件)。
32G = 18.6G + 6.2G + 6.2G + 690MB + 230MB + 76.8MB + 76.8MB
到這裡,我們知道每條寫入的資料,從寫入到 TTL 過期,經過 Minor Compaction 的次數是可以計算出來的。所以只要計算出每次 Compaction 的網路開銷,就可以計算出,HBase 通過次要壓縮消化每條資料,所佔用的總的開銷是多少,這裡用到的變數有:
-
單條資料大小s
-
峰值寫入T.
-
HFIle副本數R1
-
HFile壓縮比C
計算公式如下:
NInMinor = S * T *(R1-1)* C *總次數
NOutMinor = S * T *(R1-1)* C *總次數
假設S = 1000,T = 20W,R1 = 3,C = 0.2,總次數= 6
-
NInminor = 1000 * 200000 * (3 - 1) * 0.2 * 6
-
-
= 480000000.0bytes/s
-
-
= 457.8MB/s
-
-
NOutminor = 1000 * 200000 * (3 - 1) * 0.2 * 6
-
-
= 480000000.0bytes/s
-
-
= 457.8MB/s
4.3.4 網路資源定量分析小結
在使用者寫入 TPS 20W,單條資料大小 1000 bytes 的場景下,整體網路吞吐為:
-
NIntotal = NInwrite + NInflush + NInmajor + NInminor
-
-
= 572MB/s + 76.3MB/s + 12MB/s + 457.8MB/s
-
-
= 1118.1MB/s
-
-
NOuttotal = NOutwrite + NOutflush + NOutmajor + NOutminor
-
-
= 381MB/s + 76.3MB/s + 12MB/s + 457.8MB/s
-
-
= 927.1MB
當然這是理想情況下的最小開銷,有很多種情況,可以導致實際網路開銷超過這個理論值,以下情況都會導致實際流量的升高:
-
預分割槽不足或者業務量增長,導致 Region 發生 Split,Split 會導致額外的 Compaction 操作
-
分割槽寫入不平均,導致少量 region 不是因為到達了 flushsize 而進行 flush,導致 flush 下來的檔案 Size 偏小
-
HFile 因為 balance 等原因導致本地化率低,也會導致 compaciton 產生更多的網路卡開銷
-
預分割槽數目過多,導致全域性 memstore 水位高,memstore 沒辦法到達 flushsize 進行 flush,從而全域性都 flush 出比較小的檔案
-
等等
有了這個量化分析後,這些不深入展開,簡單說幾點已經在有贊生產環境得到驗證具有實效的優化點:
-
業務接入初期,協助業務做 Rowkey 的設計,避免寫入熱點
-
增加 hbase.hstore.compaction.min,增加每次 Compaction 參加的檔案數,相當於減少了每條資料整個生命週期經歷過的 Compaction 次數
-
根據業務穩態的規模,做好預分割槽,儘量減少 Split 造成的額外開銷
-
對於讀 RT 不敏感的業務,可以設定 hbase.hstore.compaction.max.size 為 4g,儘可能減少過大的檔案做 Compaction,因為大檔案做 compaction 的 ROI 實在太低
-
對於沒有多版本並且有 TTL 的資料,可以關閉系統的 MajorCompaction 週期,資料過期採用檔案整體過期的方式,消除 MajorCompaction 的系統開銷
-
對於吞吐大的場景,使用者在寫入資料的時候就對資料做壓縮,減小寫路徑造成的網路開銷,畢竟 WAL 是不能壓縮的(壓縮功能形同虛設)
-
調整 Memstore 的記憶體比例,保證單機上每個 region 儘可能的分配到 Flushsize 大小的記憶體,儘可能的 flush 大檔案,從而減少後續 Compaction 開銷
五、總結
到這裡,HBase 的寫吞吐場景的資源定量分析和優化的介紹就算結束了,本文基於 HBase1.2.6 版本。對很多 HBase 的細節沒有做展開說明,有些地方因為作者認知有限,難免紕漏,歡迎各位同行指出。
在這裡相信有許多想要學習大資料的同學,大家可以+下大資料學習裙:957205962,即可免費領取套系統的大資料學習教程
相關文章
- HBase寫吞吐場景資源消耗量化分析及優化優化
- 高頻寫入redis場景優化Redis優化
- JVM之調優及常見場景分析JVM
- Hbase原理的介紹和使用場景分析
- 資料分析:複雜業務場景下,量化評估流程
- Hbase優化優化
- MongoDB、Hbase、Redis等NoSQL優劣勢、應用場景MongoDBRedisSQL
- HBase記憶體配置及JVM優化記憶體JVM優化
- HTAP資料庫及應用場景分析資料庫
- 協程及非同步載入資源場景非同步
- Redis 5種資料結構 及使用場景分析Redis資料結構
- Web靜態資源快取及優化Web快取優化
- HBase查詢優化優化
- EOS基礎1:賬戶註冊及資源消耗
- 三種雲原生儲存方案優缺點及應用場景分析
- Redis的應用場景及優缺點Redis
- 儀表盤場景的前端優化前端優化
- 大資料分析: SAP Sybase IQ功能特性及適用場景大資料
- Mysql慢SQL分析及優化MySql優化
- 桌面客戶端效能提升,最佳化使用資源消耗客戶端
- etcd 在超大規模資料場景下的效能優化優化
- HBase建模、使用以及優化優化
- Apache HBase MTTR 優化實踐Apache優化
- 淘特 Flutter 流式場景的深度優化Flutter優化
- 銀行業資料長期保留的需求場景及策略分析行業
- Chrome 外掛特性及實戰場景案例分析Chrome
- 如何使用HBase?大資料儲存的兩個實戰場景大資料
- SQL 抽象語法樹及改寫場景應用SQL抽象語法樹
- SQL抽象語法樹及改寫場景應用SQL抽象語法樹
- 大量索引場景下 Easysearch 和 Elasticsearch 的吞吐量差異索引Elasticsearch
- memcached 和 redis 使用場景及優缺點對比Redis
- Hbase和Hive的特點,和應用場景Hive
- 圖資料庫及應用場景資料庫
- HBase資料的讀寫流程
- 優化動畫卡頓:卡頓原因分析及優化方案優化動畫
- 分散式系統選主場景分析及實現分散式
- MySQL資料SQL優化中,索引不被使用的典型場景總結MySql優化索引
- 使用Android Profile做效能分析及優化Android優化