Cloudera Impalaのアーキテクチャ

(本ブログは若干古くなっているので、Impala情報ページをご覧下さい。比較的新しい情報をまとめています)

一人アドベントカレンダー25日目、最終日です。

2013_12_14_18_ 3

最終日はCloudera Impala(以下Impala)について。Impalaは分散クエリエンジンです。最近EMRでも利用できるようになりました。

Hiveとは何が違うのか、なぜHiveを高速化しなかったのかというような意見もあるようですが、その答えはClouderaの創業者でもあるMike Olsonが今週公開したブログ(Impala v Hive)に詳しく書かれています。かなり興味深い内容ですが、今のところ英語のみです。きっと日本語の記事もいずれ読めるようになるはず。。。

さて、最終日はCloudera Impalaのアーキテクチャについて書いてみます。引用している資料はSlideshareでClouderaが公開しているものです。リンクは一番下の参考資料をご覧下さい。

Cloudera Impala


http://impala.io/img/impala-logo.png

Impala開発の背景

Impalaは1年以上前に発表されたクエリエンジンで、現在のバージョンは1.2.3です。Hadoopでビッグデータを処理するためには、当初MapReduceのコードをJavaやStreamingで記述する必要がありました。しかし、バッチ処理はともかくとして、分析などに使おうとすると、分析の度に多くのコードを書き換えるのが大変ということで、Yahoo!ではApache Pigが開発され、FacebookではHiveが開発されました。

SQLライクな言語が利用できるHiveは、大量データ、いわゆるビッグデータの処理のためには向いていますが、それほどデータ量が多くない場合、およびRDBMS同様のリアルタイム性が必要な処理には向いていません。利用するユーザーが増え、BIツールなどがODBCやJDBC経由でHiveを利用するようになり、Hiveのクエリを高速に行いたい言う要望が高まってきました。

そのころ、Googleではビッグデータに対するSQLアクセスに、MapReduceを使用しない新しい分散クエリエンジン(F1)を開発しました。Impalaも、既存のMapReduceを高速化するのではなく、あるいはSQLを翻訳して別のフレームワークで実行するのではなく、完全に新しい分散クエリエンジンとして開発されました。現在はApacheライセンスのオープンソースとして開発が続けられており、githubでソースコードが公開されています [1]

Impalaは高いパフォーマンスを目指しています。C++で開発されており、ランタイムでのコード生成にはLLVMを使用し、ショートサーキットリードを使ってデータノード上のデータに直接アクセスするなど、パフォーマンス上のボトルネックを減らすようにしています。中間データやメモリから溢れたデータもディスクには書かれません。

Impalaのアーキテクチャ

Impalaは分散システムです。全てのデータノードが動作しているノードでImpalaサーバー(impalad)も実行します。MapReduceは使用しないので、タスクトラッカーを同居させる必要はありません。

また、Impalaにはstatestoreというサービスが必要です。これは一般的なマスターノードとは若干役割が異なり、クエリの計画の際などに必要な各ノードの状態を保存するためなどに使用されています。

impala1

また、ImpalaはHiveと同じメタストアを利用します。つまり、同じデータに対してHiveを使ってクエリを行うことも可能ですし、Impalaを使ってクエリを行うこともできます[2]。最新のImpalaはCatalog Serviceを導入し、メタ情報のリフレッシュを自動で行うことができるようになっています。(過去のブログを参照)

クライアントからクエリの受付け

クライアントがODBC/JDBC/Beeswax/シェルなどからクエリを実行すると、1台のImpaladが処理を受け付けます。Impalaにはマスターノードは存在していないので[3]、クライアントはどのノードに対してもクエリを投げることができます。

impala2

クエリを受け付けたノードのQuery Plannerは、リクエストを分散実行するための実行計画を立て、プランをフラグメントの集合にします。続いて、Query Coordinatorは、処理をすべきデータを持っているノードのimpaladに対して処理を分散します。この際、データを持っているデータノードはどれかを特定するために、ネームノードにもアクセスします。今後HDFS Caching(HDFS-4949)の仕組みが導入されると、さらに良い結果が得られるのではないかと思います。

impala3分散されたクエリは各ノードで実行されます。Query Executorは必要に応じてHDFSやHBase上のデータを読み込みます。HDFSにはショートサーキットリードという仕組みがあるので、Query Executorがデータを読み出す度にネームノードにアクセスする必要はありません。

分散して実行された結果はimpalad間でストリームで通信されます。MapReduceとは異なり、中間データがディスクに書かれることはありません。従って、大量のデータを処理するため(正確にはクエリの結果が大量になるようなケース)、多くのメモリを搭載している必要があります。

impala4Query Executorで実行された中間結果はストリームでQuery Coordinatorに返ってきます。必要に応じて集約を行い、中間結果をまとめてクライアントに返します。

JOINの処理

クエリの実行の際、複数のデータセットの結合が必要な場合は多いでしょう。Impalaでは Left-Deep Join Treeというツリーを作成し、順番に実行していきます。

impala5スライドには「最も大きなテーブルをFROM節の最初にする必要がある」と書いてありますが、ver 1.2.2以降でコストベースのジョインオプティマイザが導入され、自動的に調整されるようになりました。

クエリと論理実行計画は以下のようになります。impala6 impala7 impala8なお、Impalaのドキュメントはかなり充実しています。もっと詳しく知りたい方は是非ご覧下さい。http://www.cloudera.com/content/support/en/documentation/cloudera-impala/cloudera-impala-documentation-v1-latest.html

雑記

一人アドベントカレンダー、軽い気持ちで始めてみたものの、12月は業務が想像以上に忙しく激しく後悔。おかげで年内は休みなく仕事をしなければならなさそう。

でも、それなりに知見も得られたので良かったかな。楽しんでいただければ幸いです。

補足

[1] Cloudera Impalaのgithub http://cloudera.github.io/impala/

[2] 現時点では複雑なデータ型(MAPやSTRUCT)は利用できません。また、カスタムのSerDeは利用できません。これはImpalaは処理を高速化するため、汎用フォーマットはImpalaがネイティブにサポートする方針のためとのことです。UDFは、C++で記述またはHiveのUDFが利用できます。

[3] 各ノードの状態を管理する軽量のStatestoreと、ver1.2以降ではHiveのメタストアとの同期を取るCatalogServiceが必要です

参考資料

http://www.slideshare.net/insideHPC/impala-overview
http://www.slideshare.net/huguk/hug-london2013
http://www.slideshare.net/mapredit/cloudera-impala-hug-karlsruhe
https://speakerdeck.com/grahn/practical-performance-analysis-and-tuning-for-cloudera-impala

Pocket

One thought on “Cloudera Impalaのアーキテクチャ

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)