天天看點

HBase2.0重新定義小對象實時存取

小對象,特别指1K~10MB範圍的資料,比如圖檔,短視訊,文檔等。這些資料廣泛的存在于人工智能,醫療,教育,生活分享,電子商務等領域。目前對象存儲典型技術方案為AWS的S3以及阿裡雲的OSS,還有一些基于MySQL+對象存儲的二次開發方案。這些方案解決了對象存儲的可靠性和擴充性問題,但是存在一些缺陷:兩個方案都存在通路延時問題,因為通路資料至少要2次查詢,一次索引通路+一次資料通路,特别的當使用者想查詢一組有關聯資料的時候,需要N次調用;對象存儲很難将對象和一些次元、名額資料混合存儲,而這些是查詢時過濾資料的條件,導緻對象存儲的方案在檢索能力上不足;MySQL+對象存儲方案将次元、名額資料存儲在Mysql解決了檢索能力,但是引入了資料不一緻問題,實作主備雙活也非常困難,造成可用性上的缺陷,同時這個方案對使用者代碼侵入大,對運維也不友好。本文将介紹一種全新的小對象實時存取解決方案:HBase2.0,在MOB技術的加持下,HBase2.0将重新定義小對象實時存取,消除以上兩個方案的缺陷,具有低延遲,讀寫強一緻,檢索能力強,水準易擴充等關鍵能力

本文将以一條sql展開小對象實時存取的方案演進,介紹不同架構的優缺點。然後提供人工智能和醫療方面兩個采用HBase2.0的案例分析。最後總結小對象實時存取的最佳實踐。

查詢場景定義

使用者表T:包含三個屬性S1、S2、S3,屬性的大小為50bytes左右,包含一個對象資料Object從100KB~10MB

查詢:以S1、S2、S3為條件查詢Object

select Object from T where S1 = xxx and S2 > yyy and S3 < zzz           

對象存儲解決方案

對象存儲的模型是KV,設計邏輯表為:S1+S2+S3 => Object,将S1、S2、S3組合成一個key

查詢實作

// Bucket是對象存儲概念,可以了解為對象的一個集合或者表
// 對象存儲支援字首檢索,下面表示按“S1 = xxx and S2 > yyy”查找中繼資料
List keys = GetBucket(key >= xxx+yyy)

// 使用者需要自己寫代碼實作對S3屬性列的條件過濾
filterByS3(keys, zzz)

// 依次讀取出Object
for(key : keys) {
   GetObject(key);
   // do something
}           

對象存儲總結:

優勢:

  • 讀寫強一緻
  • 支援水準擴充

劣勢:

  • 實時性差,一次請求要查詢N次伺服器(一次檢索對象清單+n次對象讀取)
  • 檢索能力不足,僅支援key的字首檢索,還需要使用者端增加檢索邏輯;
  • 當屬性列增多,特别是動态增加的情況下,對象存儲很難支援(key會變得非常複雜)

MySQL+對象存儲解決方案

将屬性列存儲在MySQL,Object存儲在對象存儲,通過一個引用列進行關聯

HBase2.0重新定義小對象實時存取

查詢實作:

List references = select reference from T where S1 = xxx and S2 > yyy and S3 < zzz

// 依次讀取出Object
for(Key : references) {
   oss.GetObject(key);
   // do something
}           

MySQL+對象存儲總結:

  • 檢索能力強
  • 支援索引
  • 實時性差,一次請求要查詢N次伺服器(1次查MySQL+n次查對象存儲)
  • 讀寫存在不一緻問題,需要額外的開發保證寫MySQL和寫對象存儲的事務一緻性
  • 不支援動态屬性列的增加
  • 運維複雜

HBase解決方案

S1+S2組合作為Rowkey存儲,S3屬性和Object作為普通列

Rowkey 普通列
S1+S2 S3 Object
Scan scan = new Scan();
scan.setStartKey(S1+S2); // 按S1+S2字首查詢
scan.setFilter(S3); // 利用Filter過濾S3
scan.addColumn(Object); // 傳回Object列
List objects = T.scan(scan); // 一次查詢即傳回所有結果           

HBase方案總結:

優勢

  • 實時查詢,延遲低
  • 檢索能力強:支援過濾器Filter;支援索引(通過Phoenix提供索引能力)
  • 業務代碼簡潔
  • 支援動态列,可以随意增加屬性列
  • 易于維護

HBase2.0 小對象存儲經典案例

下面通過兩個案例介紹HBase2.0給業務帶來的改變與價值

案例1:某人工智能公司,利用HBase實作查詢延遲從10秒提升到20ms,性能提升500倍,滿足了業務對實時查詢的強需求。

場景:存儲人臉圖檔資料,每個臉有一個ID,人臉按一定邏輯進行分組;請求場景為讀取每個組的全量資料

1、其中 45% 左右的組含有1張人臉

2、45%左右的組含有 2 ~ 9張人臉資料

3、其餘的組人臉數範圍為 10 ~ 10019

4、其中每個臉2.4k

優化前架構為MySQL+OSS,當一個組有1000張人臉時,查詢大概在10s

HBase2.0重新定義小對象實時存取

使用HBase作為存儲,将每個組的資料存儲在同一行,設計如下:

組ID 人臉ID1 人臉ID2 ... 人臉IDn

查詢時通過一次請求即可擷取所有人臉:Table.get(組ID),1000張臉耗時20ms

HBase2.0重新定義小對象實時存取

案例2:某醫療公司,HBase解決10億規模,200TB檢驗報告資料的實時存取需求

場景:查詢某個使用者最近的一次檢查報告;或者查詢某個使用者的多個曆史檢查報告

1、使用者規模10億+

2、每一個使用者會有一個或多個檢查報告,每一個報告會有一個時間戳

3、其中每一個報告在200KB左右

4、要求存儲可以水準擴充

HBase表設計

rowkey
使用者ID +(Long.max-時間戳) 檢查報告

查詢

  • 查詢某個使用者最近的一次檢查報告:Scan(使用者ID).Limit(1)
  • 查詢某個使用者的多個曆史檢查報告:Scan(使用者ID).Limit(N)

HBase小對象存儲最佳實踐

  • 20KB一下的小對象直接存儲,50KB以上的小對象需要開啟MOB特性,20KB~50KB之間的情況按需開啟MOB并調整MOB的門檻值大小(操作方式在下面)
  • 對于邏輯上關聯的對象,特别是查詢時經常一起傳回的,可以考慮存儲在同行不同列;或者保持相同的rowkey字首,這樣可以通過一個Scan來查詢資料
  • 對于屬性列非常多,查詢條件複雜的場景,可以利用Phoenix建構索引
  • 把屬性列和對象列放在不同的column family下

MOB特性介紹

MOB在HBase2.0版本引入,解決了HBase在存儲小對象上的寫放大問題,關于MOB技術原理已經有文章介紹:

MOB技術原理

MOB是服務端功能,如果使用者使用雲HBase則不需要關心細節,隻需要提出需求即可;如果是自己運維,那麼開啟MOB功能僅需要一條指令:alter 't1', {NAME => 'f1', IS_MOB => true, MOB_THRESHOLD => 

102400} 其中IS_MOB表示開啟功能,MOB_THRESHOLD表示多大的資料被認為是MOB對象,機關是byte

總結

HBase2.0重新定義了小對象實時存取的業務通路方式,不再是索引+對象的多次查詢,提供簡潔的一體化解決方案。具有低延遲,讀寫強一緻,檢索能力強,水準易擴充等關鍵能力;并且具備動态列,多版本等靈活的功能;最後一體化的解決方案簡化了使用者端的代碼,也減少了服務端的運維成本。

未來展望:資料的快速響應能力是支援實時業務的核心,但是同時成本也是業務保持競争優勢的關鍵。對象存儲通常具有較大規模,幾百TB是常見。資料天然具有冷熱之分,利用這一點,HBase可以内部對資料進行劃分,将通路頻率低的資料轉移到OSS以獲得更低的存儲成本。同時,在對象資料的大小分布不均的場景中,HBase可以将超大資料存儲在OSS,降低長尾資料的影響。以上的工作都會對業務透明。

最後歡迎大家體驗HBase2.0,點選進入

阿裡雲HBase2.0官網

繼續閱讀