HBase協處理器入門(1.2.0-cdh5.8.0版本)

注:本文示例來源於《HBase不睡覺書》第六章 6.2協處理器,文中HBase版本爲1.2.2,本文采用1.2.0-cdh5.8.0。
=================================================
需求:
        當插入數據時,如果遇到單元格爲mycf:name=JACK,則在mycf:message這個列插入一句話:Hello World! Welcome back!。這個需求在關係型數據庫中使用觸發器來實現。在HBase中我們使用協處理器來實現。
step1
    新建maven項目,打包方式選擇jar。原生版本只需添加hbase-server依賴(不要同時添加hbase-client依賴)。而cdh版本需要同時添加hbase-server、hbase-client,hbase-common以及guava包。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.idayan</groupId>
  <artifactId>coprocessor</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>coprocessor</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.apache.hbase</groupId>
      <artifactId>hbase-server</artifactId>
      <version>1.2.0-cdh5.8.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hbase</groupId>
      <artifactId>hbase-client</artifactId>
      <version>1.2.0-cdh5.8.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hbase</groupId>
      <artifactId>hbase-common</artifactId>
      <version>1.2.0-cdh5.8.0</version>
    </dependency>
    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>12.0.1</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

step 2

        新建類:HelloWorldObserver雖然所有的協處理器都要實現接口Coprocessor,但是實現接口需要實現很多不必要的方法。所以我選擇直接繼承BaseRegionObserver類,這樣很多方法都有了基本你的實現,我們只需要重寫需要的方法即可。

step 3

 編碼:

HelloWorldObserver.java

package com.idayan;

import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.client.Durability;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.List;

/**
 * @author: xianghu.wang
 * @Date: 2018/3/15
 * @Description:
 */
public class HelloWorldObserver extends BaseRegionObserver{

    public static final String JACK = "JACK";

    /**
     * 重寫prePut方法。
     * 這個方法會在Put動作之前進行操作
     * @param e
     * @param put
     * @param edit
     * @param durability
     * @throws IOException
     */
    @Override
    public void prePut(ObserverContext<RegionCoprocessorEnvironment> e,
                       Put put, WALEdit edit, Durability durability) throws IOException {

        //獲取mycf:name的單元格
        List<Cell> name = put.get(Bytes.toBytes("mycf"),Bytes.toBytes("name"));

        //如果該put中不存在mycf:name,則不作操作,這個單元格直接返回
        if (name == null || name.size() == 0) {
            return;
        }

        //如果該put中存在mycf:name,則判斷mycf:name是否爲JACK
        if (JACK.equals(Bytes.toString(CellUtil.cloneValue(name.get(0))))) {
            //如果mycf:name是JACK,則在mycf:message中添加一句話
            put.addColumn(Bytes.toBytes("mycf"),Bytes.toBytes("message"),Bytes.toBytes("Hello World! Welcome back !"));
        }

    }
}
step 4
打包,放到HDFS上。我的jar包名是coprocessor-1.0-SNAPSHOT.jar,上傳到HDFS目錄下。

[maxiu@idayan00 hadoop-2.6.0-cdh5.8.0]$ bin/hdfs dfs -put /home/maxiu/myData/coprocessor-1.0-SNAPSHOT.jar /user/maxiu
18/03/15 11:09:20 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
[maxiu@idayan00 hadoop-2.6.0-cdh5.8.0]$ bin/hdfs dfs -ls /user/maxiu
18/03/15 11:10:03 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 1 items
-rw-r--r--   1 maxiu supergroup       2844 2018-03-15 11:09 /user/maxiu/coprocessor-1.0-SNAPSHOT.jar
我的jar:鏈接:https://pan.baidu.com/s/1vUw66lCjypE0EO8O3aO-5Q 密碼:8wdm
step5
在HBase中啓用這個觀察者,登錄服務器,使用hbase shell 執行以下命令:
hbase(main):002:0> create 'mytable','mycf' //創建表
0 row(s) in 1.5240 seconds

=> Hbase::Table - mytable
hbase(main):003:0> alter 'mytable' , METHOD =>'table_att','coprocessor'=>'hdfs://idayan00//user/maxiu/coprocessor-1.0-SNAPSHOT.jar|com.idayan.HelloWorldObserver||'
Updating all regions with the new schema... //啓用協處理器
1/1 regions updated.
Done.
0 row(s) in 2.5410 seconds

hbase(main):004:0> desc 'mytable' //查看錶屬性
Table mytable is ENABLED                                                                                                                                                                                                                                                      
mytable, {TABLE_ATTRIBUTES => {coprocessor$1 => 'hdfs://idayan00//user/maxiu/coprocessor-1.0-SNAPSHOT.jar|com.idayan.HelloWorldObserver||'}                                                                                                                                   
COLUMN FAMILIES DESCRIPTION                                                                                                                                                                                                                                                   
{NAME => 'mycf', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'
}                                                                                                                                                                                                                                                                             
1 row(s) in 0.0490 seconds

hbase(main):005:0>
  • table_att是固定詞組,意思就是調用setValue()方法給表設置屬性
  • 屬性名爲 coprocessor,就是協處理器的意思
  • 屬性值爲<包所在路徑>|<協處理器類全名>||,並且中間不能有空格。
如果想刪除該協處理器可以執行以下命令:
hbase(main):005:0> alter 'mytable',METHOD =>'table_att_unset',NAME => 'coprocessor$1'
Updating all regions with the new schema...
1/1 regions updated.
Done.
0 row(s) in 2.5900 seconds
測試協處理器
    現在嘗試用Java API來添加包含有mycf:name=JACK的數據
Put put = new Put(Bytes.toBytes("row1"));

put.addColumn(Bytes.toBytes("mycf"),Bytes.toBytes("name"),Bytes.toBytes("JACK"));

table.put(put);
查看結果:

通過hbase shell 添加數據:
put 'mytable','row2','mycf:name','JACK'

可以看到通過java api 和hbase shell添加數據 協處理器都生效了。

下面我們再添加一條名字不是JACK的
put 'mytable','row3','mycf:name','MAXIU'

可以看到第三行只有一條記錄,並沒有在message那一列添加數據。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章