S-JIS[2010-02-27] 変更履歴

HBaseのテーブル操作

HBaseのテーブルをJavaから操作する例。
HBaseのテーブルそのものを扱うにはHBaseAdminクラスを使用する。


テーブル操作の基本

import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MasterNotRunningException;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.log4j.PropertyConfigurator;
	public static void main(String[] args) throws IOException {
		PropertyConfigurator.configure("C:/cygwin/usr/local/hbase-0.20.3/conf/log4j.properties");

		// 設定ファイルを用いてHbaseへ接続
		HBaseConfiguration conf = new HBaseConfiguration();
		conf.addResource(new Path("C:/cygwin/usr/local/hbase-0.20.3/conf/hbase-site.xml"));

		HBaseAdmin admin = new HBaseAdmin(conf);
		exists(admin);	// テーブル存在確認
		create(admin);	// テーブル作成
		list(admin);	// テーブル一覧
		disable(admin);	// テーブル使用可否変更・確認
		add(admin);	// 項目の追加・削除
		describe(admin);	// テーブル情報取得
	}

テーブルの存在確認

	static void exists(HBaseAdmin admin) throws MasterNotRunningException {
		String tableName = "TEST_TYPE"; //テーブル名
		boolean exists = admin.tableExists(Bytes.toBytes(tableName));
		System.out.println(tableName + "=" + exists);
	}

HBase Shellの以下のコマンドと同様。

> exists 'TEST_TYPE'
true

テーブルの新規作成・削除

	static void create(HBaseAdmin admin) throws IOException {
		byte[] tableName = Bytes.toBytes("java1");
		HTableDescriptor desc = new HTableDescriptor(tableName);
		desc.addFamily(new HColumnDescriptor(Bytes.toBytes("familyA")));
		desc.addFamily(new HColumnDescriptor(Bytes.toBytes("familyB")));

		admin.createTable(desc);
//		admin.createTableAsync(desc);
	}

createTable()はテーブル作成が終わるまでメソッド呼び出しから戻ってこない。
createTableAsync()は非同期、つまりすぐにメソッド呼び出しから戻ってくる。

HBase Shellの以下のコマンドと同様。

> create 'java1', 'familyA', 'familyB'
0 row(s) in 2.5310 seconds

HBase Shellのdropコマンドは「admin.deleteTable(tableName)」。
ただし事前にテーブルを使用不可にしておく必要がある。


テーブルの使用可否

	static void disable(HBaseAdmin admin) throws IOException {
		byte[] tableName = Bytes.toBytes("java1");
		print(admin, tableName);

		// テーブルを使用不可にする
		admin.disableTable(tableName);
		print(admin, tableName);

		// テーブルを使用可能にする
		admin.enableTable(tableName);
		while (!admin.isTableAvailable(tableName)) {
			print(admin, tableName);
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) { }
		}
		print(admin, tableName);
	}

	static void print(HBaseAdmin admin, byte[] tableName) throws IOException {
		boolean a = admin.isTableAvailable(tableName);
		boolean e = admin.isTableEnabled(tableName);
		boolean d = admin.isTableDisabled(tableName);
		System.out.printf("a=%b, e=%b, d=%b%n", a, e, d);
	}
a=true, e=true, d=false
a=false, e=false, d=true
a=false, e=true, d=false
a=false, e=true, d=false
a=false, e=true, d=false
a=false, e=true, d=false
a=false, e=true, d=false
a=false, e=true, d=false
a=false, e=true, d=false
a=false, e=true, d=false
a=false, e=true, d=false
a=false, e=true, d=false
a=true, e=true, d=false

disableTable()を実行すると、メソッド呼び出しから戻るには少し時間がかかる。
戻った直後は既にisTableDisabled()はtrue(isTableEnabled()はfalse)になっている。

enableTable()を実行すると、すぐにisTableEnabled()はtrue(isTableDisabled()はfalse)になる。
しかしisTableAvailable()がtrueになるのは少し時間がかかるようだ。


テーブル一覧の取得

	static void list(HBaseAdmin admin) throws IOException {
		HTableDescriptor[] list = admin.listTables();
		for (HTableDescriptor desc : list) {
			System.out.println(desc.getNameAsString()); //テーブル名を表示
		}
	}

テーブル情報の取得

	static void describe(HBaseAdmin admin) throws IOException {
		byte[] tableName = Bytes.toBytes("java1");
		HTableDescriptor desc = admin.getTableDescriptor(tableName);
		System.out.println(desc.toString());
	}

HTableDescriptorにはテーブルの情報が入っている。(HBase Shellのdescribeコマンドと同等)
{NAME => 'java1',
 FAMILIES => [
  {NAME => 'familyA', COMPRESSION => 'NONE', VERSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'},
  {NAME => 'familyB', COMPRESSION => 'NONE', VERSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}
 ]
}

テーブルが見つからない場合はorg.apache.hadoop.hbase.TableNotFoundExceptionが発生する。


項目(family)の追加・削除

	static void add(HBaseAdmin admin) throws IOException {
		byte[] tableName = Bytes.toBytes("java1");

		admin.disableTable(tableName);
		try {
			// 項目削除
			admin.deleteColumn(tableName, Bytes.toBytes("familyB"));

			// 項目追加
			HColumnDescriptor column = new HColumnDescriptor(Bytes.toBytes("familyC"));
			admin.addColumn(tableName, column);
		} finally {
			admin.enableTable(tableName);
		}
	}

項目を追加・削除する為には、事前にテーブルを使用不可にしておく必要がある。
使用不可でない場合、org.apache.hadoop.hbase.TableNotDisabledExceptionが発生する。

deleteColumn()は、指定した項目が無くてもエラーにならない。
addColumn()は、項目が既に存在していてもエラーにならない。

他にmodifyColumn()というメソッドもあるようだ。

HBase Shellのalterコマンドに相当する。


HBaseプログラミングへ戻る / HBaseへ戻る / Java目次へ行く / 技術メモへ戻る
メールの送信先:ひしだま