HBase0.20にJavaからアクセスする例。
|
|
HBaseにアクセスするには、HBaseのjarファイルの他に、Hadoopのjarファイルが必要。[2010-02-20]
とは言っても、hbase-0.20.3では、HBaseの中に必要なHadoopのjarファイルが入っている。
jarファイル | 備考 | ||
---|---|---|---|
HBase | C:\cygwin\usr\local\hbase-0.20.3\hbase-0.20.3.jar | ↓ソースの場所(Eclipseで添付可能) C:/cygwin/usr/local/hbase-0.20.3/src/java |
|
C:\cygwin\usr\local\hbase-0.20.3\lib\ | commons-logging-1.0.4.jar | ||
zookeeper-3.2.2.jar | 分散システムアクセスの何か | ||
log4j-1.2.15.jar | |||
Hadoop | C:\cygwin\usr\local\hbase-0.20.3\lib\ | hadoop-0.20.1-hdfs127-core.jar | Hadoop分散ファイルシステム |
lib直下にはjarファイルがたくさんあるが、単独環境ではとりあえず上記の4つがあれば動くようだ。
まったく申し訳ない&ありがたいことに、豊月さんのサンプルほぼそのまんまです。[2010-02-20]
import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.Get; import org.apache.hadoop.hbase.client.HTable; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.util.Bytes;
public class HBaseSample { public static void main(String[] args) throws IOException { // 設定ファイルを指定 HBaseConfiguration conf = new HBaseConfiguration(); conf.addResource(new Path("C:/cygwin/usr/local/hbase-0.20.3/conf/hbase-site.xml")); // テーブルを指定(ここでHBaseへ接続) HTable table = new HTable(conf, Bytes.toBytes("TEST_TYPE")); try { // 取得したテーブルからROW(キー)を指定してデータを取得 Get g = new Get(Bytes.toBytes("KEY00001")); Result r = table.get(g); // 項目ColumnFamilyAのデータを取得 byte[] value = r.getValue(Bytes.toBytes("ColumnFamilyA")); String valueStr = Bytes.toString(value); System.out.println(valueStr); } finally { table.close(); } } }
org.apache.hadoop.hbase.util.Bytesは、UTF-8で文字列をバイト列に変換するユーティリティー。
したがって、UTF-8以外のエンコードを使いたい場合は自分でString#getBytes("MS932")とかを使う。
→Bytesクラスのメソッド
HBaseのプログラムは、Eclipseから直接実行することが出来る。
(Hadoopだとhadoopシェルから実行しないといけないが)
上記のサンプルを動かしてみると、標準エラーにZooKeeperのログがぼろぼろ出てくる。[2010-02-20]
HBASE_HOME/conf/にlog4j.propertiesがあるが、これはデフォルトでは使われていない。
中身の出力レベルを変えてこのファイルを使うようにすればログ出力を制御できる。
# Define some default values that can be overridden by system properties
hbase.root.logger=WARN,console
hbase.log.dir=.
hbase.log.file=hbase.log
〜
#
# console
# Add "console" to rootlogger above if you want to use this
#
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy/MM/dd HH:mm:ss} %p %c{2}: %m%n
# Custom Logging levels
#log4j.logger.org.apache.zookeeper=INFO
#log4j.logger.org.apache.hadoop.fs.FSNamesystem=DEBUG
#log4j.logger.org.apache.hadoop.hbase=DEBUG
#log4j.logger.org.apache.hadoop.dfs=DEBUG
一番上のhbase.root.loggerがデフォルトの出力レベルで、元々INFOになっているのでWARNに変える。
一番下がパッケージ名ごとの出力レベルなので、コメントアウトする。
(あと、「年」は4桁で表示すべき!)
import org.apache.log4j.PropertyConfigurator;
public static void main(String[] args) throws Exception {
// log4jの設定ファイルを指定
PropertyConfigurator.configure("C:/cygwin/usr/local/hbase-0.20.3/conf/log4j.properties");
// 設定ファイルを指定
HBaseConfiguration conf = new HBaseConfiguration();
〜
PropertyConfiguratorでlog4jの設定ファイルを指定する。
ZooKeeperのクラスがロードされるより前(HBaseのテーブルにアクセスするより前)に設定すること。
HBaseのプログラムの実行時に発生したエラー(例外)は、log4j.propertiesで指定した場所にエラーメッセージが出力される。[2010-02-20]
以下、各行の先頭に「WARN」や「DEBUG」と出ているのはlog4jの出力、それ以外は普通にコンソールに出力されたメッセージ(例外のスタックトレース)。
HBaseが起動していないので接続に失敗しているケース。
HTable table = new HTable(conf, "TEST_TYPE"); ←ここで発生
エラー(例外)の内容 | 備考 |
---|---|
WARN zookeeper.ClientCnxn: Exception closing
session 0x0 to sun.nio.ch.SelectionKeyImpl@f0eed6 |
「127.0.0.1:2181」は、hbase-site.xmlの hbase.zookeeper.quorum hbase.zookeeper.property.clientPort で指定したZooKeeperのアドレス。 |
DEBUG client.HConnectionManager$TableServers:
Sleeping 1000ms, waiting for root region. |
接続失敗時にリトライするまでちょっとスリープする。 「1000ms」は、hbase-site.xmlの hbase.client.pause で指定した時間。 |
DEBUG client.HConnectionManager$TableServers:
locateRegionInMeta attempt 0 of 10 failed; retrying after sleep of 1000
because: Timed out trying to locate root region |
locateRegionInMeta()の失敗。 リトライ最大回数の「10」はhbase-site.xmlの hbase.client.retries.number で指定した回数だが、 「0 of 10」なので、初回の失敗。 |
Exception in thread "main"
org.apache.hadoop.hbase.client.NoServerForRegionException: Timed out
trying to locate root region |
locateRootRegion()の失敗。 ZooKeeperへの接続のリトライ回数オーバー。 リトライ回数はhbase-site.xmlの hbase.client.retries.number で指定した回数。 |
HConnectionManagerの各メソッド内でそれぞれリトライを行っているようなので、最終的に停止するまでの合計リトライ回数はhbase-site.xmlで指定したリトライ回数より多くなる。
対処方法としては、ZooKeeper(HBase)を起動する。
データ取得がタイムアウトしたケース。
Result r = table.get(g); ←ここで発生
エラー(例外)の内容 | 備考 |
---|---|
Exception in thread "main"
org.apache.hadoop.hbase.client.RetriesExhaustedException: Trying to
contact region server 192.168.xxx.1:1838 for region
TEST_TYPE,,1266507739937, row 'KEY00001', but failed after 1 attempts. |
TEST_TYPEテーブルの row=KEY00001から データを取得しようとして リトライオーバー。 |
接続が成功していてもデータアクセスにはちょっと時間がかかるので、待ち時間を越えてしまうことがある。
対処法としては、リトライ回数hbase.client.retries.numberを多くする。
(上の例は、リトライ回数2回で起きた。状態が良くなれば、リトライ回数1回でも発生しないけど)
その他分かりやすいケース。
エラー(例外)の内容 | 備考 |
---|---|
Exception in thread "main"
org.apache.hadoop.hbase.TableNotFoundException: TEST_TYPE2 |
TEST_TYPE2テーブルが存在しない。 |
値の取得(Get)において、 ROWが存在しない場合 ColumnFamilyが存在しない場合 Columnが存在しない場合 はResult#getValue()でnullが返るだけで、エラーにはならない。 |