はじめに
JavaクライアントからHBaseに対して、CRUDを実行する簡単なサンプルプログラムの紹介です。
使用するJavaAPIはv1.0で大きく変更されているのですが、検索するとv0.9の情報が多いです。
そのため、v1.0のJavaAPIを使用した例を参考までに残しておきます。
環境
使用する環境は以下のとおりです。
- CentOS 7.5(サーバ)
- Windows 10(クライアント)
- JDK8
- HBase 2.2.0
- HBase Client 2.2.0
サーバはCentOS 7.5でHBase 2.2.0の疑似分散環境を構築済みです。
HBaseは以下で構築した環境を用いています。
事前準備
今回はクライアントがWindowsであるため「winutils.exe」が必要です。
「winutils.exe」がないと以下のようなエラーが発生します。
DEBUG | main | Failed to find winutils.exe
java.io.FileNotFoundException: java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset. -see https://wiki.apache.org/hadoop/WindowsProblems
at org.apache.hadoop.util.Shell.fileNotFoundException(Shell.java:528)
at org.apache.hadoop.util.Shell.getHadoopHomeDir(Shell.java:549)
at org.apache.hadoop.util.Shell.getQualifiedBin(Shell.java:572)
at org.apache.hadoop.util.Shell.<clinit>(Shell.java:669)
at org.apache.hadoop.util.StringUtils.<clinit>(StringUtils.java:79)
at org.apache.hadoop.conf.Configuration.getBoolean(Configuration.java:1555)
at org.apache.hadoop.hbase.HBaseConfiguration.checkDefaultsVersion(HBaseConfiguration.java:66)
at org.apache.hadoop.hbase.HBaseConfiguration.addHbaseResources(HBaseConfiguration.java:80)
at org.apache.hadoop.hbase.HBaseConfiguration.create(HBaseConfiguration.java:94)
at sample.TestMain.test(TestMain.java:43)
at sample.TestMain.main(TestMain.java:20)
Caused by: java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset.
at org.apache.hadoop.util.Shell.checkHadoopHomeInner(Shell.java:448)
at org.apache.hadoop.util.Shell.checkHadoopHome(Shell.java:419)
at org.apache.hadoop.util.Shell.<clinit>(Shell.java:496)
以下のURLから「winutils.exe」をダウンロードします。
ダウンロードしたファイルは、binディレクトリの下に「{HADOOP_HOME}/bin/winutils.exe」のように格納します。
次に環境変数HADOOP_HOMEを設定します。
私の環境では「C:\pleiades\workspace\hbase_test\hadoop-3.2.0」を設定しています。
Javaでクライアントプログラム作成
今回はMavenを使用しているので、pom.xmlにhbase-clientを以下のように追加します。
<dependencies>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.2.0</version>
</dependency>
</dependencies>
HBaseに対して、Get/Put/Scan/Deleteを実行するプログラム例は以下のようになります。
package sample;
import java.io.IOException;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
public class TestClient {
public static void main(String[] args) {
TestClient app = new TestClient();
app.test();
}
public void test() {
org.apache.hadoop.conf.Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "hbaseserver1.example.com");
conf.set("hbase.zookeeper.property.clientPort","2181");
try (Connection conn = ConnectionFactory.createConnection(conf)) {
Table table = conn.getTable(TableName.valueOf("test"));
// PUT
System.out.println("put: ");
Put p = new Put(Bytes.toBytes("key01"));
p.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("col1"), Bytes.toBytes("test03"));
table.put(p);
// GET
Get g = new Get(Bytes.toBytes("key01"));
Result r = table.get(g);
byte[] val = r.getValue(Bytes.toBytes("cf"), Bytes.toBytes("col1"));
System.out.printf("get: %s%n", Bytes.toString(val));
// DELETE
System.out.println("delete: ");
Delete d = new Delete(Bytes.toBytes("key01"));
d.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("col1"));
table.delete(d);
// SCAN
System.out.println("scan: ");
Scan scan = new Scan();
ResultScanner rs = table.getScanner(scan);
for (Result rv : rs) {
System.out.println(Bytes.toString(rv.getRow()));
}
table.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
以下のコードでは接続先のzookeeperのホスト名とポートを指定しています。
複数のzookeeperのサーバがある場合は、"hbaseserver1.example.com,hbaseserver2.example.com"のように指定するようです。
conf.set("hbase.zookeeper.quorum", "hbaseserver1.example.com");
conf.set("hbase.zookeeper.property.clientPort","2181");
上述はJavaコード中に接続先のホスト名を直接指定しましたが、通常は以下のようなhbase-site.xmlを作成します。
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>hbase.zookeeper.quorum</name>
<value>hbaseserver1.example.com</value>
</property>
<property>
<name>hbase.zookeeper.property.clientPort</name>
<value>2181</value>
</property>
</configuration>
作成したhbase-site.xmlを読み込む場合は以下のように記述します。
Configuration conf = HBaseConfiguration.create();
conf.addResource(new Path("/hbase-site.xml"));
最後に/etc/hostsに以下のように自ホストのIPアドレスがないと、リモートからHBaseにアクセスすることができませんでした。
クライアントとHBaseが同一サーバ上で動いていれば以下の記述がなくても動きます。
192.168.10.177 hbaseserver1.example.com hbaseserver1
※IPは私の環境