SHOEISHA iD

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

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

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

初めてのHBase

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

初めてのHBase 第9回

セカンダリインデックス

 次に、セカンダリインデックスについて説明します。

 セカンダリインデックスを用いることで、対象カラムのソートが含まれるクエリやWHERE句に条件があるクエリが高速になる場合があります。ただし、データの追加・更新時にセカンダリインデックスを更新するため、多少のオーバヘッドがかかります。

 Phoenixのセカンダリインデックスは以下の2種類があります。

  • Mutable Indexing
  • Immutable Indexing

 それぞれについて説明していきます。

 セカンダリインデックスを使うためには以下の設定が必要です。以下の設定をhbase-site.xmlに追加して、HBaseを再起動してください。

<property>
    <name>hbase.regionserver.wal.codec</name>
    <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
</property> 

Mutable Indexing

 Mutable Indexingは、一度作成したデータに対して変更をするようなユースケースに用います。Mutable Indexingでは、データの変更があった場合に、セカンダリインデックスに対してもその変更を反映します。

 それでは、実際に使ってみましょう。まずは、Phoenixのコマンドラインを起動します。

$ cd <Phoenixのインストールディレクトリ>/bin
$ ./sqlline.sh localhost

 テーブルを作成します。

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

 次に、セカンダリインデックスを作成します。

 以下では、INDEX1という名前で、COL2に対して昇順(デフォルト)のセカンダリインデックスを作成しています。

0: jdbc:phoenix:localhost> CREATE INDEX INDEX1 ON TBL1 (COL2);

 ここで、実際にHBase上でどのようにセカンダリインデックスが表現されているか見てみましょう。

 まずは、HBase shellを起動します。

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

 HBase上でテーブルを確認してみます。

$ list
TABLE
INDEX1
SYSTEM.TABLE
TBL1
3 row(s) in 0.0250 seconds

 先ほど作成したセカンダリインデックスの名前で、HBase上にTableが作成されているのが分かります。Phoenixでは、セカンダリインデックスは実データのTableとは別のTableに保存されます。

 それでは、実際にデータを入れてみます。

0: jdbc:phoenix:localhost> UPSERT INTO TBL1 VALUES ('aaa', '111', 1);
0: jdbc:phoenix:localhost> UPSERT INTO TBL1 VALUES ('bbb', '222',2);
0: jdbc:phoenix:localhost> UPSERT INTO TBL1 VALUES ('ccc', '333',3);
0: jdbc:phoenix:localhost> SELECT * FROM TBL1;
+------------+------------+------+
|    COL1    |    COL2    | COL3 |
+------------+------------+------+
| aaa        | 111        | 1    |
| bbb        | 222        | 2    |
| ccc        | 333        | 3    |
+------------+------------+------+

 HBase上の、セカンダリインデックスのテーブルの中身を見てみましょう。

$ scan 'INDEX1'
ROW                                            COLUMN+CELL
 111\x00aaa                                    column=_0:_0, timestamp=1392487975536, value=
 222\x00bbb                                    column=_0:_0, timestamp=1392487975643, value=
 333\x00ccc                                    column=_0:_0, timestamp=1392487975685, value=
3 row(s) in 0.1110 seconds

 セカンダリインデックスのテーブルの中では、RowKeyにセカンダリインデックスを作成したCOL2の値と主キーであるCOL1の値がマッピングされているのが分かります。このセカンダリインデックスを使うことで、COL2の昇順ソートやWHERE句にCOL2の条件が含まれているクエリに対して高速に処理をすることが可能になります。

 以下は、実際にセカンダリインデックスが使われている例です。EXPLAIN文で確認しています。

0: jdbc:phoenix:localhost> EXPLAIN SELECT COL1, COL2 FROM TBL1 WHERE COL2='222';
+------------+
|    PLAN    |
+------------+
| CLIENT PARALLEL 1-WAY RANGE SCAN OVER INDEX1 ['222'] |
+------------+

 ここで、以下のクエリのEXPLAINしてみます。

0: jdbc:phoenix:localhost> EXPLAIN SELECT COL1, COL2, COL3 FROM TBL1 WHERE COL2='222';
+------------+
|    PLAN    |
+------------+
| CLIENT PARALLEL 1-WAY FULL SCAN OVER TBL1 |
|     SERVER FILTER BY COL2 = '222' |
+------------+

 上記のクエリでは、COL2がWHERE句の条件に含まれているのにもかかわらず、セカンダリインデックスが使われていません。

 Phoenixでは、現在のところ、セカンダリインデックスへのScanだけで解決できる場合のみ、セカンダリインデックスが使われるようです。

 上記のクエリでは、COL3のデータを取得する必要がありますが、セカンダリインデックスにCOL3のデータが含まれていないので、セカンダリインデックスが使われませんでした。

 これの解決方法として、INCLUDEを使うことができます。

CREATE INDEX INDEX2 ON TBL1 (COL2) INCLUDE (COL3);

 上記のようにすることで、COL3のデータがセカンダリインデックスに含まれるようになります。

 EXPLAINで確認しても、セカンダリインデックスが使われていることが分かります。

0: jdbc:phoenix:localhost> EXPLAIN SELECT COL1, COL2, COL3 FROM TBL1 WHERE COL2='222';
+------------+
|    PLAN    |
+------------+
| CLIENT PARALLEL 1-WAY RANGE SCAN OVER INDEX2 ['222'] |
+------------+

 HBase上では以下のようになっています。Columnとして、COL3の値が格納されています。

$ scan 'INDEX2'
ROW                                            COLUMN+CELL
 111\x00aaa                                    column=_0:_0, timestamp=1392490841021, value=
 111\x00aaa                                    column=_0:_0:COL3, timestamp=1392490841021, value=\x80\x00\x00\x01
 222\x00bbb                                    column=_0:_0, timestamp=1392490851138, value=
 222\x00bbb                                    column=_0:_0:COL3, timestamp=1392490851138, value=\x80\x00\x00\x02
 333\x00ccc                                    column=_0:_0, timestamp=1392490851178, value=
 333\x00ccc                                    column=_0:_0:COL3, timestamp=1392490851178, value=\x80\x00\x00\x03
3 row(s) in 0.0550 seconds

 これら以外にも、Phoenixは、複合インデックスや降順のインデックスにも対応しています。

 以下は、その例になります。COL2とCOL3の複合インデックスであり、COL2に対しては降順のインデックスとなっています。

CREATE INDEX INDEX2 ON TBL1 (COL2 DESC, COL3);

次のページ
まとめ

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

初めてのHBase連載記事一覧

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7645 2014/03/05 14:00

イベント

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

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

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

メールバックナンバー