Hadoopはどのように動くのか ─並列・分散システム技術から読み解くHadoop処理系の設計と実装

第17回Impalaの設計と実装[1]

はじめに

今回から3回に渡って、Hadoop上で動作するデータ処理ソフトウェアの1つであるApache Impala(incubating)(以下、Impala)について、以下の流れで説明していきます。

  • Impala概要(今回)
  • クエリ実行時の並列化の仕組み(第18回)
  • I/O処理における高速化の仕組み(第19回)

Impalaの特徴のすべてをお伝えできるわけではありませんが、Impalaの速度に対する取り組みについて参考になれば幸いです。

今回は、Impalaが開発されるに至った背景や特徴、および動作の概要までを紹介していきます。

Impala開発の背景

これまでの連載内でも触れられてきましたが、ImpalaはHadoop上でSQL(正確にはHive Query Language/HiveQL)を高速に処理するために開発された並列データ処理系です。Impala以前から、SQLを実行するHadoopのエコシステムとして、Apache Hive(以下、Hive)が存在していました。少し長くなりますが、Impalaが先行のHiveとは別に新規に開発された背景を説明していきます。

Hadoopは、バッチ処理をMapReduceで行う並列データ処理系(並列データ処理フレームワーク)として構築されました。本連載第7回でも述べられているように、MapReduceは非常に強力なフレームワークである一方、それを用いたアプリケーションの記述はJava言語を用いた手続き的な方法となり、必ずしも生産性が高くないため、処理を簡潔に記述するために、Apache Pig(以下、Pig)やHiveといった宣言的なクエリで問い合わせができるインターフェースが用いられてきました。特にHiveは、SQLに似たHiveQLでクエリを記述できることから人気が高まり、JDBC/ODBC経由でのアクセスなどが整備された結果、元々はリレーショナルデータベースやデータウェアハウス(DWH)に接続することを用途としたアプリケーションからも利用できるようになっていきました。

Hiveは、接続方法が整備されたことで、DWHにおける低レイテンシ指向の問い合わせを始めとした、バッチ以外のさまざまなワークロードの問い合わせを有するアプリケーションから接続されるようになりました。しかしながら、HiveひいてはMapReduceと、並列データベースに代表されるDWHで期待される特性は、本連載第14回で述べられているように異なります。DWHを想定したアプリケーションからの問い合わせをHiveにおいて処理する場合は、応答時間が長くなるだけでなく、タイムアウトなどの理由でアプリケーション側から強制終了され、実行が停止してしまうこともありました。

このような状況は期待する特性の齟齬によるものであったため、ImpalaはHiveの特性に合わないアドホックなSQL処理の要望に応えるべく、処理エンジンを含めて新規に開発されました。

Impalaの特長

一般に、Impalaの処理はHiveと比較して非常に高速です。しかし、ImpalaはHiveを置き替えるものではありません。本連載第8回の「ImpalaやPrestoの高速性の理由」でも述べられているように、Impalaは応答速度を重視するため、耐障害性について妥協している側面があります。そのため、バッチ処理としての高スループットを目指す用途ではHiveを用い、分析などのアドホッククエリに対して高速に応答を返す用途ではImpalaを用いる、というように使い分けることを想定しています。

上記のような背景で開発されたImpalaは、アドホッククエリに対応すべく、特に次の2つをはじめとするさまざまな特徴や特性を有しています。

  1. アドホッククエリに特化すべく、MapReduceやSparkなどの汎用エンジンを用いずに記述された並列SQL処理エンジン
  2. I/O先読みやランタイムコード生成をはじめとする種々の方式による高効率性

第18回ではおもに1. について、第19回ではおもに2. について、それぞれ説明していきます.今回はその準備として、続く説明でImpalaの基本的な構成と処理の流れについて紹介します。

Impalaの構成要素

動作の説明に先立って、Impalaの構成要素およびImpalaに関連するコンポーネントについて説明します。Impalaは、ほかのHadoopのエコシステム同様、複数の要素から成り立っています。

Impala Daemon(impalad)

ImpalaにおけるSQL処理の中核を担うデーモンです。

後述のDataNodeが起動する各ノードで起動し、クエリを受け取った後にほかのimpaladと連携してクエリを実行し、クライアントに結果を返します。クライアントは、どのノード上のimpaladにアクセスすることも可能です。特に、クエリ実行時にクライアントと直接通信を行うimpaladは、クエリ実行全体を管理する役割を持ち、コーディネータと呼ばれます。

Catalog Server(catalogd)

Hadoopクラスタ上でImpalaが使用するメタデータを管理するデーモンであり、クラスタ上で1つだけ起動されます。

catalogdは、Hiveのカタログ管理デーモンであるMetastore(テーブル定義などのメタ情報)を元に動作し、Impalaが発行したDDLをMetastoreに保存する中継役を担います。また、Metastoreの情報とHDFSのメタデータをキャッシュし、問い合わせにおいて実行計画を作成する際のメタデータアクセスを高速化します。

StateStore

Hadoopクラスタ上でimpaladの状態を監視するデーモンであり、クラスタ上で1つだけ起動されます。

このデーモンが各impaladの状況を監視し連携することで、停止しているimpaladに処理を要求されないように調整します。また、catalogdの保持する情報を各impaladに配布する役割も担います。

下記の図1でオレンジ色の部分がImpalaのデーモンになります。

図1 Impalaの構成要素
図1 Impalaの構成要素

続けて、Impalaそのものではないものの強く関連しているコンポーネントについて紹介します。これらは上の図で青色の部分です。

Impala クライアント

クエリを発行するクライアントプログラムもImpalaにおける重要なコンポーネントの1つです。impala-shellというコマンドラインクライアントもありますが、JDBC/ODBCを使用してユーザーのアプリケーションからクエリを実行することも可能です。

HDFS NameNode(NN)

HDFSが管理するブロックのメタデータを管理するデーモンです。Impalaでのクエリ実行時のHDFSアクセスに必要な情報もNameNodeから提供されます。NameNodeについては本連載第11回のHDFSにおけるレプリケーション第14回のHDFS、YARN、MapReduceの実装の内容も参考にしてください。

HDFS DataNode(DN)

HDFSが管理するブロック自体を管理するデーモンです。Impaladは、HDFS上のファイルにアクセスするために、NameNodeから取得したメタデータを元に、DataNodeからデータを取得します。そのために、ImpaladはDataNodeと同じノードで起動する必要があります。DataNodeについても、NameNodeと同様、本連載第11回のHDFSにおけるレプリケーションや第14回のHDFS、YARN、MapReduceの実装で紹介されています。

Hive Metastore Server(HMS)

Hiveのメタデータを管理するデーモンです。前述のとおり、Impalaはテーブル定義の情報をHiveのMetastoreに保存します。

今回の連載では、おもにデータ処理を行うimpaladの動作に焦点を当てて見ていきます。

クエリ実行時の処理の流れ

上述のように、Impalaではクライアントからクラスタ上の任意のimpaladに接続してクエリを発行して結果を得ることができます。図2は、この処理の順序を単純化して示したものです。実際にクエリを受け取ったimpaladがコーディネータとなり、下記の流れでクエリを実行します。

  1. クライアントがコーディネータにSQLを送信
  2. コーディネータがSQLの実行計画を作成し、各impaladに処理内容(部分クエリ)を分配
  3. 各impaladはコーディネータから受けた部分クエリを実行。その際、必要に応じてHDFSからデータを取得
  4. 各impaladの実行結果をコーディネータが統合
  5. コーディネータからクライアントにクエリの結果を送信
図2 Impalaのクエリ実行時のイメージ
図2 Impalaのクエリ実行時のイメージ

次回からは、このクエリ処理の流れを前提として説明していきます。

おわりに

今回は、Impalaの開発に至る背景と、動作の概要を説明しました。次回は、ハッシュ結合の並列化方法やLLVMにおけるランタイムコード生成による高速化方法をはじめとする、Impalaにおけるクエリ実行時の並列化の仕組みについて説明します。

おすすめ記事

記事・ニュース一覧