讀書筆記-HBase in Action-第二部分Advanced concepts-(2)Coprocessor

來源:互聯網
上載者:User

標籤:hbase   coprocessor   擴充   

Coprocessor是HBase 0.92.0引入的特性。使用Coprocessor,可以將一些計算邏輯下推到HBase節點,HBase由一個單純的儲存系統升級為分布式資料處理平台。

Coprocessor分為兩種:Observer和Endpoint。Observer能修改擴充已有的用戶端操作功能,而Endpoint能引入新的用戶端操作。

Observer

Observer的作用類似於資料庫的觸發器或者AOP中的advice。為Put操作增加Observer,其中1-2-4-6是一次正常的Put操作RPC調用過程,而3和5屬於Observer,可以在Put操作之前和之後加入自訂處理邏輯。


Observer包括三種,RegionObserver(針對資料訪問和更新操作,運行在Region上)/WALObserver(針對WAL日誌事件,運行在RegionServer上下文)/MasterObserver(針對DDL操作,運行在Master節點)。

Endpoint

Endpoint的作用則類似於資料庫預存程序。實現機制是通過擴充HBase RPC協議,給用戶端暴露新的操作介面。如,用戶端負責發起調用和收集結果,服務端各節點負責並行計算。


實戰

以上一章的follows表為例,通過Observer實現followedBy被關注表資料一致性維護,Endpoint實現關注人數量統計。

因為要實現在插入follows表時自動插入followedBy表,需要用到關注人/被關注人使用者名稱資訊,所以首先升級schema。


實現Observer

代碼中有三處注釋值得注意:

  1. postPut方法在put操作之後被調用。
  2. 如果通過hbase-site.xml安裝Observer,會應用到全域所有表,所以這裡判斷put操作的是否follows表。
  3. 這裡有點bad smell。Observer運行在伺服器端,為了共用代碼,又調用用戶端代碼,僅為示範作用。

packageHBaseIA.TwitBase.coprocessors;//…publicclass FollowsObserver extends BaseRegionObserver {    private HTablePool pool = null;    @Override    public void start(CoprocessorEnvironment env)throws IOException {        pool = newHTablePool(env.getConfiguration(), Integer.MAX_VALUE);    }    @Override    public void stop(CoprocessorEnvironment env)throws IOException {        pool.close();    }    @Override    public void postPut(//1,在Put操作之後調用            finalObserverContext<RegionCoprocessorEnvironment> e,            final Put put,            final WALEdit edit,            final boolean writeToWAL) throws IOException {        byte[] table=e.getEnvironment().getRegion().getRegionInfo().getTableName();        if (!Bytes.equals(table,FOLLOWS_TABLE_NAME))             return;  //2,判斷表名        KeyValue kv =put.get(RELATION_FAM, FROM).get(0);        String from =Bytes.toString(kv.getValue());        kv = put.get(RELATION_FAM,TO).get(0);        String to =Bytes.toString(kv.getValue());        RelationsDAO relations = newRelationsDAO(pool);        relations.addFollowedBy(to,from);//3,插入followedBy表    }}
Observer的安裝可以通過修改hbase-site.xml或者使用tableschema修改陳述式完成,前者需要重啟HBase服務,後者只需要重新上下線對應表。

$ hbase shellHBaseShell; enter 'help<RETURN>' for list of supported commands.Type"exit<RETURN>" to leave the HBase ShellVersion0.92.0, r1231986, Mon Jan 16 13:16:35 UTC 2012hbase(main):001:0>disable 'follows'0 row(s) in 7.0560 secondshbase(main):002:0>alter 'follows', METHOD => 'table_att','coprocessor'=>'file:///Users/ndimiduk/repos/hbaseiatwitbase/target/twitbase-1.0.0.jar|HBaseIA.TwitBase.coprocessors.FollowsObserver|1001|'Updatingall regions with the new schema...1/1regions updated.Done.0 row(s) in 1.0770 secondshbase(main):003:0>enable 'follows'0 row(s) in 2.0760 seconds

其中1001為優先順序,當載入多個Observer時,按照優先順序次序運行。

實現Endpoint

關注人數量統計可以通過用戶端Scan實現,相比Endpoint方案,有兩個待改進點:

  1. 傳輸所有關注人到用戶端,不必要的網路I/O。
  2. 拿到所有關注人Result結果後,遍曆實現計數是單線程的。

實現Endpoint包括三部分

定義PRC介面

publicinterface RelationCountProtocol extends CoprocessorProtocol {    public long followedByCount(String userId) throwsIOException;}
服務端實現

和用戶端不同,InternalScanner運行在特定Region上,返回的是原始的KeyValue對象。

packageHBaseIA.TwitBase.coprocessors;//…publicclass RelationCountImpl extends BaseEndpointCoprocessor implementsRelationCountProtocol {    @Override    public longfollowedByCount(String userId) throws IOException {        byte[]startkey = Md5Utils.md5sum(userId);        Scan scan = newScan(startkey);        scan.setFilter(newPrefixFilter(startkey));        scan.addColumn(RELATION_FAM,FROM);        scan.setMaxVersions(1);        RegionCoprocessorEnvironmentenv= (RegionCoprocessorEnvironment)getEnvironment();        InternalScanner scanner =env.getRegion().getScanner(scan);//1,伺服器端        long sum = 0;        List<KeyValue> results= new ArrayList<KeyValue>();        boolean hasMore = false;        do {            hasMore =scanner.next(results);            sum += results.size();            results.clear();        } while (hasMore);        scanner.close();        return sum;    }}
用戶端代碼

參考注釋:

  1. 定義Call執行個體 
  2. 調用服務端Endpoint。
  3. 彙總所有RegionServer得到的結果

public long followedByCount (final String userId) throws Throwable {    HTableInterface followed =pool.getTable(FOLLOWED_TABLE_NAME);    final byte[] startKey = Md5Utils.md5sum(userId);    final byte[] endKey =Arrays.copyOf(startKey, startKey.length);    endKey[endKey.length-1]++;    Batch.Call<RelationCountProtocol,Long> callable =        newBatch.Call<RelationCountProtocol, Long>() {        @Override        public Longcall(RelationCountProtocol instance) throws IOException {            returninstance.followedByCount(userId);        }    };//1 call instance    Map<byte[], Long>results = followed.coprocessorExec(                                   RelationCountProtocol.class,                                   startKey,                                   endKey,                                   callable);//2 invoke endpoint    long sum = 0;    for(Map.Entry<byte[],Long> e : results.entrySet()) {        sum +=e.getValue().longValue();    }//3 aggreagte results    return sum;}
Endpoint只能通過設定檔部署,還需要將相關jar包加入到HBase classpath。

<property>    <name>hbase.coprocessor.region.classes</name>    <value>HBaseIA.TwitBase.coprocessors.RelationCountImpl</value></property>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.