BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース vert.xのハイボリューム/スケーラブルなアーキテクチャ - Eberhard Wolff氏とのインタビュー

vert.xのハイボリューム/スケーラブルなアーキテクチャ - Eberhard Wolff氏とのインタビュー

原文(投稿日:2013/05/20)へのリンク

Web 2.0とモバイルクライアントの目覚ましい成長が,アプリケーションアーキテクチャに関する私たちの考え方を変えつつある。Node.jsは,サーバ側のソフトウェアに非ブロック/非同期のランタイム環境を構築することでこの課題に取り組もうと試みた,最初のテクノロジのひとつだ。そして昨年,同様のランタイムをJava仮想マシン上に実現するvert.xが登場した。Node.jsとは対照的にvert.xは,本来の意味での多言語(polyglot)アプローチを踏襲している。JavaScript,Groovy,Javaその他の言語を使ったシステムの構築や,ひとつのアプリケーション内での混在が可能だ。

InfoQはEberhard Wolff氏にコンタクトを取り,これら2つのテクノロジの間にある違い,それぞれをベースとした場合の開発アーキテクチャから生じる課題,各アーキテクチャの提供するメリットなどについて議論した。

氏は以前,SpringSourceの主席コンサルタントを務めていた。現在はadesso AGでアーキテクチャ,技術マネージャの役職にある。長年に渡ってエンタープライズシステムの解析と設計に携わってきた氏は,最近数ヶ月間をvert.xの研究開発に費やしているという。

InfoQ: Node.jsの誕生から約4年になります。vert.xは2年ほどですが,これらのテクノロジや概念に必要性のあることは明らかになっています。Node.jsとvert.xについての見解をお聞かせください。適用する上でどちらが便利なのでしょう,あるいはどのようなユースケースが相応しいのでしょうか?

Eberhard Wolff: たくさんのクライアントを扱うハイパフォーマンス環境では,ますます多くの課題が存在していると思います。そのためには,多数のクライアントを少数のスレッドで処理できる非同期モデルが有効です。しかし,vert.xはそれだけではありません。JVM上のアプリケーションで使用されるプログラミング言語は,通常は1つです。主要なプログラミング言語として選択されているのは,現在もなおJavaです。それに続くのが,独自のフレームワークを備えたScala,あるいはClojureといったところでしょう。これは.NETでの状況とは違います。.NETでは当初から多言語が意識されていました。ひとつのアプリケーションでさえ,そうだったのです。vert.xはこれと同じように,JVM上のさまざまな言語の共存を,これまでよりも容易にします。どの言語からでも,フレームワークを自然な感覚で使えるようにするためのラッパも用意しています。JVM上でJavaScriptコードを実行することもできますし,vert.xのイベントバス上でJSONオブジェクトを転送すれば,それをJavaやScalaなど他の言語に統合するようなことも可能です。本質的には多言語環境であるといえるJVMに対して,唯一アプローチしたものであるという点で,これは興味深い進展だと思っています。それからもうひとつ,JVMにはモジュラリティに関する問題があります。個々のモジュールを分離してデプロイ可能にするにはどうすればよいか,という件です。OSGiの採用はひとつの方法ですが,まだ広く利用されるには至っていません。サーバにさまざまなWARファイルをデプロイして,SOAPで相互に通信を行う方法もありますが,かなり複雑なソリューションである上,パフォーマンス上のオーバーヘッドも無視できません。それに比べると,vert.xのモジュール化アプローチはずっとエレガントです。すなわちvert.xは,非同期,多言語,そしてモジュール性を備えた,極めてユニークなフレームワークなのです。

 

InfoQ: Node.jsについてですが,私自身,実際にNode.jsサーバで動作するアプリケーションをひとつ書いているところです。そこではシングルスレッド方式で要求を処理するのですが,フォローアップ処理が必要な場合には,スレッドプールまで要求を送り込んで実行するようになっています。つまり,高レベルな概念としてのモジュラリティや独立したコンポーネントというものがなく,それぞれが相互に通信可能になっているのです。この部分について,vert.xではどのようになっているのでしょう?

Eberhard: vert.xでは,個々のモジュール – さまざまなデプロイ単位 – がイベントバスを使って,お互いにイベントを送信し合います。イベントには例えば,JSONオブジェクトを格納することができます。vert.xのモジュールは個々にクラスローダを持っています。実質的には独立したコンポーネントと言ってよいでしょう。ですから,機能を別々のモジュールに配置することも可能です。例えば,MongoDBを操作するモジュールがGithubで公開されています。このモジュールは,イベントバス経由で適切なイベントを受信して,データをデータベースに保存します。非同期プログラミングと比べると,一見しただけではごく小さな機能にも思われるかも知れません。しかし,エンタープライズアプリケーション内で頻繁に直面する問題に対処するものとして,実際にはとても重要なものだと思っています。

 

InfoQ: イベントバスに関して,少し詳しく説明して頂けますか?トピックやキューを持った,Java Messaging Systemのようなものと理解すればよいのでしょうか?

Eberhard: ポイント・ツー・ポイント接続だけでなく,パブリッシュ/サブスクライブ通信や,複数ノードへの配信も可能です。ただしイベントはトランジェントで,永続的なストレージなどにはストアされませんから,失われる可能性があります。信頼性に重点を置いているJMSとは違って,vert.xのイベントバスはパフォーマンスを重視しているのです。

 

InfoQ: モジュールの相互独立性はどの程度なのでしょう?コンポーネントを任意に選び出したとき,稼働中にそれを交換したり,アップグレードしたりすることは本当に可能なのでしょうか?そのモジュールへのメッセージはバックアップされて,モジュールが再起動するまでキューに保存されている,ということなのでしょうか?

Eberhard: 稼働中でもモジュールの交換やアップグレードは可能です。ただしイベントは永続化されていませんから,受信側が停止している間のイベントは破棄されることになります。

 

InfoQ: この環境で使用されるシステムは,どのようなものなのでしょう?結局のところ,開発しているシステム自体がハイパフォーマンスやスケーラブルといった概念にそぐわないものであれば,一方にそれらを求める訳にはいかないように思うのです。

Eberhard: そうですね。これもvert.xの特徴のひとつなのですが,worker verticleというものを定義することができるのです。worker verticleはスレッドプールを使用して,ブロックIOを使用するレガシーコードを組み込むことができます。スレッドプールとプライマリイベントループは分離されていますから,それによってイベントループがブロックされることはありません。従ってworker verticleでは,どんなタスクでも実行することができます – 同期処理でも,ブロックIOでも,何も問題ないのです。Javaの世界には非ブロッキング設計のされていないライブラリが数多くあります。その意味からも,この機能は非常に重要です。

 

InfoQ: 新たにシステムを設計しようというとき,これを事前に評価することは可能でしょうか?以前に,Node.jsの作者であるRyan Dahl氏のインタビューを読んだことがあります。氏はJavaScriptが選択肢として優れている理由として,周辺モジュールの数が少ないことを挙げていました。しかし "モジュールの数が少ない" ということは,理屈の面から言えば,極端に出来の悪いモジュール – 非同期処理で使用できるように設計されていないモジュール – はないはずだ,ということにもなります。Javaならば,適当に何かライブラリを選択しただけで,たちまちトラブルに見舞われてしまうように思えるのです。

Eberhard: そうでしょうね。そしてそのためにこそ,worker verticleが存在するのです。Node.jsの言っていることは理解できます。簡単に言ってしまえば,JavaScriptプログラマは非同期の概念を使うのに慣れている,ということでしょう。彼らはAJAXで長い間,非同期プログラミングをやってきているはずですから。Javaのコミュニティには "単純なフロントエンドばかり開発しているJavaScriptの連中と違って,我々は大規模システムの開発手法を理解している" という声があります – 少なくとも,過去にはありました。しかしAJAXのおかげで,彼らはコールバックと非同期の概念に対処しなければならなくなりました。それは彼らにとって,極めて自然なことです。従って,パフォーマンスに優れたJavaScript環境が入手可能となった現在では,JavaScriptをベースにNode.jsのようなものが開発されるのもごく自然なことです。このことは,vert.xの例を見ても分かると思います。JavaScriptの関数の代わりに,Javaでは匿名の内部クラスを使用しているのです。それが原因になって,非常にたくさんのコードが必要になりました。個人的な意見ですが,これはJava言語の設計の古さに関する問題のひとつだと思います。匿名内部クラスというアイデアは完全に失敗でしょう。ただしこの問題は,Java 8では解決されています。

 

InfoQ: JavaのコミュニティがJavaScriptプログラマに対して "フロントエンドをやってればいいんだ" と言っている,という話がありましたが,そういった意味では,Node.js側にも多少の不利な点があるのではないでしょうか。というのも,JavaScriptでプログラムが書ける人はたくさんいますが,Node.jsで開発するようなシステムには,それとは違う概念的バックグラウンドが必要ではないかと思うのです。JavaScriptのような言語が新たにエンタープライズ市場に参入したことによって,エンタープライズシステムの適切な知識を持たない人たちがシステムを設計するようになるのは,リスクがあるのではないでしょうか?

Eberhard: こう考えてみてはどうでしょう – Javaコミュニティは古くからバックエンドシステムに携わってきたので,大規模システムの開発には慣れています。大規模システムの設計に関するアイデアの多くは,Javaコミュニティから生まれました。でも私は,たまたま使用した言語でその開発者を評価しようとは思いません。それに,非同期の概念に関しては – まさにJavaScript開発者の体の一部なのです。大規模システムではモジュール化も重要な課題です。vert.xはここでも,ユニークな代替策を用意しています。適切にモジュール化すれば,大規模システムをより小さな部分に切り分けることができます。それにも増して興味深いのは,そのモジュール化の概念がメッセージを基本としている点です。これにはまた別のメリットがあります。システムが特定のメソッド呼び出しではなく,メッセージにのみ依存することによって,モジュール間の疎結合が実現されるのです。

 

InfoQ: なるほど。それがJSONという,それ自体が非常に "ルーズ" なメッセージ形式を使うことでさらに促進されて,互換性の問題を回避できる,ということですね。

Eberhard: そのとおりです。ただしJSONは技術面での選択肢のひとつであるに過ぎません。JSONにはスキーマ定義に相当するものがないのです。実のところ,フレキシビリティを損なうからスキーマは好ましくない,と言う人もいます。最初にインターフェースを設計して,それらに基づいたシステム開発を行うという,ウォーターフォールモデルになってしまう,というのが彼らの主張です。私自身は,JSONメッセージが期待している構造であることのチェックが可能になりますから,スキーマは有用だと思っています。JSONにスキーマが存在しないのは問題でしょう。一般的に言って,データ構造を定義する何らかの制約は必要なものですから。そういった場合は,XMLスキーマを使うのが適当だと思います。

 

InfoQ: 実は数ヶ月前,動的データ型に関連して面白い経験をしたのです。PhoneGapとNode.js, MongoDBを使ってTwitterクローンをコーディングする,というトレーニングを開催したのですが,その最中にフロントエンド担当者が,彼らの "tweets" にイメージを追加するというアイデアを思い付いたのです。彼らのイメージはノードサーバを通じてデータベースに転送されて,その後フロントエンドに返されるようになっていました。フロントエンドチームがこの機能を見せると,ノードとデータベースを担当するチームはとても驚きました。彼らは自分たちがイメージを処理しているという認識を持っていなかったからです。この時の状況はとてもクールでしたが,逆に大きな問題を含む可能性もあるように思えたのです。

Eberhard: それはまさに,スキーマがフレキシブルであることのメリットと言えますね。ですが2つ以上のチームが開発に関わっていれば,通常は何らかのインターフェース定義が存在するはずです。その定義に従わせる手段として,スキーマのようなものが必要なのです。今の話にはもうひとつ,興味深い部分がありました。データをどこで解釈しているか,という点です。あなたの説明にあったスタックでは,システムの大部分がデータのチェックや検証に関心を払わず,単にJSONドキュメントを保存して終わりとなっています。データのスキーマを解釈する必要がないから,ドキュメントの内部が何であるかは関係ありません。しかしエンタープライズシステムは,そうではいかないでしょう。"お客様" ということになれば,ユーザのデータがどのようなものかは認識しておかなければならないはずですから。

 

InfoQ: 今の話には,JavaScriptのような動的型付けのイデオロギが背景にあるように思います。アヒルのように歩いて,泳いで,鳴くのなら,それはアヒルだ,ということですね。つまり,私が期待しているデータ型のように見えて,必要なデータがすべて揃っているならば,それ以外のことを気にするな,と。

Eberhard: そのとおり。ただし問題があります。 あなたがユーザから取得したオブジェクトに誕生日(date of birth)を入れてほしいのであれば,スキーマにそれを定義することができます。これはXMLスキーマの得意とするところです。XMLスキーマには高度に洗練された型システムがあって,注文番号がどのようなフォーマットなのか,といったことまで,正規表現を使って定義することができるのです。もしスキーマを守らなければ,たちまちトラブルに見舞われることになります。そのデータは無効であると,事前にスキーマから通知されますから,それを初期警告として利用することができます。

 

InfoQ: vert.xのイベントバスで使用されるのは,いつでもJSONなのでしょうか?

Eberhard: いいえ,どのようなオブジェクトでも使用することができます。 ですが,Javaオブジェクトを使う場合には,シリアライゼーションとクラスローディングの問題に突き当たるでしょう。その意味で,このコンテキストではJSONが適切な選択ですから,通常はこれを使用します。

 

InfoQ: Node.jsやvert.xなどのテクノロジに関してですが – 大規模アプリケーションのアーキテクチャはこれらのテクノロジをベースとしていると思われますか,あるいはある特定の領域のアーキテクチャで使用されているものと考えた方がよいのでしょうか?私の知る限りでは,LinkedInではモバイルデバイスのトラフィック処理にNode.jsを使用していますが,アプリケーションそのものは "普通の" エンタープライズアプリケーションだったはずです。

Eberhard: 現時点で言えば,昔からのエンタープライズシステムにこれらのテクノロジが取り入れられるには,まだ少し時間が掛かるだろうと思っています。この点がSpringなどとは違うところです。Springがエンタープライズシステムに適しているのは,最初の頃から明らかでした。明確なマイグレーションパスがあったからです。しかしvert.xでは事情が少し違います。vert.xは他のアプリケーションに組み込むこともできますが,そのパワーを完全に発揮させるには,ランタイム環境で使用する必要があります。この環境は,これまでのエンタープライズJavaとはかなり違っていて,サーブレットもアプリケーションコンテナもなく,ただJavaプロセスがあるだけなのです。ですが一方では,非同期システムへのトレンドが存在しています。ErlangやScala,Akka,Spring Integrationのようなフレームワーク,あるいはApache Camel – それぞれが異なるアプローチで,異なるフォーカスを持っています。Spring IntegrationやApache Camelを例に取れば,さまざまなアダプタを提供し,非同期メッセージやプロセスデータを送信します。要するに "Enterprise Integration Patterns" に示されているような,統合ソリューションを提供しているのです。Erlangのアイデアは高いパフォーマンスと信頼性の実現です。vert.xも同じです。つまり非同期処理はシステム構築の具体的な方法として,ますます重要になってきているのです。

 

InfoQ: この種のテクノロジで避けるべきなのは,どのようなことだと思われますか?どんな部分に落とし穴があるのでしょう?

Eberhard: その質問はつまり,これらのソリューションが特に便利なのはどのようなコンテキストか,ということですね。ハイパフォーマンスシステム,とりわけ膨大なクライアント数を抱えたシステムがスイートスポットだと思います。あるいは統合シナリオや,その他のシナリオでも疎結合のメリットを活かせるかも知れません。別の言い方をすれば,ごくありきたりのWebアプリケーションにとってはベストソリューションではないかも知れない,ということです。

 

InfoQ: 既存のフレームワークをvert.xで使用するには,どうすればよいのでしょう?Webページの配信にはApache Wicketのようなフロントエンドフレームワークを使う,といったように,既存のフレームワークを選択することは可能でしょうか?

Eberhard: 残念ながら簡単ではありません。大部分のフロントエンドフレームワークがServlet APIを使っているからです。Servlet APIはブロッキングAPIなので,vert.xとは相性がよくないのです。ですから,テンプレートエンジンを使ったソリューションを設計して,自身でHTMLページ配信を管理することになります。それよりも,フロントエンド用にJSONとRESTインターフェースを備えたバックエンドシステムを開発する方が,より一般的なユースケースです。最終的にはフロントエンドのロジックが多くなり,バックエンドは少なくなります。必ずしもビジネスロジックではなく,例えばHTMLページをレンダリングするロジックなどです。

 

InfoQ: 先程,本番環境の話が出ましたが,このコンテキストで,クラウドベースのシナリオよりも多く利用されると思いますか?あるいは実質的には大きな差はなくて,運用チームが新しいパラダイムを採用しなければならない,ということなのでしょうか?

Eberhard: "クラウド" という言葉が正確には何をさしているのか,によります。大部分のPaaSクラウドで問題なのは,彼らが単にサーブレットAPIを提供しているだけだ,という点です。そのために,私たちが経験したのと同じ状況に直面することになります。vert.xアプリケーションをIaaSにデプロイするのに何ら問題はありませんが,この領域の別のJavaテクノロジでvert.xを使っても,それほど大きなメリットはないと思います。

 

InfoQ: 開発時のサポートに関して少し聞かせてください。Node.jsを考えているならば,良くも悪くも,JavaScriptをサポートするIDEが見つかります。しかし全般的に言ってJavaScriptの開発環境は,Javaソフトウェア開発時の充実度にははるかに及びません。QA資料に関しても同じように思います。改善はされていますが,それでも大きな進歩には至っていません。vert.xの状況はどうなのでしょうか?

Eberhard: vert.xの優れた点として,ホット・リデプロイ(hot redeploy)機構が利用可能なことがあります。これによって開発は非常に容易になります。さらにはどのようなソースファイルでもvert.xでコンパイル,実行可能,というメリットもあります。ただしEclipseプラグインは用意されていません。

 

InfoQ: それに加えて,その言語のために存在するものはすべて利用することができますね。テストあるいは自動コードなどのインフラの存在が,Javaの利用を決める対象として見直されることはないでしょうか?

Eberhard: そういうことも可能ですね。しかし先ほど述べたように,モジュールとデプロイのコンセプトが違いますから,いくつか課題があります。

 

InfoQ: vert.xのデバッグについてはどうでしょう?実行中のプロセスにアタッチすることはできますか?

Eberhard: もちろん,JVMが提供する機能ですから。実際,JVMを使っていることによるメリットはたくさんあります。ソースコードは,高度に最適化された仮想マシン上で,バイトコードとして実行されます。それに加えて,例えばJavaScript用よりもバイトコード用に最適化されるVMを開発する方が容易ではないか,とも思います。V8チームの開発したものは素晴らしいですし,本当にエキサイティングではありますが,JVMに投資されたエンジニアの数は膨大なものです。それを頼りにしてJVMを使用する方がよい考えではないかと思います。要因が何であれ,Node.jsよりもvert.xが高速であるという測定結果はあります。ただしベンチマークの常として,それをどう解釈するかが難しい部分はありますね。

 

InfoQ: そのとおりですが,納得のいく結果だとは思います。いずれにしても,V8チームが過去数年間で開発した成果は,本当に素晴らしいものです。それに対して,JVMには20年以上にわたる開発の歴史があります。もうひとつ,V8エンジンの高いパフォーマンスが,いくつかのコンセプトに依存していることも触れなくてはいけないでしょう。そのようなコンセプトを知らなくても,文法的に正しいコードを書くことはできます。それはそれでいいのですが,内部的なコンセプトと矛盾していれば,結果はパフォーマンス低下となって現れます。これと同じようなことは,Javaでは起こりえないと思います。間抜けなループ処理のひどいコードを書くことはもちろんありますが,それはまた別の問題ですから。

Eberhard: そうですが,それは比較しているものが適当ではないと思います。本来ならば,スタック全体を比較する必要があるでしょう – vert.xのJavaScriptにはRhinoとJVM,Node.jsにはV8というように。動的言語のサポートは,JVM本来の機能ではありませんから。もうひとつ指摘したいのは,vert.xではイベントループを複数,通常はCPUコアごとにひとつずつ使用できることです。これはV8にはないものだと思います。つまり,もし8コアのサーバがあれば,複数のNodeサーバを起動する必要があります。しかしvert.xならば,8つのイベントループを持つJVMをひとつだけ起動すればよい,という点が違いますし,おそらくはより効率的です。ただし先程も言いましたが,ベンチマークではもっと複雑な問題があります。

 

InfoQ: 最後になりましたので,まとめとして ... vert.xのもっとも大きなメリットは何でしょう?ご自身の考えとしてお聞かせください。

Eberhard: そうですね,vert.xはエキサイティングで意義深いテクノロジだと思っていますが,それにはいくつか理由があります。第1には,今後JVMで問題になるであろう,非同期IOを備えていることです。その次には,エンタープライズJavaに欠けているモジュール化の概念に優れていることがあります。これは,かなりの多くのプロジェクトが抱えていて,しかも適切なソリューションを考え出すのが難しい問題なのです。そして最後に,私はこれも理由のひとつだと思うのですが,多言語VMとしてのJVMが今後ますます重要になるだろう,ということです。Java言語だけがJVMの未来であるとは思えません。vert.xは本当の多言語ですので,そのために役立ちます。課題としては,サーブレットやアプリケーションコンテナをvert.xランタイムに置き換えるのに必要な労力の大きさでしょうね。

 

 

Eberhard Wolff氏はJava Championsの創立メンバである。いくつかの記事や書籍の著者であるとともに,国際会議でも定期的に講演を行っている。エンタープライズJava,Spring,クラウド,NoSQLなどをバックグラウンドとする氏は,ドイツのベルリンにあるadesso AGでアーキテクチャとテクノロジのマネージャを務める。

この記事に星をつける

おすすめ度
スタイル

BT