Skip to content

Instantly share code, notes, and snippets.

@repeatedly
Created October 25, 2012 02:28
Show Gist options
  • Save repeatedly/3950123 to your computer and use it in GitHub Desktop.
Save repeatedly/3950123 to your computer and use it in GitHub Desktop.
Impala

なんかClouderaが出したらしい.Hiveと違ってMapReduceをやらず,独自のクエリエンジンを使っている.場合によっては10x以上速くなるらしい.GoogleのDremelに触発されて2年かけて作ってたらしい.

構成

Frontend / Backendのサーバが2種類.FrontendがBeeswax経由でWebから叩けたりする.BackendはHDFSとかのデータノード上でクエリとかを実行するやつだと思われる(2.の実行エンジン辺り?).

ソース

主要なディレクトリはcommon, be(backend), fe(fronend)の3つ.

※ Thriftとかを実行して必要なソースを全部揃えてないので,確証がないので注意!

common

ThriftのIDLが入っている.ImpalaはThriftべったりなコードになっていて,IDLで定義されているデータがサーバ周りではそこかしこに出てくる.気になる人は生成しましょう

fe

これはJavaで書かれている.SQLのパーサやスキャナのbison/flexつき.なんでこれがJavaかというと,おそらくHiveとかをライブラリとして使いたいからだと思われる.

fe/src/main/java/com/cloudera/impala/service

feのエントリポイント.Frontend.javaがコアで,ここからクエリのオペレーションの解析やプランナを呼び出している(Hiveとかがライブラリでどこまで出来るのか詳しくないので,なんでこれをC++で実装してないのかは謎.誰か教えてください). fe/src/main/java/com/cloudera/impala/analysisにたくさんのExprを解析するためのクラス群がたまっている.

common/thrift/ImpalaPlanService.thriftを使うと,多分このFrontendを単独で動かすことが出来る.

be

これはC++で書かれている.

be/src/service/impala-server.{h,cc}

これらがサーバの本体.一つのサーバでFrontendとBackendの両方のAPIを持ってる(上のfeディレクトリがなんでfeという名前なのかは正直分かってない).Frontend/BackendのどちらもThriftサーバである.

impala-serverはサーバ起動時にfe/src/main/java/com/cloudera/impala/service/JniFrontend.java(Frontend.javaのJNIラッパー)を生成するというアプローチを取っていて,普通に使う分には外部にPlanServiceを別途立ち上げる必要は無い.

be/src/exprs

各クエリの表現が実装されている.各ExprにCodegenメソッドがあるので,そこでLLVMを使って頑張る.

be/src/exec

アグリゲーションとか,その辺の操作周りのクラスが入っている.操作によってはJITとかする.ここにもCodegenとかあって,正直この辺りimpalaがどこまでLLVMに依存しているのかまだ分かってない.

HBaseの読み込みはJNIで,HDFSは多分libhdfs.

be/src/sparrow

スケジューラとか入っている.Coodinatorが分散処理する時とかに多分使う.

その他のディレクトリ

ユーティリティとか.

処理の流れ

  1. どこからかQuery投げる
  2. BE(C++)が受ける
  3. FE(Java)にクエリを解析するため投げる
  4. BE(C++)でクエリを実行 with LLVM (複数ノードであれば,Coodinator経由で処理を分散して各ノードで実行.Dremelの影響を受けていると行っているが,この辺の分散処理はscatter/gatherみたいな感じ(Treeではない気がする))
  5. BE(C++)がHDFS/HBaseからデータを取ってきて処理実行
  6. 結果を返す

みたいな感じな気がする.

実際

クエリを投げると中でそのクエリに対応したidと状態が作られる.通常ではクエリのidが返され,クライアントはそのidを使って再度データのフェッチとかのリクエストを投げる.中ではidと状態のマップを持ってるので,そのまま返せば良い.これは多分,でかいデータだと本当に何秒かかるか分からんので,まぁよくあるAPI.sync用のAPIもあった気がする.

注意点

ここでHighになっているメモリ使用量を制限出来ない問題.いわゆるでかいデータでjoinとか使用とすると際限なくメモリ食いまくりますよ,ということなのでfixされるまで注意

TODO

  • Planner周りのソース真面目に読む
  • Coodinator周りのソース真面目に読む
  • クエリ実行部分のソース真面目に読む
  • その前にHiveのソース真面目に読む

参考文献

  1. https://github.com/cloudera/impala
  2. http://d.hatena.ne.jp/shiumachi/20121024/1351085695
  3. http://blog.cloudera.com/blog/2012/10/cloudera-impala-real-time-queries-in-apache-hadoop-for-real/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment