SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

初めてのHBase

HBaseをSQLで操作してみよう(前編)

初めてのHBase 第8回

  • X ポスト
  • このエントリーをはてなブックマークに追加

コマンドラインで使ってみる

 Phoenixの準備ができたので、実際に動かしてみましょう。下記のようにしてコマンドラインを立ち上げます。

$ cd bin
$ ./sqlline.sh localhost

 最初に、CREATE TABLEでテーブルを作成します。以下のようにCREATE文を入力するとテーブルが作成されます。

0: jdbc:phoenix:localhost> CREATE TABLE TBL1 (
. . . . . . . . . . . . .> COL1 VARCHAR NOT NULL PRIMARY KEY,
. . . . . . . . . . . . .> COL2 INTEGER
. . . . . . . . . . . . .> );

 確認する場合は、!tablesと!columnsを使います。

0: jdbc:phoenix:localhost> !tables
+------------+-------------+------------+------------+------------+------------+---------------------------+----------------+-------------+----------------+
| TABLE_CAT  | TABLE_SCHEM | TABLE_NAME | TABLE_TYPE |  REMARKS   | TYPE_NAME  | SELF_REFERENCING_COL_NAME | REF_GENERATION | INDEX_STATE | IMMUTABLE_ROWS |
+------------+-------------+------------+------------+------------+------------+---------------------------+----------------+-------------+----------------+
| null       | SYSTEM      | TABLE      | SYSTEM TABLE | null       | null       | null                      | null           | null        | false          |
| null       | null        | TBL1       | TABLE      | null       | null       | null                      | null           | null        | false          |
+------------+-------------+------------+------------+------------+------------+---------------------------+----------------+-------------+----------------+
0: jdbc:phoenix:localhost> !columns TBL1
+------------+-------------+------------+-------------+-----------+------------+-------------+---------------+----------------+----------------+----------+------------+------------+
| TABLE_CAT  | TABLE_SCHEM | TABLE_NAME | COLUMN_NAME | DATA_TYPE | TYPE_NAME  | COLUMN_SIZE | BUFFER_LENGTH | DECIMAL_DIGITS | NUM_PREC_RADIX | NULLABLE | COLUMN_DEF | SQL_DATA_T |
+------------+-------------+------------+-------------+-----------+------------+-------------+---------------+----------------+----------------+----------+------------+------------+
| null       | null        | TBL1       | COL1        | 12        | VARCHAR    | null        | null          | null           | null           | 0        | null       | null       |
| _0         | null        | TBL1       | COL2        | 4         | INTEGER    | 10          | null          | 0              | null           | 1        | null       | null       |
+------------+-------------+------------+-------------+-----------+------------+-------------+---------------+----------------+----------------+----------+------------+------------+

 次に、データを入れてみましょう。

 Phoenixでは、データを入れるときにUPSERT文を使います。UPSERTはINSERTとUPDATEをもじったものだと思いますが、データがない場合は新しくデータを作成し、ある場合は更新をします。

0: jdbc:phoenix:localhost> UPSERT INTO TBL1 VALUES ('aaa', 1);
0: jdbc:phoenix:localhost> UPSERT INTO TBL1 VALUES ('bbb', 2);
0: jdbc:phoenix:localhost> UPSERT INTO TBL1 VALUES ('ccc', 3);

 入れたデータをSELECT文で見てみましょう。

0: jdbc:phoenix:localhost> SELECT * FROM TBL1;
+------------+------+
|    COL1    | COL2 |
+------------+------+
| aaa        | 1    |
| bbb        | 2    |
| ccc        | 3    |
+------------+------+

 データが入っていることが確認できると思います。

 ここで、実際にHBase上にどのようにデータが入っているかをのぞいてみましょう。HBase shellを起動します。

$ <HBaseのインストールディレクトリ>/bin/hbase shell

 HBase上では、Phoenix上で作成したテーブルと同じ名前のTableが作成されています。そのTableに対してscanをかけると、以下のように出力されます。

$ scan 'TBL1'
ROW                                            COLUMN+CELL
 aaa                                           column=_0:COL2, timestamp=1389695144507, value=\x80\x00\x00\x01
 aaa                                           column=_0:_0, timestamp=1389695144507, value=
 bbb                                           column=_0:COL2, timestamp=1389695144546, value=\x80\x00\x00\x02
 bbb                                           column=_0:_0, timestamp=1389695144546, value=
 ccc                                           column=_0:COL2, timestamp=1389695144582, value=\x80\x00\x00\x03
 ccc                                           column=_0:_0, timestamp=1389695144582, value=
3 row(s) in 0.0420 seconds

 主キーとして設定したCOL1がRowKeyにマッピングされ、COL2はColumn/Valueにマッピングされているのが分かります。ColumnFamilyとしては、デフォルト値の"_0"が設定されています。

 ちなみに、各Rowに"_0"のColumnがあるのが分かると思います。一見余計なものに見えますが、これは主キー以外の列がNULLの場合にRowが消えてしまわないようにするためのものです。HBaseはColumnが存在しないRowを作ることができないため、このような工夫がなされています。

 次に、以下のようなテーブルを作ってみましょう。今回は、主キーとして3つの列を指定しています。また、FAM1.COL4やFAM2.COL6のように、ピリオドで区切った列名を指定しました。

0: jdbc:phoenix:localhost> CREATE TABLE TBL2 (
. . . . . . . . . . . . .> COL1 VARCHAR NOT NULL,
. . . . . . . . . . . . .> COL2 INTEGER NOT NULL,
. . . . . . . . . . . . .> COL3 CHAR(2) NOT NULL,
. . . . . . . . . . . . .> FAM1.COL4 VARCHAR,
. . . . . . . . . . . . .> FAM1.COL5 VARCHAR,
. . . . . . . . . . . . .> FAM2.COL6 VARCHAR
. . . . . . . . . . . . .> CONSTRAINT PK PRIMARY KEY (COL1, COL2, COL3)
. . . . . . . . . . . . .> );

 さらに、データを入れます。

0: jdbc:phoenix:localhost> UPSERT INTO TBL2 VALUES ('aaa', 1, '12', 'bbb', 'ccc', 'ddd');
0: jdbc:phoenix:localhost> SELECT * FROM TBL2;
+------------+------+------+------------+------------+------------+
|    COL1    | COL2 | COL3 |    COL4    |    COL5    |    COL6    |
+------------+------+------+------------+------------+------------+
| aaa        | 1    | 12   | bbb        | ccc        | ddd        |
+------------+------+------+------------+------------+------------+

 HBase上でscanをかけると、以下のようになります。

$ scan 'TBL2'
ROW                                            COLUMN+CELL
 aaa\x00\x80\x00\x00\x0112                     column=FAM1:COL4, timestamp=1389695036362, value=bbb
 aaa\x00\x80\x00\x00\x0112                     column=FAM1:COL5, timestamp=1389695036362, value=ccc
 aaa\x00\x80\x00\x00\x0112                     column=FAM1:_0, timestamp=1389695036362, value=
 aaa\x00\x80\x00\x00\x0112                     column=FAM2:COL6, timestamp=1389695036362, value=ddd
1 row(s) in 0.0380 seconds

 今回のテーブルでは主キーを3つの列で指定しましたが、それらがすべてRowKeyの一部としてマッピングされています。

 また、FAM1.COL4やFAM2.COL6のようにピリオドで区切った列名を指定すると、ピリオドより前に指定した文字列がColumnFamilyとなり、ピリオドより後ろに指定した文字列がColumnになります。

 主キーはすべてRowKeyにマッピングされます。

 また、列をColumnFamilyで分けたい場合は、ピリオド区切りで列名を指定すれば良いです。

Javaから使ってみる

 PhoenixはJDBCをサポートしているので、以下のようにJavaからアクセスすることができます。

 事前準備として、phoenix-2.2.2-install.tarを解凍した際に出力されたphoenix-2.2.2-client.jarにクラスパスを通す必要があります。

Connection connection = DriverManager.getConnection("jdbc:phoenix:localhost");
connection.setAutoCommit(true);

Statement statement = connection.createStatement();
statement.executeUpdate(
    "CREATE TABLE TBL3 (" +
    "COL1 VARCHAR NOT NULL PRIMARY KEY," +
    "COL2 INTEGER" +
    ")");

statement.executeUpdate("UPSERT INTO TBL3 VALUES ('aaa', 1)");
statement.executeUpdate("UPSERT INTO TBL3 VALUES ('bbb', 2)");
statement.executeUpdate("UPSERT INTO TBL3 VALUES ('ccc', 3)");

ResultSet resultSet = statement.executeQuery("SELECT * FROM TBL3");

while (resultSet.next()) {
  System.out.println(resultSet.getString(1) +  "," + resultSet.getInt(2));;
}

resultSet.close();
statement.close();
connection.close();

まとめ

 今回は、HBaseをSQLで操作できるライブラリであるPhoenixについて説明し、実際に動かしてみました。次回は、トランザクションやセカンダリインデックスなど、Phoenixの高度な機能を使ってみたいと思います。

 また、株式会社サイバーエージェントでは、Hadoop/HBaseエンジニアを募集しています。ご興味のある方はこちらからエントリーしていただければと思います。エンジニア>R&Dエンジニア>R&Dエンジニアを選択しエントリーしていただければ幸いです。

参考資料

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
初めてのHBase連載記事一覧

もっと読む

この記事の著者

鈴木 俊裕(スズキ トシヒロ)

株式会社サイバーエージェント アメーバ事業本部 Ameba Technology Laboratory 2008年4月に株式会社サイバーエージェントに新卒で入社。基盤システムの開発・運用に従事する。 2010年4月にHadoop/Hiveを用いたログ解析基盤の開発・運用を担当する。 2011年4月に、ログ解析、レコメンド、検索エンジンなどを開発するAmeba Technology Laboratoryの立ち上げメンバーとなる。 2011年10月からHBaseを用...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7589 2014/01/30 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング