ひがやすを技術ブログ

電通国際情報サービスのプログラマ

App Engineではどの言語を使えばいいのか

App Engineで使える言語は基本的にはPythonJavaです。それでは、どちらを選ぶのが良いのでしょうか。
それ以外の言語の人向けの話は後から出てくるのでしばらくこのままお読みください。


趣味ならば単に好きなものを選ぶだけでいいのですが、仕事で使うためには、長所と短所をきちんと把握した上で選ぶ必要があります。また、ここでの話は言語としての一般的な話ではなくApp Engineで使うとき限定の話としてお読みください。


まず安定度ですが、インフラ部分の安定度は、どちらも基本的に同じです。もしかすると、まったく同じものを使っているのかもしれません。
その上で動くAPIの部分は、インフラと直接結びついている低レベルな部分と低レベルなAPIの上に構築された高レベルな部分とに分けて考える必要があります。


低レベルなAPIはLLAPIと呼ばれたりしますが、安定度は、PythonJavaも同じです。API自身も非常によく似ています。言語の違いをあまり感じさせないくらいです。
高レベルなAPIはデータベースに接続する部分だとJavaならJDO/JPAPythonだとdbモジュールだとかがあります。実は、この部分からJavaPythonの運命がわかれてきます。Pythonの方は安定していますが、Javaの方は、まだまだバグがあったり仕様が変わったりすることがあるのです。ただ、最初の頃に比べるとかなり改善されていて、今では頻繁にバグに遭遇することはありません。安心して使えるかというとそうでもないけど。
Javaの方がPythonより安定していないようなイメージがあるのは、この辺に原因があるのかもしれません。


Javaを使いたいあなた、心配することはありません。Slim3を使えばいいのです。Slim3は、安定しているLLAPIの上に構築されている薄いラッパーなので、あまりバグが入り込む隙間がありません。1.0.0もリリースされたし、安心して使うことができます。Javaで開発する場合もSlim3を使えば安定した開発が可能なのです。


次はパフォーマンスについてです。パフォーマンスはspin-up(アプリケーションの起動)とリクエストの処理の二つに分けてみていきます。


spin-upの速度はAppEngineにおいて、非常に重要なものです。
これまでのスタイルでは、アプリケーションの起動時に出来る限りの最適化を行っておき、リクエストの処理を短くすることが重要でした。アプリケーションの起動はどうせ一回しかやらないのだから、その速度はあまり重要ではなかったのです。
しかし、AppEngineでは、2,3分アクセスがないと直ぐにインスタンスがspin-down(終了)され、次にリクエストがあったときに、spin-upが起きるので、spin-upはとても頻繁におきます。また、リクエストが集中してscale outが必要なときにもspin-upがおきます。
spin-upの速度はAppEngineにおいて、非常に重要なものなのです。大事なことなのでなんどもいいますよ。


とても単純なアプリケーションで比較するとPythonのspin-upは100ms以下。Javaは1000ms以下。大雑把にいってPythonの方が10倍速いと言えるでしょう。
これは、単純なアプリケーションでの場合ですが、Springのような重量級のフレームワークを使うとspin-upが20000msを超えることもざらです。桁を間違って書いているわけではありません。念のため。DIContainerの中では軽いといわれているGuiceでも7000msから8000msくらいかかったりするのでAppEngineでDIContainerを使うのはあまり現実的ではありません。


もともとDIContainerが普及したのは、テストをしやすくするためとAOPを使った宣言的トランザクションなどが使えるためですが、AppEngineではテストをするためのフレームワークが整備されていてDIContainerなしでもテストが簡単に行えますし、AppEngineでは基本的にGlobalTransactionが使えずごく限定された範囲でしかトランザクションが使えないので、宣言的トランザクションも役に立ちません。


つまり、AppEngineでは、DIContainerを使うメリットがあまりなく、デメリットが非常に大きいので、DIContainerを使うべきではありません。
もっというと、機能の豊富なフレームワークは、spin-upが遅く、AppEngineの制限から豊富な機能が使えなかったりするので、AppEngineには向かないと言えます。


JDO/JPAもspin-upに4000msから5000msくらいかかるので、はっきりいってAppEngineに向いていません。標準で用意されているフレームワークがAppEngineに向いていないというのは、ちょっとどうかなと思いますが。


AppEngineでとりあえず動作するということと、実用的につかえるということはまるで違います。自分たちがこれまで使ってきたフレームワークをAppEngineで試してみて、spin-upの遅さにがっかりしたという開発者は、世界中にいっぱいいます(MLやtwitterでよく見る)。
この辺が、AppEngine for Javaが遅いと思われている原因なのかもしれません。


Javaを使いたいあなた、心配することはありません。Slim3を使えばいいのです。Slim3はAppEngineに最適化されているのでspin-upも1100msくらいです。超単純なServletより若干(200msから400ms)オーバーヘッドがあるくらいなので、安心して使うことができます。


リクエストの処理は、単純なRequest Handlerの場合、Javaの方がPythonより10倍速いという結果があります。ただ、実際は、Bigtableへのアクセスなどを含むので10倍の差は開かないでしょう。


リクエスト時に動く、データアクセスの処理もJDO/JPAはもっさりしていて遅いです。Slim3の方が圧倒的に速いので、ぜひ次のデモを自分で試して実感してください。
http://slim3demo.appspot.com/performance/


これまでの話をまとめると、AppEngineで開発する場合、Pythonと比べてJavaは、安定度に難があり、spin-upの速度やデータアクセスの速度に問題を抱えています。これらの問題を解決するには、Slim3を使うのが良いということです。
もちろん、Java使いでSlim3を使わずに開発している人もいると思いますが、その人達は、上記にあげた問題を抱えているはずです。


さて肝心な、どの言語を選んだ方がいいかですが、Pythonの出来がいいので、LLな人はPythonを使うのがおすすめです。これまでPHPRubyを使ってきた方も仕事で使うなら、Pythonを使った方が固いです。
JVM(Java)経由でRuby(JRuby)やPHP(Quercus)を使う手もありますが、Javaのオーバーヘッドに加えてさらにScriptEngineのオーバーヘッドが加わるので速度的には期待できません。
ただ、JRubyは頑張ってチューニングしていて、最新版だとSinatraで8000ms位でspin-upするようなので、なんとか使えるかもしれません。Sinatraでも厳しいくらいなので、AppEngineでRailsを仕事で使うのは、今のところ現実的ではないでしょう。


Pythonを使う上での注意点は、Djangoのような高機能なフレームワークを使うとPythonでも重くなってしまうということです。KayのようなAppEnginejに最適化されているフレームワークを使うのがおすすめです。
http://code.google.com/p/kay-framework/


Java使いの方は、Slim3を使うのがオススメ。もちろん、Slim3が好みに合わない人も沢山いると思いますが、使わない場合は、上記で上げたような問題を自前で解決する必要があります。