2013年10月にHadoop 2.2が正式リリースされて以来、Hadoopの世界は大きく変わりました。それまでの概念である「Hadoop= HDFS+MapReduce」が刷新され、MapReduceが受け持っていたMapデータ処理とクラスタリソース管理が分離できるようになりました。これにより、SparkなどMapReduce以外のデータ処理エンジンがHadoop上で利用可能になりました。
そしてHadoopのクラスタリソース管理を行うミドルウェアとして、新たなデファクトスタンダードの地位を確立しようとしているのが「Apache Hadoop YARN(Yet Another Resource Negotiator: YARN) 」です。YARNの登場は並列分散処理にどんな変化をもたらすのでしょうか。本稿では2月8日に行われた「Hadoop Spark Conference Japan 2016」での小沢健史氏(Hadoopコミッタ/PMC、NTTソフトウェア イノベーションセンタ)によるセッション「YARN: 分析プラットフォームのためのリソース管理基盤」の内容をもとに、YARNがナビゲートしようとしている世界を覗いてみたいと思います。
Hadoop Conference Japan 2016セッションでの小沢健史氏
データ分析基盤の分離とスケーラビリティ確保のために
前述したようにYARNとは、Hadoopクラスタを構成するリソースの管理を行うミドルウェアであり、Hadoopを構成するコンポーネントのひとつです。小沢氏はYARNが提供する機能として、以下の3つを挙げています。
計算機クラスタ内におけるリソース管理
YARNアプリケーションの実行履歴の表示
YARN上で動作中のサービスの場所を知るためのしくみ(サービスレジストリ)
YARNが登場してきた背景には、バッチ処理やマシンラーニングなど、データ分析の目的ごとにデータの処理基盤を切り替えて使い分けたいというニーズがありました。小沢氏は例としてGoogleの事例を紹介、「 Googleでは、バッチ処理にTenzingやMapReduceを、SQLにはBigQueryを、マシンラーニングにはTensorFlowを利用している」と説明しています。
セッションの模様:「YARNとは?」
こうしたデータ分析基盤を使い分けたいというニーズに対し、「 処理基盤ごとにクラスタを分ける」と「処理基盤を(1つのクラスタ内に)同居させる」という2つの方法を取ることが考えられます。前者の場合はリソースの分離を簡単に行うことができますが、クラスタ間でデータを同期させる必要が生じます。後者は逆にデータの同期は不要ですが、今度はリソースの分離が難しくなります。
ではYARNは設計方針としてどちらの手法をとっているのでしょうか。小沢氏は「Hadoopは巨大なデータを処理するためにスケーラビリティ重視で設計された。したがってHadoopのコンポーネントであるYARNもHadoopと同様、スケーラビリティを重視している。そのためデータは動かさず、複数のデータ処理基盤を1つのクラスタ内に同居させる選択をしている」と、Hadoopのスケーラビリティ重視という特徴に沿っていることを強調しています。
もともと、YARNはHadoop開発の中心企業でもあるYahoo!の「MapReduceでは大規模処理(4000台級)に対応しきれず、スケールしない。処理系のマスタをジョブごとに立ち上げたい」という要望から生まれました。Yahoo!では3万6000台を超えるマシンで構成されたHadoopクラスタが稼働していましたが、この規模になるとマスタ(JobTracker)の仕事量が多くなりすぎて、スケーラビリティに深刻な問題が生じます。マスタの仕事を減らし、クラスタ内の個々のスレーブ(TaskTracker)に割り振ることで、ジョブの並列実行を増やし、スケーラビリティを向上させる ─YARNの設計思想の中心にあるのはHadoopと同様、「 スケーラビリティ」であることがわかります。
YARNを支える3つの機能、今とこれから
YARNのリソース管理
YARNではマスタとしてResourceManagerがクラスタ全体のリソースを管理し、スレーブであるNodeMangerが計算機ごとのコンテナを管理します。アプリケーションの実行依頼があると、ResourceManagerがNodeManager上にコンテナを確保し、アプリケーションの要求に応じてリソースを割り当て、NodeManagerがそのアプリケーションのライフサイクルを管理します。MapReduceもYARN上では分散アプリケーションのひとつとして、スレーブ内のコンテナ上で実行されることになります。
YARNのリソース管理アーキテクチャ
小沢氏はここで、YARNにおけるリソース管理の課題として「割り当てられたコンテナのリソースがすべて使いきれているとは限らない」を挙げています。YARNでは、アプリケーションの実行依頼ごとにジョブがキックされますが、その際、実行環境としてジョブがResourceManagerに要求するリソースは「全部使い切るとは限らない、最大値の要求であるため、すこしずつリソースが余る」( 小沢氏)ことになりやすいのです。小沢氏は「過剰なリソースの割当は個人的にとても課題意識をもっている部分。たとえば割り当て済みのCPUリソースを見て、意図しないで暴走するタスクがあらわれるかもしれない」として、その解決策としてYARNコミュニティにおいて「割り当て済みのコンテナをすべてモニタリングし、リソースが空いているようならコンテナ容量を超過してコンテナを動作させる」という提案がなされていると紹介しています。リソースの適切な割り当ては、今後のYARN開発にとって引き続き重要なテーマだといえます。
バージョン2で変わる! 履歴管理
YARNの2つめの機能である履歴管理として、Timeline Serverの説明がありました。Timeline ServerはYARN上で実行中、もしくは実行完了したアプリケーションの情報を保存/閲覧するサーバです。アプリケーションの履歴を参照することで、パフォーマンスチューニングやデバッグに活用することが可能になります。履歴として保存されるデータは
YARNアプリケーションすべてに共通な情報 … 割り当てられたコンテナ数、キューの名前など
各YARNアプリケーション固有の情報 … MapReduceならMapper/Reducerのカウンタ数やシャッフル量など
の2種類がありますが、YARNのパッケージに含まれるTimeline Serverで閲覧できるのは1.の汎用的な情報だけです。小沢氏はTezに含まれる、きめ細やかな表示が可能なTez-UIを使うことで「たとえばMapタスクがどのくらい利用されているのかなどを詳細にチェックするといったリッチな性能解析が可能になる」と紹介しています。
現在のTimeline Serverは「アプリケーションの数が増えても問題なく動作すること、ビューワが作成しやすいようにRESTful APIをもつこと」( 小沢氏)を前提に設計されています。「 バージョン1(V1)ではバックエンドストレージはプラガブル(デフォルトはLevelDB)でWriterとReaderはすべてTimeline Serverが代わりに行っている。一方、開発中のバージョン2(V2)では、バックエンドストレージにスケーラブルなKVSを想定しており、HBaseを主眼に置いて開発されている。WriterとReaderも異なり、分散書き込み/読み込みに対応する。またAPIの劇的な変更もあり、複数のジョブをまたがったプロファイリングや情報の保存/取得が可能になる」( 小沢氏) 。
Timeline Serverの設計思想
なお、Yahoo!ではすでに「バックエンドでHBaseを運用しており、彼ら専用にチューニングしたTimeline Serverが開発中」( 小沢氏)とのこと。それらの成果もV2移行で取り入れられることもありそうです。
サービスレジストリ
3つめの機能であるサービスレジストリですが、この機能があることで、クライアントは簡単にデプロイ済みのアプリケーションに接続することが可能になります。「 アプリケーションがどのポートで動いているか、ResourceManagerがZooKeeperに登録し、クライアントはZooKeeperに問い合わせることで書き込み先を把握、ダイレクトにアプリケーションに接続できる」と小沢氏。どちらかというと開発者のための機能であり、YARN上でHBaseを使うケースなどで威力を発揮します。
サービスレジストリとは?
YARN上の新たな分散処理基盤 ─DAG
冒頭でも触れたとおり、YARNが実装されたことにより、TezやSpark、FlinkなどMapReduce以外の並列分散処理基盤がいくつも登場してきました。小沢氏はこれらのミドルウェアの特徴として「MapReduceより汎用的で記述性が高い」ことを挙げています。そしてこれらの分散処理基盤でキーワードとなるのが「DAG(Directed Acyclic Graph: 非循環有向グラフ) 」です。これはMapReduceのかつてのライバルだったMicrosoftの「Dryad」が採用していたアーキテクチャでもあります。
MapReduceでは、Map - Shuffle - Reduceといった一連の操作においてひとつの処理が終わるまで次の処理を始めることができません。Shuffleが終わるまでReduceは実行できず、Reduceが終わるまでは次のジョブは開始できません。またHDFSに絶対に書き込むことが求められます。これは並列処理という面では非常にマイナスです。
DAGの概要
一方、DAGではMap - Map - Reduceのような、以前であれば複数のMapReduceジョブで表現していた処理を単一のクエリで表現することができます。そしてSparkのような「モダンな並列分散処理基盤」は基本的にDAGを用いたジョブの記述が可能で、その上でそれぞれにプラスアルファの特徴があります。
Tez
DAG+ディスク最適化+低レイテンシ用最適化機構+インタフェースはHive/Pig/Spark/Flinkなどを想定
Spark
DAG+低レイテンシ実現のためのインメモリ計算機構+関数型言語ライクなインタフェース
Flink
DAG+独自のシャッフル機構+ストリーミング処理とバッチ処理等価なインタフェース
しかし、これらの並列分散処理基盤をYARNで実装する上ではもちろん課題もあります。小沢氏は、ジョブの立ち上げに時間がかかること、そしてウォーミングアップに時間がかかることを挙げており、「 Tez、Spark、FlinkはJVMで動作するため、この問題が起こりやすい」と指摘します。
ではこれらの課題に対し、どういった工夫がなされているのか。小沢氏はTezとSparkについてそれぞれ説明しています。
まずTezについて。Hiveなど高級言語によるインタフェースでのバッチ処理を前提に設計されたTezは、もともと遅延よりも処理スループットを重視していました。そのため、コンテナは処理が終われば手放すように設計されていたのですが、コンテナの再利用を図ることで、ひとつのコンテナでMapもReduceも実行できるようなしくみが追加されました。ジョブ実行時、可能な限り計算リソースを手放さずに再利用し、ジョブが完了してもセッションが切れない限りリソースを確保できています。またセッションとは関係なく「デーモンとしてすべてのマシンに立ち上げっぱなし」( 小沢氏)のHive用コンテナを利用する「Long Lived and Process」というしくみにより、ウォームアップ済みのJVMやファイルキャッシュが利用できるので、高速処理が可能になっています。
Sparkにおいては、現在YARNにおける動作モードとして
yarn-clusterモード
ジョブを投入する:YARNコンテナ上でSparkドライバを起動
yarn-clientモード
対話式の実行形態を想定:クライアント側でSparkドライバ
の2つが存在します。とくにSparkは対話式プログラミングに強いため、Tezのコンテナ再利用レベルの機能はすでに導入済みとのこと。しかしインメモリ型の処理機構であるSparkは「コンテナを終了できない(インメモリが消えてしまう) 」という事情があるため、計算リソースを使っていなくても手放すことができないという状態に陥ることになり、結果としてリソース利用率の低下を招きます。
yarn-clusterモードとyarn-clientモード
この対策としてSpark 1.2からワークロードに応じてコンテナを動的に確保/削除する方法が取られています。タスクが残っている状態で一定時間以上経過したら、アイドル状態のコンテナを開放するというしくみですが、中間データはNodeManagerのシャッフルサービスで永続化するため、インメモリのメリットは薄くなるという欠点もあります。
Sparkの動的リソース管理
TezもSparkも互いに最適化することで、低レイテンシと高スループットの両立を目指しており、開発がすすむにつれ、幅広いニーズに応えられる処理系に成長することが期待されています。
HadoopのリソースマネージャとしてはYARNのほかにもうひとつ、Apache Mesosが存在します。講演終了後、YARNとMesosの関係に小沢氏に伺ったところ「両方ともHadoopのリソースマネージャとして、統合する動きも一部あるが、現在は棲み分けられている状態。TezやSparkなどHadoop系の処理基盤との連携が多いのはYARN。MesosはPaas基盤、そしてSpark Streamingでの事例が増えている」とのこと。両者ともに究極的なゴールはデータセンターにおけるリソース管理を行うというものですが、そのプロセスはそれぞれに異なっているようです。
"Yet Another"という言葉通り、つねにひとつ先の未来を志向しているYARN。小沢氏をはじめとするコミッタ/PMCと多くの開発たちの手によって、YARNリソース管理基盤からデータセンターOSへと確実に進化の階段を上っているようです。