HBase2.0重新定義小物件實時存取
小物件,特別指1K~10MB範圍的資料,比如圖片,短視訊,文件等。這些資料廣泛的存在於人工智慧,醫療,教育,生活分享,電子商務等領域。目前物件儲存典型技術方案為AWS的S3以及阿里雲的OSS,還有一些基於SQL/">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儲存在物件儲存,通過一個引用列進行關聯
查詢實現:
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
使用HBase作為儲存,將每個組的資料儲存在同一行,設計如下:
Rowkey | 普通列 | 普通列 | 普通列 | 普通列 |
---|---|---|---|---|
組ID | 人臉ID1 | 人臉ID2 | ... | 人臉IDn |
查詢時通過一次請求即可獲取所有人臉: Table.get(組ID),1000張臉耗時20ms
案例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官網