HBase數據壓縮編碼探索


摘要: 本文主要介紹了hbase對數據壓縮,編碼的支持,以及雲hbase在社區基礎上對數據壓縮率和訪問速度上了進行的改進。

前言

你可曾遇到這種需求,只有幾百qps的冷數據緩存,卻因為存儲水位要浪費幾十台服務器?你可曾遇到這種需求,幾百G的表,必須純cache命中,性能才能滿足業務需求?你可曾遇到,幾十M的小表,由於qps過高,必須不停的split,balance,利用多台服務器來抗熱點? 
面對繁雜的場景,Ali-HBase團隊一直致力於為業務提供更多的選擇和更低的成本。本文主要介紹了hbase目前兩種提高壓縮率的主要方法:壓縮和DataBlockEncoding。

無損壓縮:更小,更快,更省資源

通用壓縮作為數據庫解決存儲的重要手段,通常數據庫都存在數據塊的概念,針對每個塊做壓縮和解壓。塊越大,壓縮率越高,scan throughput增加;塊越小,隨機讀IO壓力較小,讀latency越小。作為一種Tradeoff,線上hbase通常采用64K塊大小,在cache中不做壓縮,僅在落盤和讀盤時做壓縮和解壓操作。

開源hbase通常使用的LZO壓縮或者Snappy壓縮。這兩種壓縮的共同特點是都追求較高的壓縮解壓速度,並實現合理的數據壓縮率。然而,隨着業務的快速增漲,越來越多的業務因為因為存儲水位問題而擴容。hbase針對這一情況,采用了基於跨集群分區恢復技術的副本數優化、機型升級等方法,但依然無法滿足存儲量的快速膨脹,因此我們一直致力於尋找壓縮更高的壓縮方式。

新壓縮(zstd、lz4)上線

Zstandard(縮寫為Zstd)是一種新的無損壓縮算法,旨在提供快速壓縮,並實現高壓縮比。它既不像LZMA和ZPAQ那樣追求盡可能高的壓縮比,也不像LZ4那樣追求極致的壓縮速度。這種算法的壓縮速度超過200MB/s, 解壓速度超過400MB/s(實驗室數據),基本可以滿足目前hbase對吞吐量的需求。經驗證,Zstd的數據壓縮率相對於Lzo基本可以提高25%-30%,對於存儲型業務,這就意味着三分之一到四分之一的的成本減少。

而在另一種情況下,部分表存儲量較小,但qps大,對rt要求極高。針對這種場景,我們引入了lz4壓縮,其解壓速度在部分場景下可以達到lzo的兩倍以上。一旦讀操作落盤需要解壓縮,lz4解壓的rt和cpu開銷都明顯小於lzo壓縮。

我們先通過一張圖片直觀的展示各種壓縮算法的性能: 
compress1

compress2

以線上幾種典型數據場景為例,看看幾種壓縮的實際壓縮率和單核解壓速度(以下數據均來自於實際應用)

業務類型 無壓縮表大小 LZO(壓縮率/解壓速度MB/s) ZSTD(壓縮率/解壓速度MB/s) LZ4(壓縮率/解壓速度MB/s)
監控類 419.75T 5.82/372 13.09/256 5.19/463.8
日志類 77.26T 4.11/333 6.0/287 4.16/ 496.1
風控類 147.83T 4.29/297.7 5.93/270 4.19/441.38
消費類 108.04T 5.93/316.8 10.51/288.3 5.55/520.3

目前,2017年雙11,ZSTD已經在線上全面鋪開,已累計優化存儲數PB。LZ4也已經在部分讀要求較高業務上線。 
下圖為某監控類應用zstd壓縮算法后,集群整體存儲量的下降情況。數據量由100+T減少到75T。

result

編碼技術:針對結構化數據的即查即解壓

hbase作為一種schema free的數據庫,相當於傳統的關系型數據庫更加靈活,用戶無需設計好表的結構,也可以在同一張表內寫入不同schema的數據。然而,由於缺少數據結構的支持,hbase需要很多額外的數據結構來標注長度信息,且無法針對不同的數據類型采用不同的壓縮方式。針對這一問題,hbase提出了編碼功能,用來降低存儲開銷。由於編碼對cpu開銷較小,且效果較好,通常cache中也會開啟編碼功能。

舊DIFF Encoding介紹

hbase很早就支持了DataBlockEncoding,也就是是通過減少hbase keyvalue中重復的部分來壓縮數據。 以線上最常見的DIFF算法為例,某kv壓縮之后的結果:

  • 一個字節的flag(這個flag的作用后面解釋)
  • 如果和上個KV的鍵長不一樣,則寫入1~5個字節的長度
  • 如果和上個KV的值長不一樣,則寫入1~5個字節的長度
  • 記錄和上個KV鍵相同的前綴長度,1~5個字節
  • 非前綴部分的row key
  • 如果是第一條KV,寫入列族名
  • 非前綴部分的的列名
  • 寫入1~8字節的timestamp或者與上個KV的timestamp的差(是原值還是寫與上個KV的差,取決於哪個字節更小)
  • 如果和上個KV的type不一樣,則寫入1字節的type(Put,Delete)
  • Value內容

那么在解壓縮時,怎么判斷和上個KV的鍵長是否一樣,值長是否一樣,寫入的時間戳究竟是是原值還是差值呢?這些都是通過最早寫入的1個字節的flag來實現的, 
這個字節中的8位bit,含義是:

  • 第0位,如果為1,鍵長與上個kv相等
  • 第1位,如果為1,值長與上個kv相等
  • 第2位,如果為1,type與上個kv一樣
  • 第3位,如果為1,則寫入的timestamp是差值,否則為原值
  • 第456位,這3位組合起來的值(能表示0~7),表示寫入的時間戳的長度
  • 第7位,如果為1,表示寫入的timestamp差值為負數,取了絕對值。

diff

DIFF 編碼之后,對某個文件的seek包含以下兩步:

  1. 通過index key找到對應的datablock
  2. 從第一個完整KV開始,順序查找,不斷decode下一個kv,直到找到目標kv為止。

DIFF encoding對小kv場景使用效果較好,可以減少2-5倍的數據量。

新Indexable Delta Encoding上線

從性能角度考慮,hbase通常需要將Meta信息裝載進block cache。如果將block大小較小,Meta信息較多,會出現Meta無法完全裝入Cache的情況, 性能下降。如果block大小較大,DIFF Encoding順序查詢的性能會成為隨機讀的性能瓶頸。針對這一情況,我們開發了Indexable Delta Encoding,在block內部也可以通過索引進行快速查詢,seek性能有了較大提高。Indexable Delta Encoding原理如圖所示:

index

在通過BlockIndex找到對應的數據塊后,我們從數據塊末尾找到每個完整KV的offset,並利用二分查找快速定位到符合查詢條件的完整kv,再順序decode每一個Diff kv,直到找到目標kv位置。

通過Indexable Delta Encoding, HFile的隨機seek性能相對於使用之前翻了一倍,以64K block為例,在全cache命中的隨機Get場景下,相對於Diff encoding rt下降50%,但存儲開銷僅僅提高3-5%。Indexable Delta Encoding目前已在線上多個場景應用,經受了雙十一的考驗,整體平均讀rt減少10%-15%。

 

雲端使用

阿里HBase目前已經在阿里雲提供商業化服務,任何有需求的用戶都可以在阿里雲端使用深入改進的、一站式的HBase服務。雲HBase版本與自建HBase相比在運維、可靠性、性能、穩定性、安全、成本等方面均有很多的改進,更多內容歡迎大家關注 https://www.aliyun.com/product/hbase

轉自:https://yq.aliyun.com/articles/277084

 


交流

如果大家對HBase有興趣,致力於使用HBase解決實際的問題,歡迎加入Hbase技術社區群交流:

微信HBase技術社區群,假如微信群加不了,可以加秘書微信: SH_425 ,然后邀請您。

 

 

​  釘釘HBase技術社區群


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM