Apache Apollo 1.0 がリリースされた。ActiveMQ のサブプロジェクトである Apache Apollo は,マルチコア・マルチプロセッサ指向の新たなスレッディングモデルを備えることによって,速度とスケーラビリティ,さらには信頼性の面でも ActiveMQ やその他の多くのメッセージ処理プロジェクトを凌駕する。
Apollo 1.0 の特徴:
- Stomp 1.0 ワイヤプロトコル
- Stomp 1.1 ワイヤプロトコル
- トピックおよびキュー
- キューブラウザ
- トピックの恒久サブスクリプション
- 高信頼性メッセージング (reliable messaging)
- JMS API
- その他多数
Apollo の開発リーダである Hiram Chirino 氏は,Apollo 本来のパフォーマンスを実証するために STOMP ベンチマークを作成し,主要な STOMP ベンダ (JBoss HornetQ,ActiveMQ,Apollo) との等価比較を行った。しかし大部分のユーザは JMS API を使用すると想定されるので,妥当性の面でいくらか疑問な点がある。
そこで氏は Apollo の速度に対する疑念を晴らすべく,JMS ベンチマーク セットを新規に作成した。ベンチマークの結果は明確だ。Apollo の性能は極めて高く,ほとんどのシナリオにおいて JBoss HornetQ と ActiveMQ に明らかに勝っている。
氏は Apache Apollo 1.0 のリリース発表の中で,Apollo の開発がサブプロジェクトとして実施された理由として,プロセッサ市場のマルチコアへの移行に対処すべく構築された Apollo は ActiveMQ から根本的に独立した存在であるから,という説明をしている。ActiveMQ の現行バージョンには複雑なスレッドロック機構が採用されている。マルチコアマシンのメリットを活用する上で,これがボトルネックとなるのだ。Apollo サブプロジェクトがその信頼性の高さとスピード狂ぶりを実証した今,ActiveMQ 6 に Apollo が取り入れられる可能性は高そうだ。
InfoQ では今回のリリースに関して取材すべく,氏にコンタクトを取った。
InfoQ: マルチコアマイクロプロセッサ対応のために Apollo ではどのような最適化が実施されているのか,簡単に説明して頂けますか。
Apollo は libdispatch の基本的アイデアを採用して,非同期プロセッシングモデルへと完全に切り替えられています。このモデルでは,すべてのオペレーションがごく限られた数のスレッドで実行されます。それによってコンテキストスイッチの増加を回避しているのです。
Libdispatch は OS X のGrand Central Dispatch で使用されているライブラリだ。Apollo 開発の一環として氏は,libdispatch と Grand Central Dispatch の Java 版にあたるものを開発する HawtDispatch という別プロジェクトを立ち上げた。HawtDispatch ライブラリは libdispatch や Grand Central と同じ原理に従おうとしている。Apollo はこの HawtDispatch を採用して,マルチコアのメリットを活用している。
氏はさらに,HawtDispath の採用によって複数のクリティカルセクションの同時ロックに関する問題を解決し,パフォーマンスボトルネックを回避できたことも報告している。マルチコアに適したこのアプローチにより,Apache Apollo の処理にはウェイトが使用されていない。その代わり,アトミックなコンペア・アンド・スワップ(CAS,compare-and-swap) プロセッサ命令が多用されている。
InfoQ: ベンチマークを実行することで,JMS 市場について分かったことはありますか。
Java には優れたオープンソースのメッセージングオプションがたくさんあります。それが分かった点はよかったですね。それらすべてが同じ API を実装している (いくつかは同じワイヤプロトコルを使用している) ので,エンドユーザはアプリケーションの影響を心配せずに,あるベンダから他のベンダに移行することが可能なのです。
InfoQ: 全体的に Apollo STOMP の方が Apollo OpenWire より優秀なように見られますが,なぜでしょうか。STOMP は単純な文字列指向のプロトコルで,一方の OpenWire はバイナリ指向のプロトコルですから,明らかに OpenWire の方が高性能だと思えるのですが。
そうですね,帯域の限られたネットワークなど特定の条件であれば,OpenWire の方がよい結果を得られたのかも知れません -- そのようなケースでもベンチマークを行う必要がありそうです。一方ここで分かるのは,現在のプロセッサでは,少々のテキストヘッダとバイナリヘッダのパース処理では大差は出ない,ということです。そんなことよりプロセッサのキャッシュをホットに保ったり,過剰な同期処理よるプロセッサストールを回避するような最適化の方に時間を費やした方がよいでしょう。
InfoQ: HornetQ や ActiveMQ に比較して Apollo の性能が非常によいのですが,これは Apache Apollo の方がマルチコアプロセッサのメリットをよく活用しているということでしょうか。
マルチコアプロセッサを効果的に利用できていることもありますが,それだけではありません。プロデューサからコンシューマへのメッセージ移動に使う,フローコントロールとメモリバッファサイズの管理の優秀さも理由だと思います。Apollo で採用しているメモリ管理戦略は,スループットが良好である限りにおいてメモリバッファの使用を最少限にする,というものです。すぐに参照されないメッセージは,一度メモリから退避してディスクに保存します。参照速度に合わせてプロデューサをフロー制御する必要があるか,あるいは新たな生成メッセージを積極的にスワップアウトするべきかを判断するため,Apollo はコンシューマの処理速度を常に監視しています。また,退避したメッセージをコンシューマへの配信が可能になる前にメモリ上に用意しておけるように,ストレージの積極的なプリフェッチも行います。さらに Apollo は,メッセージのストレージ保存とコンシューマへのメッセージ送信を並列実行します。例えばストレージへの保存処理の完了前に コンシューマからメッセージ確認の応答があった場合,メッセージのストレージ保存やメモリからの削除処理は実行されません。結果的にこれは,ディスク IO の負荷を軽減することになります。
InfoQ: ジャーナリングに関しては,どのようなオプションがありますか。コードを見る限りでは,ジャーナリング (永続的キューと恒久的トピック) には LevelDB または BerkleyDB が使用されているようです。一方で以前の Apache ActiveMQ には,KahaDB あるいは AMQ Message Store (オープンソース JTA である JOTM と同じく Howl をベースにしたもの) が使用されていました。方針を変更した理由は何でしょう。キーバリュー型データベースをどのようにジャーナルに使っているのでしょうか。もうひとつ, LevelDB あるいは/または Berkley DB を使用するということから,Apollo はピュアJava ではないことになります。そうですよね? サポート対象 OS それぞれの JNI ライブラリをコンパイルする必要があるのでしょうか。Apollo が主として (少なくとも初期状態では) Linux をサポートするという理由はそこにあるのでしょうか。ピュア Java 版 Apollo の計画はあるのでしょうか,あるいはもはや無理な話なのですか。
BerkleyDB (BDB) ストアを選択した場合,ストアの実装には BDB API が使用されます。この場合は永続化処理の堅牢性を確保するため,BerkleyDB 自身がジャーナリングを提供します。
キー/バリューを小さく保つことが可能な場合には LevelDB インデックスの方が効率的です。以降のインデックス圧縮も小さくなるからです。このストアを選択した場合には,ActiveMQ KahaDB ストアと同じジャーナリング戦略を採用します。最初にすべての永続化操作とログファイルを同期します。LevelDB インデックスエントリは,通常はジャーナルファイルを示す単なるポインタなので,サイズは小さなままです。これにより LevelDB インデックスの非同期更新が可能になり,インデックスのパフォーマンスがさらに向上します。さらに LevelDB は,メッセージキューでの主要な利用パターンであるシーケンシャルな読み書きが,BTree ベースのインデックスに比較して非常に高速である点でも優れています。
(JNI の必要性について) Apollo にはピュア Java 実装の LevelDB も同梱されています。ネイティブバージョンが使用できないプラットフォーム,例えば Windows ではそちらのバージョンを使用することになります。さらにピュア Java 実装である BerkleyDB ベースのメッセージストアも選択可能です。ですから Linux の方が最適化の恩恵を受けられるとは言っても,それ以外のプラットフォームが冷遇されている訳ではありません。
この件に関しては,Linux 対 Windows (ネイティブジャーナリング対ピュア Java) の Apache Apollo ベンチマークが参考になるだろう。
LevelDB は Google の開発したキーバリュー型ストレージライブラリである。文字列キーから文字列バリューへの順序付きマッピングを提供する。
Apache Apollo プロジェクトを心から歓迎し, 1.0 リリースを祝福しよう。