1. 起源

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

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

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

2. 協(xié)處理器有兩種: observer 和 endpoint

1) observer 協(xié)處理器

Observer 類似于傳統(tǒng)數(shù)據(jù)庫中的觸發(fā)器,當發(fā)生某些事件的時候這類協(xié)處理器會被?Server 端調(diào)用。

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

比如: put 操作之前有鉤子函數(shù) prePut,該函數(shù)在 put 操作執(zhí)行前會被 Region Server 調(diào)用;在 put 操作之后則有 postPut 鉤子函數(shù)。

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

  • RegionObserver:提供客戶端的數(shù)據(jù)操縱事件鉤子:?Get、?Put、?Delete、?Scan?等。
  • WALObserver:提供?WAL?相關(guān)操作鉤子。
  • MasterObserver:提供?DDL-類型的操作鉤子。如創(chuàng)建、刪除、修改數(shù)據(jù)表等。

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

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

2) endpoint 協(xié)處理器

Endpoint 協(xié)處理器類似傳統(tǒng)數(shù)據(jù)庫中的存儲過程,客戶端可以調(diào)用這些 Endpoint 協(xié)處理器執(zhí)行一段 Server 端代碼,并將 Server 端代碼的結(jié)果返回給客戶端進一步處理,最常見的用法就是進行聚集操作。

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

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

下圖是 EndPoint 的工作原理:

3. 協(xié)處理器加載方式?

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

靜態(tài)加載的協(xié)處理器稱之為 System Coprocessor

動態(tài)加載的協(xié)處理器稱之為 Table Coprocessor。

1) 靜態(tài)加載?

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

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

2) 動態(tài)加載

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

disable 指定表

hbase> disable mytable

添加 aggregation

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

重啟指定表

hbase> enable mytable

協(xié)處理器卸載

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

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

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

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

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

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