ひがやすを技術ブログ

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

Slim3 Preview release

Slim3の正式リリースは、来年の一月くらいになりそうですが、ドキュメントも最低限のものはそろったので、今の段階のものをPreview版として紹介しておきます。


サイトへは、http://slim3.org でアクセスしてください。
Getting Startedをやり、Slim3 Datastoreのドキュメントを読み、Online demoをみれば、Slim3のことは把握できるようになっています。
Oneline demoからソースも見れるようになっているので、動かしながらソースを確認することができます。Online demoは、IE6で見るとレイアウトが崩れていますが、これはIE6を使うなというメッセージということで。(IE7,8では未確認)


Slim3は、Google App Engineに対して最適化されています。
例えば、最近、App Engineで問題になっているのは、spin upの時間です。spin upというのは、アプリケーションを起動することです。これまでの常識だと、アプリケーションの起動時に多少時間をかけてもリクエストの処理が早くなるなら、そっちのほうが優先されてきました。
しかし、App Engineでは、負荷の状況にもよりますが、2,3分アクセスがないと直ぐにアプリケーションがspin downされ、次のアクセスでspin upされてしまいます。spin up(アプリケーションの起動)に時間がかかるフレームワークは、App Engineには向いていません。
また、起動に時間がかかるとかなりCPU時間を消費するので、貴重なリソースを消費(課金にもつながる)してしまい踏んだりけったりです。


cronで1,2分ごとにアクセスすることである程度、spin downは防げますが、無駄にCPUを消費するし、無理やり感がありますよね。spin upに時間がかからないことがApp Engineでは重要なのです。
Slim3は、そのことを知っているので、spin upの時にはほとんど何もしません。
spin upの点で、AppEngineに向いていない代表は、Springです。起動に時間がかかるからね。AppEngine MLに寄せられているspin upの問題のほとんどは、Springに関するものです。Spring3のJavaConfig使えば、ある程度改善されるかもしれないけど。


spin upは30秒以内に終わらないければ、500 Internal Server Errorです。また、spin up中に次のリクエストがくるとQueueに積まれますが、Queueに積まれて10秒以内に処理されないと、これも500 Internal Server Errorです。spin upを短くすることは、AppEngineで動かすには最重要課題です。


AppEngineのデータアクセスには、JDO/JPAを使うのが一般的ですが、PersistenceManagerFactory/EntityManagerFactoryの初期化がまた遅いんですよ。状況によると思いますが、3秒以上かかる。
spin upの時にデータにアクセスすることも多いので、かぶると最悪です。
JDO/JPAは使うことが推奨されているにもかかわらず、AppEngineには向いていません。では、どうすればいいかというと、Datastore Low level APIを使うことです。Slim3は、Low level APIを直接使って(JDO/JPAを使わず)、Bigtableにアクセスしています。


AppEngineへの最適化以外に、Slim3は次の三つの特徴があります。

  • TDD support
  • HOT reloading
  • Type-safe query


Slim3では、Controller, Model, Serviceを作るときに、そのTestCaseも同時に作成します。また、Bigtableにアクセスする場合でも、AppEngineの方でそれをエミュレートする機能があるので、それを使い、モック無しで普通にテストできます。
DIの主なメリットは、テストのしやすさと宣言的トランザクションだと思いますが、AppEngineではモックなしで簡単にテストができ、Bigtableの仕様的に宣言的トランザクションはほとんど使えないので、AppEngineでDIを使うメリットは余りないんじゃないかと思います。単に複雑になるだけ。
これが、Slim3でDIをはずした理由です。


HOT reloadingは、Seasar2のHOT deployと同じです。Containerを使ってないので、余分なオーバーヘッドがなくSeasar2より高速に動作します。


Type-safe queryはBigtableに対して、S2JDBCのようにアクセスできることだと思ってください。こんな感じ。


EmployeeMeta e = new EmployeeMeta();
List list = Datastore.query(e)
.filter(e.job.equal("ANALYST"), e.salary.greaterThan(5000))
.sort(e.name.asc)
.asList();

JDOだとこんな感じ。


PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = pm.newQuery(Employee.class);
query.setFilter("job == \"ANALYST\") && salary > 5000");
query.setOrdering("name asc");
List list = (List) query.execute();
query.closeAll();
pm.close();

また、Slim3は、JDOよりも高速に動作します。例えば、10000件のフェッチだと3倍以上高速に動作します。
Online demoで実際に確かめると実感しやすいでしょう。


Slim3は、パフォーマンス的には、たぶんGAE/Jの中では最速。なぜかというと、Servlet層は、かなり薄いラッパーなのでオーバーヘッドがほとんどない。Datastore層に関しては、EntityとModelのmappingをランタイム時にリフレクションを使うのではなく、コンパイル時に直接ソースコードに書き出しているので、余分なオーバーヘッドがほとんどないから。
詳しくは、http://sites.google.com/site/slim3appengine/slim3-datastore/defining-data-classes/meta-data-of-model
これ以上速くする方法が、私的に思いつかないだけで、きっと誰かがより高速な方法を思いつくと思いますが。
高速化で直ぐに思いつくのはmemcacheを使うことですが、memcacheによるキャッシュは、フレームワークに組み込むよりもアプリケーション側でコントロールしたほうがわかりやすいと思っています。


Slim3の公式ドキュメントとしては英語のみとなりますが、日本語の情報としては、gluegentさんのSong of Cloudに取り上げられたりしているので、定期的にチェックしてみるといいのではないでしょうか。AppEngineのつっこんだ情報が満載です。
http://songofcloud.gluegent.com/2009/11/slim3-datastore1.html
http://songofcloud.gluegent.com/2009/11/slim3-datastore2.html
http://songofcloud.gluegent.com/2009/11/slim3-datastore3.html


なにかわからないことがあれば、twitterに #slim3 か #appengine をtagとして書き込めば誰かが反応してくれるんじゃないかと思います。Slim3固有のことは#slim3、Slim3かAppEngineか迷ったときは#appengine。140字を超える場合は、http://groups.google.co.jp/group/slim3-user-japan へ。