はじめに
今回は,
Impalaのクエリ処理の特徴
Impalaは,
また,
前回の説明にあったように,
まずHash Joinの処理を例にImpalaでの実行計画について説明し,
- ※1)
- このような設計方針のため,
Impalaのバージョン1の時点ではソートや結合の処理でメモリサイズを超えるような処理が必要となった場合にはエラー終了する動作となっていました。バージョン2になり, メモリに収まらないハッシュ表のDisk Spillなども行われるようになりましたが, 処理の高速性を保つためにはメモリ上で処理を完結させることが重要であることは変わりません。
実行計画とplan fragment
今回は,
select count(colA) from tabA join tabB on colA=colB join tabC on colB=colC;
Impalaでは,
図1 実行計画の例
Operator #Hosts Avg Time Max Time #Rows Est. #Rows Peak Mem Est. Peak Mem Detail --------------------------------------------------------------------------------------------------------------------- 09:AGGREGATE 1 181.94ms 181.94ms 1 1 20.00 KB -1.00 B FINALIZE 08:EXCHANGE 1 73.592us 73.592us 3 1 0 -1.00 B UNPARTITIONED 05:AGGREGATE 3 270.619ms 292.402ms 3 1 8.64 MB 10.00 MB 04:HASH JOIN 3 35.811ms 77.643ms 36.63K 33.94M 50.05 MB 3.23 MB INNER JOIN, BROADCAST |--07:EXCHANGE 3 33.631ms 36.165ms 769.23K 769.23K 0 0 BROADCAST | 02:SCAN HDFS 1 357.375ms 357.375ms 769.23K 769.23K 8.66 MB 32.00 MB default.tabc 03:HASH JOIN 3 2s072ms 3s076ms 476.19K 33.33M 203.02 MB 5.99 MB INNER JOIN, BROADCAST |--06:EXCHANGE 3 69.922ms 74.444ms 1.43M 1.43M 0 0 BROADCAST | 01:SCAN HDFS 1 586.556ms 586.556ms 1.43M 1.43M 12.66 MB 48.00 MB default.tabb 00:SCAN HDFS 3 531.481ms 761.759ms 33.33M 33.33M 32.66 MB 176.00 MB default.taba
図1のOperator列の各行をそれぞれ見てみましょう。
- AGGREGATION
- 集約関数
(上記のcountなど) の集約処理を表します。今回は列値によるgroup byを実施していないため結果が1行にまとまっていますが, 集約を実施する場合Impalaはメモリ上にgroup byのキーでハッシュ表を作成することにより処理を実行します - EXCHANGE
- あるノードにおいて,
ほかのノードから再分配されたレコードを受け取る処理を表します。その際, データはほかのノードのメモリからネットワークなどを介して, 当該ノードのメモリへと転送されます。 - HASH JOIN
- メモリ上にハッシュ表を作成して等結合を行う処理を表します。Impalaでは,
ハッシュ表を内部表 (今回のtabBとtabC) として, 外部表 (今回のtabA) の値をProbeし, 結合処理を行います (第5回の 「Impala/ Presto」 , 第8回の 「Impala/ Prestoにおける結合処理」 )。 - SCAN HDFS
- データの読み出し処理を表します。データの読み出し元は,
HDFSが一般的ですが, HBaseやAmazon S3などのほかのストレージを用いることも可能です。
これらをふまえて実行計画を見てみると,
Impalaの場合,
以下に,
図3 plan fragmentの例
F00:PLAN FRAGMENT [RANDOM] DATASTREAM SINK [FRAGMENT=F03, EXCHANGE=08, UNPARTITIONED] 05:AGGREGATE | output: count(colA) | hosts=3 per-host-mem=10.00MB | tuple-ids=3 row-size=8B cardinality=1 | 04:HASH JOIN [INNER JOIN, BROADCAST] | hash predicates: colB = colC | hosts=3 per-host-mem=3.23MB | tuple-ids=0,1,2 row-size=12B cardinality=33940820 | |--07:EXCHANGE [BROADCAST] | hosts=1 per-host-mem=0B | tuple-ids=2 row-size=4B cardinality=769231 | 03:HASH JOIN [INNER JOIN, BROADCAST] | hash predicates: colA = colB | hosts=3 per-host-mem=5.99MB | tuple-ids=0,1 row-size=8B cardinality=33333334 | |--06:EXCHANGE [BROADCAST] | hosts=1 per-host-mem=0B | tuple-ids=1 row-size=4B cardinality=1428572 | 00:SCAN HDFS [default.taba, RANDOM] partitions=1/1 files=1 size=282.57MB table stats: 33333334 rows total column stats: all hosts=3 per-host-mem=176.00MB tuple-ids=0 row-size=4B cardinality=33333334
上記はHash JoinからAggregationまでを行うplan fragmentですが,
図1の2つ目の列は#Hostsとなっていて,
- ※2)
- Impalaのprofileコマンドは,
クエリの実行結果をパフォーマンス統計の観点からまとめたレポートです。profileコマンドで見るほかに, ImpaladのWeb UIや, クラスタ自体の管理ツールであるCloudera Managerから見ることもできます。当該ツールにおいては, 各処理の実行時間や処理量 (行数), メモリ使用量 (単一ノードでの最大値) などを確認することができます。このとき, 見積り (Est.の列) と実際の値が特にSCANの行で大きく異なる場合, 統計情報がない, もしくは統計情報が古いことが考えられます。適切な実行計画を作成できておらず, 実行時間やメモリ使用量に影響があることも考えられるので, 統計情報を収集することを検討してください (マニュアルも参照)。 - ※3)
- 対象の表が小さい場合などにおいては,
コーディネータが単一ノードでクエリの処理を完結させるように指示する場合もあります。