1. 起源

Hbase 作為列族數據庫最經常被人詬病的特性包括:無法輕易建立“二級索引”,難以執行求和、計數、排序等操作。

比如,在舊版本的(<0.92)Hbase 中,統計數據表的總行數,需要使用 Counter 方法,執行一次 MapReduce Job 才能得到。

雖然 HBase 在數據存儲層中集成了 MapReduce,能夠有效用于數據表的分布式計算。然而在很多情況下,做一些簡單的相加或者聚合計算的時候, 如果直接將計算過程放置在 server 端,能夠減少通訊開銷,從而獲得很好的性能提升。于是, HBase 在 0.92 之后引入了協處理器(coprocessors),實現一些激動人心的新特性:能夠輕易建立二次索引、復雜過濾器(謂詞下推)以及訪問控制等。

2. 協處理器有兩種: observer 和 endpoint

1) observer 協處理器

Observer 類似于傳統數據庫中的觸發器,當發生某些事件的時候這類協處理器會被?Server 端調用。

Observer Coprocessor 就是一些散布在 HBase Server 端代碼中的 hook 鉤子,在固定的事件發生時被調用。

比如: put 操作之前有鉤子函數 prePut,該函數在 put 操作執行前會被 Region Server 調用;在 put 操作之后則有 postPut 鉤子函數。

以?HBase0.92?版本為例,它提供了三種觀察者接口:

  • RegionObserver:提供客戶端的數據操縱事件鉤子:?Get、?Put、?Delete、?Scan?等。
  • WALObserver:提供?WAL?相關操作鉤子。
  • MasterObserver:提供?DDL-類型的操作鉤子。如創建、刪除、修改數據表等。

到?0.96?版本又新增一個?RegionServerObserver

下圖是以 RegionObserver 為例子講解 Observer 這種協處理器的原理:

2) endpoint 協處理器

Endpoint 協處理器類似傳統數據庫中的存儲過程,客戶端可以調用這些 Endpoint 協處理器執行一段 Server 端代碼,并將 Server 端代碼的結果返回給客戶端進一步處理,最常見的用法就是進行聚集操作。

如果沒有協處理器,當用戶需要找出一張表中的最大數據,即 max 聚合操作,就必須進行全表掃描,在客戶端代碼內遍歷掃描結果,并執行求最大值的操作。這樣的方法無法利用底層集群的并發能力,而將所有計算都集中到 Client 端統一執行,勢必效率低下。

利用 Coprocessor,用戶可以將求最大值的代碼部署到 HBase Server 端,HBase 將利用底層 cluster 的多個節點并發執行求最大值的操作。即在每個 Region 范圍內?執行求最大值的代碼,將每個 Region 的最大值在 Region Server 端計算出,僅僅將該 max?值返回給客戶端。在客戶端進一步將多個 Region 的最大值進一步處理而找到其中的最大值。這樣整體的執行效率就會提高很多。

下圖是 EndPoint 的工作原理:

3. 協處理器加載方式?

?協處理器的加載方式有兩種,我們稱之為靜態加載方式( Static Load)和動態加載方式( Dynamic Load)。

靜態加載的協處理器稱之為 System Coprocessor

動態加載的協處理器稱之為 Table Coprocessor。

1) 靜態加載?

通過修改 hbase-site.xml 這個文件來實現, 啟動全局 aggregation,能過操縱所有的表上的數據。只需要添加如下代碼:

hbase.coprocessor.user.region.classesorg.apache.hadoop.hbase.coprocessor.AggregateImplementation

2) 動態加載

啟用表 aggregation,只對特定的表生效。通過 HBase Shell 來實現。

disable 指定表

hbase> disable mytable

添加 aggregation

hbase> alter mytable, METHOD => table_att,coprocessor=>|org.apache.Hadoop.hbase.coprocessor.AggregateImplementation||

重啟指定表

hbase> enable mytable

協處理器卸載

disable mytablealter mytable, METHOD => table_att_unset,NAME=>coprocessor$1enable test

HBase當中的二級索引的簡要介紹

由于HBase的查詢比較弱,如果需要實現類似于 select name,salary,count(1),max(salary) from user group by name,salary order by salary 等這樣的復雜性的統計需求,基本上不可能,或者說比較困難,所以我們在使用HBase的時候,一般都會借助二級索引的方案來進行實現。

HBase的一級索引就是rowkey,我們只能通過rowkey進行檢索。如果我們相對hbase里面列族的列列進行一些組合查詢,就需要采用HBase的二級索引方案來進行多條件的查詢。

1.?MapReduce方案?
2.?ITHBASE(Indexed-Transanctional HBase)方案?
3.?IHBASE(Index HBase)方案?
4.?Hbase Coprocessor(協處理器)方案?
5.?Solr+hbase方案
6.?CCIndex(complementalclustering index)方案

常見的二級索引我們一般可以借助各種其他的方式來實現,例如Phoenix或者solr或者ES等。