Apache ImpalaからKuduのQuickstart環境を使う(10分で試すシリーズ)

impala

Apache Impala via Kudu Quickstart Environment

以前、Kudu の Quickstart 環境のブログを書きましたが、その時は a) Apache NiFi でデータをKuduに書き込み、b) Apache Sparkを使ってそのデータを処理する、というものでした。

Apache Kuduは列指向のストレージエンジンですが、Apache Impala と組み合わせることで RDBMS っぽい使い方が可能です。先日アップデートされた Kudu Quickstart に Impala を使う方法が追加されたので、手元の環境で検証しました。

Docker のメモリが少ない場合、impala-shell を実行した際に次のようなエラーがでる場合がありました。リトライでうまくいく場合もありますが、impalad が起動中に例外を起こしていたことによって接続できない場合もあったので、Dockerのメモリを増やしておくことをお勧めします。

$ docker exec -it kudu-impala impala-shell
 Starting Impala Shell without Kerberos authentication
 Error connecting: TTransportException, Could not connect to bdd2c4ffafdd:21000
 Welcome to the Impala shell.
 (Impala Shell v3.4.0-SNAPSHOT (b0c6740) built on Thu Oct 17 10:56:02 PDT 2019)
 You can change the Impala daemon that you're connected to by using the CONNECT
 command.To see how Impala will plan to run your query without actually executing
 it, use the EXPLAIN command. You can change the level of detail in the EXPLAIN
 output by setting the EXPLAIN_LEVEL query option.
 [Not connected] >

Kudu のクラスターを起動する

Dockerを使って Kudu クラスターを起動する手順は前回と全く同じです。起動したらターミナルはそのままにしておきます。

Impala-kudu を起動する

手順に従いコンテナを起動します。

docker run -d --name kudu-impala --network="docker_default" \
  -p 21000:21000 -p 21050:21050 -p 25000:25000 -p 25010:25010 -p 25020:25020 \
  --memory=4096m apache/kudu:impala-latest impala

Impalaシェルで接続する

起動してしばらくしたら、Impalaシェルを開始します。成功すると、最後の行のようなプロンプトが表示されます。
なお、エラーの場合は上記のような Not connected というメッセージが表示されて接続できません。docker exec -it kudu-impala /bin/bash を実行し、/var/lib/impala/logs 以下を確認してみましょう。

$ docker exec -it kudu-impala impala-shell
Starting Impala Shell without Kerberos authentication
Opened TCP connection to bdd2c4ffafdd:21000
Connected to bdd2c4ffafdd:21000
Server version: impalad version 3.3.0-RELEASE RELEASE (build 0f840c5a0f5e673c67cbd482e62065fd47b98e1a)
***********************************************************************************
Welcome to the Impala shell.
(Impala Shell v3.4.0-SNAPSHOT (b0c6740) built on Thu Oct 17 10:56:02 PDT 2019)

To see a summary of a query's progress that updates in real-time, run 'set
LIVE_PROGRESS=1;'.
***********************************************************************************
[bdd2c4ffafdd:21000] default>

クエリを実行する

テーブルを作成する

ドキュメントに従ってテーブルを作成します。

CREATE TABLE my_first_table
(
  id BIGINT,
  name STRING,
  PRIMARY KEY(id)
)
PARTITION BY HASH PARTITIONS 4
STORED AS KUDU;

DESCRIBE my_first_table;
+-------------------------+
| summary                 |
+-------------------------+
| Table has been created. |
+-------------------------+
Fetched 1 row(s) in 0.88s
[bdd2c4ffafdd:21000] default>

エラーになった場合はトラブルシュートを参照してください

Impala でParquet 形式のテーブルを作成する場合と異なるのは、PRIMARY KEY が必須なことと PARTITION BY の指定などです。ImpalaのDDLについては[3]を、ImpalaでKuduにテーブルを作成する際の詳細については [1]、[2] のドキュメントを参考にしてください。
[1] https://kudu.apache.org/docs/kudu_impala_integration.html
[2] https://docs.cloudera.com/documentation/enterprise/6/6.3/topics/kudu_impala.html
[3] https://docs.cloudera.com/documentation/enterprise/6/6.3/topics/impala_create_table.html#create_table

データの追加、更新、削除

データを追加します

-- Insert a row.
INSERT INTO my_first_table VALUES (99, "sarah");
SELECT * FROM my_first_table;
+----+-------+
| id | name  |
+----+-------+
| 99 | sarah |
+----+-------+
Fetched 1 row(s) in 0.17s

続いて複数データを追加します

-- Insert multiple rows.
INSERT INTO my_first_table VALUES (1, "john"), (2, "jane"), (3, "jim");
SELECT * FROM my_first_table;
+----+-------+
| id | name  |
+----+-------+
| 1  | john  |
| 99 | sarah |
| 2  | jane  |
| 3  | jim   |
+----+-------+
Fetched 4 row(s) in 0.11s
[bdd2c4ffafdd:21000] default>

行を更新します。Kudu-Impalaの組み合わせなら、UPDATE/UPSERTが使用できます。最初の更新で id 3 が jim から bob に更新されています。続いて UPSERT を使って id 3 を更新、id 4 を追加しています。

-- Update a row.
UPDATE my_first_table SET name="bob" where id = 3;
SELECT * FROM my_first_table;
+----+-------+
| id | name  |
+----+-------+
| 2  | jane  |
| 3  | bob   |
| 1  | john  |
| 99 | sarah |
+----+-------+
Fetched 4 row(s) in 0.11s
[bdd2c4ffafdd:21000] default>

-- Use upsert to insert a new row and update another.
UPSERT INTO my_first_table VALUES (3, "bobby"), (4, "grant");
SELECT * FROM my_first_table;
+----+-------+
| id | name  |
+----+-------+
| 2  | jane  |
| 3  | bobby |
| 1  | john  |
| 99 | sarah |
| 4  | grant |
+----+-------+
Fetched 5 row(s) in 0.11s
[bdd2c4ffafdd:21000] default>

行を削除します。

-- Delete a row.
DELETE FROM my_first_table WHERE id = 99;
SELECT * FROM my_first_table;
----+-------+
| id | name  |
+----+-------+
| 1  | john  |
| 2  | jane  |
| 3  | bobby |
| 4  | grant |
+----+-------+
Fetched 4 row(s) in 0.11s
[bdd2c4ffafdd:21000] default>

同様に、複数の行を削除します。

-- Delete multiple rows.
DELETE FROM my_first_table WHERE id < 3;
SELECT * FROM my_first_table;
+----+-------+
| id | name  |
+----+-------+
| 3  | bobby |
| 4  | grant |
+----+-------+
Fetched 2 row(s) in 0.11s
[bdd2c4ffafdd:21000] default>

ここでは基本的なDMLを確認しました。チュートリアルには外部テーブルとして利用する例も出ています。

最後にテーブルを消しておきましょう。消さずに終了した場合はトラブルシュートを参考にして下さい。

[bdd2c4ffafdd:21000] default> DROP TABLE my_first_table;
Query: DROP TABLE my_first_table
+-------------------------+
| summary                 |
+-------------------------+
| Table has been dropped. |
+-------------------------+
Fetched 1 row(s) in 0.72s

まとめ

Impala+Kuduを組み合わせると、一度テーブルさえ作成してしまえば、INSERT/UPDATE/UPSERT/DELETEのような一般的なSQLが利用できます。分析者は使い慣れたSQLを利用できるので、データエンジニアはSparkで、アナリストはSQLで、のようにビッグデータを扱うことができますね。

トラブルシュート

今回のDocker環境でコンテナを強制終了したような場合、Kuduにはテーブル情報が残っていても、Impala (メタストア)にテーブル情報がない、というように整合性が取れなくなる場合があります。これは Hive のメタストアに Apache Derby を使っているためで、本番環境では通常問題になりません。
しかし、この状態だと Impala でテーブル作成時に次のようなエラーが生じます。

ERROR: ImpalaRuntimeException: Error creating Kudu table 'impala::default.my_first_table'
CAUSED BY: ImpalaRuntimeException: Table 'impala::default.my_first_table' already exists in Kudu.

この場合は Kudu でテーブルを消します。

ブラウザで Master のアドレスを調べる

http://localhost:8051/masters


上記で表示された master 一覧のアドレスが次のコマンドで必要になります。

Tablet Server に接続する

次のようにコマンドを実行します。

docker exec -it docker_kudu-tserver-1_1 /bin/bash

master 一覧を表示する

必須ではありませんが、masterの一覧を確認します。IPアドレスは上部のスクリーンショットに表示されています。

kudu@ddf2612c2f08:/opt/kudu$ kudu master list 169.254.83.7:7051,169.254.83.7:7151,169.254.83.7:7251
               uuid               |   rpc-addresses   |   role
----------------------------------+-------------------+----------
 b3b9d412cdc244db80fc901f4a241cf1 | 169.254.83.7:7051 | FOLLOWER
 d7f840d45d5a48e49ed21bc7222d0b42 | 169.254.83.7:7151 | LEADER
 1d2bd149519a4d0ab42e41d012869237 | 169.254.83.7:7251 | FOLLOWER
kudu@ddf2612c2f08:/opt/kudu$

テーブル一覧を表示する

テーブル一覧を表示します。impala::default.my_first_table というテーブルが表示されていますが、これが整合性の取れていないテーブルです。(外部テーブルとして使っても良いのですが)

kudu@ddf2612c2f08:/opt/kudu$ kudu table list 169.254.83.7:7051,169.254.83.7:7151,169.254.83.7:7251
impala::default.my_first_table
kudu@ddf2612c2f08:/opt/kudu$

テーブルを削除する

テーブルを削除し、削除されていることを確認します。

kudu@ddf2612c2f08:/opt/kudu$ kudu table delete 169.254.83.7:7051,169.254.83.7:7151,169.254.83.7:7251 impala::default.my_first_table
kudu@ddf2612c2f08:/opt/kudu$ kudu table list 169.254.83.7:7051,169.254.83.7:7151,169.254.83.7:7251
kudu@ddf2612c2f08:/opt/kudu$

コメント