您好,登錄后才能下訂單哦!
Hbase自0.92之后開始支持Coprocessor(協處理器),旨在使用戶可以將自己的代碼放在regionserver上來運行,即將計算程序移動到數據所在的位置進行運算。這一點與MapReduce的思想一致。Hbase的Coprocess分為observer和endpoint兩大類。簡單說,observer相當于關系型數據庫中的觸發器,而endpoint則相當于關系型數據庫中的存儲過程。關于HBase Coprocessor的介紹網上有很多的文檔,由于我也是剛剛學習,從很多好人貢獻的文檔上了解了很多。
這里記錄一下自己在一個完全分布式系統上部署自定義的Coprocessor的過程,本文會介紹兩種部署的方法:一種是在hbase-site.xml中配置;第二種是使用表描述符來配置(alter);前者會被所有的表的所有的region加載,而后者只會對指定的表的所有region加載。本文會結合自己的實驗過程指出哪些地方為易錯點。
首先,還是先來看下環境:
hadoop1.updb.com 192.168.0.101 Role:master
hadoop2.updb.com 192.168.0.102 Role:regionserver
hadoop3.updb.com 192.168.0.103 Role:regionserver
hadoop4.updb.com 192.168.0.104 Role:regionserver
hadoop5.updb.com 192.168.0.105 Role:regionserver
首先編碼自定義的Coprocessor,該段代碼摘自《Hbase權威指南》,只是修改了package的名字:
/** * coprocessor * 當用戶在使用get命令從表中取特定的row時,就會觸發這個自定義的observer coprocessor * 觸發條件是用戶使用get指定的rowkey與程序中指定的FIXED_ROW一致為@@@GETTIME@@@時 * 觸發后的操作是程序會在服務端生成一個keyvalue實例,并將這個實例返回給客戶端。這個kv實例是以 * @@@GETTIME@@@為rowkey,列族和列標識符均為@@@GETTIME@@@,列值為服務器端的時間 */ package org.apache.hbase.kora.coprocessor; import java.io.IOException; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.client.Get; 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.HRegion; import org.apache.hadoop.hbase.util.Bytes; public class RegionObserverExample extends BaseRegionObserver { public static final Log LOG = LogFactory.getLog(HRegion.class); public static final byte[] FIXED_ROW = Bytes.toBytes("@@@GETTIME@@@"); @Override public void preGet(ObserverContext<RegionCoprocessorEnvironment> c, Get get, List<KeyValue> result) throws IOException { LOG.debug("Got preGet for row: " + Bytes.toStringBinary(get.getRow())); if (Bytes.equals(get.getRow(), FIXED_ROW)) { KeyValue kv = new KeyValue(get.getRow(), FIXED_ROW, FIXED_ROW, Bytes.toBytes(System.currentTimeMillis())); LOG.debug("Had a match, adding fake kv: " + kv); result.add(kv); } } }
編碼完成后需要將該類編譯并打成jar包,類名上右擊--Export,彈出如下窗口
選擇JAR file,然后Next,出現如下窗口
指定jar文件的保存路徑,然后finish,就完成了RegionObserverExample類的編譯和打包,接下來就需要將打好的jar文件使用ftp的方式上傳到hbase集群的master服務器上,這里為hadoop1。
## 已經上傳到hadoop1上 [grid@hadoop1 ~]$ ls /var/ftp/pub/RegionObserverExample.jar /var/ftp/pub/RegionObserverExample.jar ## 由于是完全分布式系統,為了方便管理,我們將jar包存放到hadoop hdfs的根目錄下的jars目錄下 [grid@hadoop1 ~]$ hdfs dfs -put /var/ftp/pub/RegionObserverExample.jar /jars ## OK,驗證已經上傳成功 [grid@hadoop1 ~]$ hdfs dfs -ls /jars Found 1 items -rw-r--r-- 4 grid supergroup 3884 2014-11-15 04:46 /jars/RegionObserverExample.jar
然后需要將打好的jar包放到hbase安裝目錄下的lib目錄下,并修改hbase-site.xml配置文件
## cp jar包到hbase安裝目錄下的lib目錄,所有節點上都做這樣的操作 [grid@hadoop1 ~]$ cp /var/ftp/pub/RegionObserverExample.jar /opt/hbase-0.98.4-hadoop2/lib/ ## 然后修改hbase-site.xml文件,添加一個選項 <!-- 這里要注意value中一定要寫完整的類名(即把包名寫全),否則報ClassNotFound錯 --> <property> <name>hbase.coprocessor.region.classes</name> <value>org.apache.hbase.kora.coprocessor.RegionObserverExample</value> </property>
在master上修改配置文件完成之后,將修改后的文件scp到其他個regionserver上,然后重啟hbase使配置生效。重啟之后來看是否能夠正確的觸發
## 使用get命令從kora表中取rowkey為@@@GETTIME@@@的行 hbase(main):014:0> get 'kora', '@@@GETTIME@@@' COLUMN CELL @@@GETTIME@@@:@@@GETTIM timestamp=9223372036854775807, value=\x00\x00\x01I\xB0@\xA0\xE0 E@@@ 1 row(s) in 0.0420 seconds ## 將列值轉化為uninx 時間 hbase(main):015:0> Time.at(Bytes.toLong("\x00\x00\x01I\xB0\x0BZ\x0B".to_java_bytes)/ 1000) => Sat Nov 15 04:42:54 +0800 2014 ## 從上面的測試中看出,我們自定義的Coprocessor已經成功的部署到分布式系統中了。
需要留意的是在hbase-site.xml配置的Coprocessor默認是會被每張表的每個region加載。如果只想要某個表使用這個observer coprocessor,就需要使用表描述符的加載方式,這種方式同樣的需要拷貝jar包到hbase安裝目錄下的lib目錄中去,與上面不同的是不用在hbase-site.xml中設置Coprocessor,而是使用alter來把Coprocessor與表綁定。如下
## cp jar包到hbase安裝目錄下的lib目錄,所有節點上都做這樣的操作 [grid@hadoop1 ~]$ cp /var/ftp/pub/RegionObserverExample.jar /opt/hbase-0.98.4-hadoop2/lib/ ## 注釋掉hbase-site.xml中的Coprocessor的配置 [grid@hadoop1 ~]$ tail -7 /opt/hbase-0.98.4-hadoop2/conf/hbase-site.xml <!-- <property> <name>hbase.coprocessor.region.classes</name> <value>org.apache.hbase.kora.coprocessor.RegionObserverExample</value> </property> --> </configuration>
在hbase shell中使用alter命令來為kora表來設定Coprocessor
## 格式:[coprocessor jar file location] | class name | [priority] | [arguments] ## 列子:hbase> alter 't1', ## 'coprocessor'=>'hdfs:///foo.jar|com.foo.FooRegionObserver|1001|arg1=1,arg2=2' ## 由于一定設置了classpath,所以可以忽略jar file location,如下: hbase(main):101:0> alter 'kora', hbase(main):102:0* 'coprocessor' => '|org.apache.hbase.kora.coprocessor.RegionObserverExample|' Updating all regions with the new schema... 0/1 regions updated. 1/1 regions updated. Done. 0 row(s) in 2.5670 seconds
設置成功,decribe下表
hbase(main):103:0> describe 'kora' DESCRIPTION ENABLED 'kora', {TABLE_ATTRIBUTES => {coprocessor$1 => '|org.apache.hbase.kora.coprocessor.RegionObserverExa true mple|'}, {NAME => 'project', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => 'FOREVER', KEEP_DELETED_ CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'} 1 row(s) in 0.0580 seconds
ok,已經設置成功,下面來測試一下
## kora表,指定了Coprocessor hbase(main):104:0> get 'kora', '@@@GETTIME@@@' COLUMN CELL @@@GETTIME@@@:@@@GETTIME@@@ timestamp=9223372036854775807, value=\x00\x00\x01I\xB0\x985W 1 row(s) in 0.0360 seconds ## testtable,沒有指定Coprocessor hbase(main):105:0> get 'testtable', '@@@GETTIME@@@' COLUMN CELL 0 row(s) in 0.0180 seconds
需要注意的是,Coprocessor的優先級有SYSTEM和USER兩種,SYSTEM優先于USER加載。使用表描述符設置Coprocessor時,不要設置優先級這一項,否則無法成功觸發,如
'coprocessor' => '|org.apache.hbase.kora.coprocessor.RegionObserverExample|USER|'
雖然也能成功設置Coprocessor,但是測試時是無法觸發的,在上述環境中親自測試過的,而且hbase幫助文檔中優先級這個項用戶不是必輸項,只有類名是必輸項。我們可以根據自己的需求來選擇使用哪種方式來配置自己的Coprocessor。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。