HBase0.89にJavaからアクセスする例。
HBaseにアクセスするには、HBaseのjarファイルの他に、Hadoopのjarファイルが必要。
とは言っても、hbase-0.89.20100621では、HBaseの中に必要なHadoopのjarファイルが入っている。
jarファイル | 備考 | ||
---|---|---|---|
HBase | C:\cygwin\usr\local\hbase-0.89\hbase-0.89.20100621.jar | ↓ソースの場所(Eclipseで添付可能) C:/cygwin/usr/local/hbase-0.89/hbase-0.89.20100621-sources.jar |
|
C:\cygwin\usr\local\hbase-0.89\lib\ | commons-logging-1.1.1.jar | ||
zookeeper-3.3.1.jar | 分散システムアクセス | ||
log4j-1.2.15.jar | |||
Hadoop | C:\cygwin\usr\local\hbase-0.89\lib\ | hadoop-core-0.20.3-append-r956776.jar | Hadoop分散ファイルシステム |
lib直下のjarファイルを全て入れてしまうのが楽(笑)
豊月さんのサンプルをベースにしています。
import org.apache.hadoop.conf.Configuration; 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.HTableInterface; 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 { // 設定ファイルの指定 Configuration conf = HBaseConfiguration.create(); // テーブルを指定(ここでHBaseへ接続) HTableFactory factory = new HTableFactory(); HTableInterface table = factory.createHTableInterface(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", new byte[0])); String valueStr = Bytes.toString(value); System.out.println(valueStr); } finally { factory.releaseHTableInterface(table); } } }
org.apache.hadoop.hbase.util.Bytesは、UTF-8で文字列をバイト列に変換するユーティリティー。
したがって、UTF-8以外のエンコードを使いたい場合は自分でString#getBytes("MS932")とかを使う。
→Bytesクラスのメソッド
(Hadoopだとhadoopシェルから実行しないといけないが
、)
HBaseのプログラムはEclipseから直接実行することが出来る。
ただし、実行時のクラスパス(の最上位)に設定ファイルのある場所「C:/cygwin/usr/local/hbase-0.89/conf」を追加しておくこと。
(hbase-*.jarの中にhbase-default.xml、hadoop-*-core.jarの中にlog4j.propertiesがあるので、それより優先させる為にクラスパスの最上位にconfを指定する必要がある)
設定ファイルが読み込めていない場合、実行時に以下のような例外が発生するかもしれない。
10/07/06 04:07:31 INFO zookeeper.ClientCnxn: Opening socket connection to server localhost/127.0.0.1:21810 10/07/06 04:07:32 WARN zookeeper.ClientCnxn: Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect java.net.ConnectException: Connection refused: no further information at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:574) at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1078) 10/07/06 04:07:32 DEBUG zookeeper.ZooKeeperWrapper: Failed to read org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /hbase/root-region-server
ZooKeeperに接続する為のポート番号の設定(hbase-default.xmlのhbase.zookeeper.property.clientPort)は2181になっているが、HBaseのプログラム内のデフォルトは21810。
つまり設定ファイルが読み込めないと21810で接続しようとする為、実際に稼動しているポート番号と異なるので接続できない。
(HBase Shellで「-d」を付けて起動すると、ZooKeeperのログが出る。HBase
Shellが正常に動いているなら、そこでポート番号が確認できる)
また、クラスパスにconfの場所を指定する代わりに、プログラム内から指定することも出来る。
public class HBaseSample { public static void main(String[] args) throws IOException { // log4jの設定ファイルを指定 PropertyConfigurator.configure("C:/cygwin/usr/local/hbase-0.89/conf/log4j.properties"); // 設定ファイルを指定 Configuration conf = HBaseConfiguration.create(); conf.addResource(new Path("C:/cygwin/usr/local/hbase-0.89/conf/hbase-default.xml")); conf.addResource(new Path("C:/cygwin/usr/local/hbase-0.89/conf/hbase-site.xml")); 〜 } }
confの生成方法 |
HBaseConfiguration conf = new HBaseConfiguration(); ↓ Configuration conf = HBaseConfiguration.create();HBase0.89では、自分でnewすると、ログに警告メッセージが出る。 |
HTableの取得方法 |
HTable table = new HTable(conf, Bytes.toBytes("テーブル名")); ↓ HTableFactory factory = new HTableFactory(); HTableInterface table = factory.createHTableInterface(conf, Bytes.toBytes("テーブル名")); |
HTableのクローズ方法 |
table.close(); ↓ factory.releaseHTableInterface(table);内部でフラッシュ(コミット)される。 |
上記のサンプルを動かしてみると、標準エラーにZooKeeperのログがぼろぼろ出てくる。
中身の出力レベルを変えればログ出力を制御できる。
# 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桁で表示すべき!)