Asakusa 0.8 with M3BP

Asakusaが新規に高速実行エンジン(M3BP)をサポートした。M3BPはメニーコア特化型のC++で実装されたDAGの実行エンジンになる。ノーチラスとFixstarsの共同開発のOSSで、単ノード・メニーコアでの「処理の高速化」に振っている。いわゆるIn-memoryの実行エンジンで、ノードのCPUコアを使い切ることを目標しており、余計な機能はすべて削った。データがサーバ・メモリーに乗るクラスのバッチ処理であれば、ほぼ物理限界までパフォーマンスをたたき出す。

http://www.asakusafw.com/release/20160412.html

実際のベンチマークは以下のwhite paperにある。
http://www.asakusafw.com/wp/wp-content/uploads/2016/04/M3forBP_WP_JA_2016Apr12.pdf

ベンチマーク対象のバッチ処理は、BOMの組み上げ再計算を行うもので、RDBMではかなり苦しい多段結合のフルバッチになっている。
MapReduce 2218sec
・Spark 229sec
・M3BP 112sec
(これはAzureでの比較で16コアでの結果だ。コア数を増やした場合はM3BPは40コア近辺で60sec程度までさらに短縮している。)

使ってみて「とにかく速い」につきる。ほぼコア・メモリーバンドと使い切っているので、データがノードに乗る限りにおいては、これ以上のパフォーマンスを出すのはなかなか難しいレベルまで来ている。(あとはどう効率的なDAGを組むかという話しかない)

これは以前のエントリーで書いたように、先のRSAを睨んだかたちでの、足下のメニーコアでの最速化を見ていることが背景にある。
http://d.hatena.ne.jp/okachimachiorz/20151225/1451028992

データフォーマットは当然だが、HDFSCSVあたりは普通にサポートしている。HDFSクラスターに一台サーバを追加して、そこで処理を実行することができる。Hadoop/Sparkでは処理が遅いjobをM3BP上で実行することにより処理時間を大幅に短縮することができる。結果としてのHadoop/Sparkの用途も広げることになると思う。

なお、2016年4月の時点で、現状のメニーコアは
http://news.mynavi.jp/news/2016/04/01/020/
にあるとおり、1CPUで22コアである。ノードはアーキテクチャが通常2ソケットであるので、ノードコアは物理44コアになる。サポートメモリーは1T(もっと上か?)程度になる。たいていの業務系のバッチ処理は、経験的にはこのサイズで収まる。まだ分析用途のためのHDFS上のデータであっても、いったんクレンジングし、適当なGroupByをしたあとであれば、同じような規模に収まると思う。

M3BPをサポートした結果、Asakusaはこれで以下の三つの実行エンジンをシームレスにサポートすることになった。Asakusaで書いたコードは、リコンパイルするだけで、一切修正することなく、各実行エンジンで走る。Asakusaの目標のひとつは、One size does not fit allを前提にしたうえでの、トータルで線形のスケーラビリティなので、各エンジンを使い分けることで、それにほぼ近づきつつある。データは普通にHDFSにあればよい。

・M3BP
C++の最速実装。処理データが1ノードで収まる場合はもっとも高速で効率が良い。

・Spark
ジョブ実行時の処理データのサイズが、1ノードで収まらず複数にまたがる場合はSparkでの実行が高速になる。

MapReduceHadoop
データサイズが巨大で、大規模なGroupByを行うような処理はMapReduceが最速になる。(それ以外はSparkのほうが高速)

「Asakusaの使いどころを大幅に広げた。」というのが、結果としての、個人的な率直な実感だ。用途的には、従来のAsakusaとはほぼ別物にまで進化していると思う。何ができるのか?という意味では以下が面白いと思っている。

RDB/分散クラスターの隙間を埋める
RDBでは処理性能が足らないが、かと言って分散クラスターでは過剰というケースでは、M3BPで処理をすることで高いパフォーマンスを得ることができるようになった。ここはいままでの分散処理基盤では完全にエアポケットになっていた。

HDFSに溜まったデータの処理の利用可能性を広げる
HDFSでのデータ連携も当たり前だが普通にできる。ある処理で、データはHDFSにあって、そもそもは大きなデータだが、ジョブ実行時に処理の途中からサイズが絞られて、結果Hadoop/Sparkのオーバーヘッドにコストがかかり、トータルでみると処理効率が悪い、というケースによりよい解決を提案できる。でかい処理はMapReduce/Sparkで行い、途中からM3BPに切り替えればよい。

■「"リアルタイム"・バッチ処理」という選択肢の提供
とにかくデータサイズが許容される範囲では処理が速い。RDBで4-5時間のバッチ処理が、Hadoopで20分程度まで短縮し、Sparkで5分程度になり、M3BPが1分を切るというレンジになってきた。バッチ処理のタイム・スケールはHourlyからMinutelyを経てSecondsの単位になってきている。こうなってくると、バッチ処理と"リアルタイム"(まぁ厳密には全然リアルタイムではないが)の違いがだんだん無くなってくる。結果、業務側でできることが格段に変わる。メニーコアの能力を使い切ることで、今までとは違うことができる。

■分散並列処理の敷居をさらに下げる
特にエッジ・ロケーションでの処理ではよい選択肢になる。1ノードなので、コストも場所も取らない。プレクレンジングの処理ではよりよい解決を提示できる。いままで、分散並列処理ということであれば、すぐに分散ノードということになっていたが、その前にまずは単ノードでの導入が可能になる。その後データが増加するにつれてクラスター構成にすればよい。

・今後
個人的には、あとはRSA的なものへの対応になる。今後のロードマップを見据えて開発する予定だ。その段階で「非同期処理(データを投げて、同期を取らずすなわち処理の終了を待たずに、次に処理を行う処理)」の実行基盤については、分散並列環境に限って言えばかなりの完成度になると思う。

やはり現状の分散並列環境、特にHadoopは、大規模データ向きである。これはこれで素晴らしい仕組みだと思う。ただし、世の中のすべてのデータ処理というセグメントでみれば、やはり過剰である部分は否めない。無論、データがPBクラスを越えるであれば、何も考えずにHadoopを使うべきだし、それは今後も変わらないだろう。TBの上位であれば、HadoopよりもSparkの方がほぼすべてのワークロードでは優位だろう。ただし、もっともメジャーであるのは、GBの上位からTBに届くかどうかレベルであり、かつ、RDBではやはり御しきれない、というデータボリュームだろう。ここに対応できるの実行エンジンがM3BPになる。Asakusaはこれらの実行基盤を透過的に使いこなし、データ処理をフルレンジでカバーする。

Asakusaで処理を記述しておけば、M3BP→Spark→MapReduceとコードをまったく変更せずに対応することが可能になっている。数件程度のデータの「バッチ処理」も数秒以内で終わり、かりにそれが数億件まで増加しても、そのままスケールアウトし、数十分で処理を終わらせる事が可能になる。