スウェーデン北部にあるアッカ山、
Akkaというフレームワーク名はこれに由来する。
本日、Akkaチームは、Java仮想マシン用のアクターフレームワークAkkaのversion 0.7をリリースした。
Jonas Bonér氏を中心とするAkkaチームは、これからの並行性の課題を解決するにあたって、JVMにおける現在の共有状態とロックによるアプローチではなく、メッセージベースのアクター、ソフトウェアトランザクションメモリ、適切なフォールト処理戦略によるソリューションを使うという判断を下した。
Akkaのソースはgithubから入手することができる。これはオープンソースであり、Apache 2.0 Licenseで利用可能だ。
Akkaの背景にある意図、現状と採用状況、今後の計画について、Jonas Bonér氏に話を聞いた。以降のセクションでは、彼の回答について紹介する。
並行性の課題に対するスケーラブルなソリューション
Q: Akkaはどんな問題を解決してくれるのですか?
私の経験から言って、並行性があってスケーラブルでフォールトトレラントなアプリケーションを正しく書くのはあまりにも難しいです。その原因のほとんどは、間違ったツールや間違った抽象化レベルを使っていることにあります。Akkaはこうした状況を変え、JVMで並行性のあるスケーラブルで高い可用性をもったソフトウェアを簡単に書けるようにするものです。
Q: Akkaのコンポーネントやアーキテクチャについて、もう少し紹介してもらえませんか?
抽象化レベルを上げるために、AkkaではアクターモデルをSTM(ソフトウェアトランザクションメモリ)とともに使っています。これにより、並行性のあるスケーラブルなアプリケーションを正しく構築するためのすぐれたプラットフォームを提供します。フォールトトレランスについては、"Let it crash" モデルを採用しています。このモデルは通信業界で使われてきたもので、自己回復するアプリケーションや決して停止しないシステムを構築するのに大成功を収めています。また、Akkaはリモートアクター(Remote Actors)とクラスタサポートを備えてます。これらは透過的な分散機構を提供し、真にスケーラブルでフォールトトレラントなアプリケーションのための基盤となります。
Akkaのアプローチは、もともとCarl Hewitt氏が1973年に提案したアクターパラダイムの再実装だ。このパラダイムは、Erlangのような言語や非常に高い可用性をもった高度にスケーラブルなシステムが一般的である通信業界において使われ、成功を収めている。
アクターアプローチでは、一方向の(fire & forget)イミュータブル(immutable)なメッセージを別のアクターに送るだけで、状態を全く共有しない。アクターをスレッドとして表現する必要はなく、非常に軽量(1アクターにつき約600バイト)なので、数百万ものアクターを普通のマシン1台で動かすことができる。
アクター内のエラー処理はスケールせず、大局的に解決することもできない。これは、アクターは障害が発生すると死ぬものとされており、生き残ったアクターがリンクされたアクター群のフォールト処理の責任を負うためだ。生き残ったアクターは障害が発生したアクターやそのグループ全体を再起動することができる。
APIとその使い方
Q: 開発者にとって、Akkaはどんな用途に使えるのでしょうか?
Akkaはいろいろな用途にいろいろな方法で使えます。例えば、デプロイメントに関して、AkkaをJARライブラリとして使って、あなたのWebアプリケーションのWEB_INF/libに置くことができます。あるいは、スタンドアローンのマイクロカーネルとして使って、複数のアドオンモジュール(REST、Comet、Servlets、Persistenceなど)とともに動かすこともできます。
現在のところ、アクターの生成やメッセージの送受信のための簡単なScala APIが用意されている。Scalaのcaseクラスをメッセージタイプとして使えるため、イミュータブル性が保証され、簡単にパターンマッチすることができる。
アクターを使った簡単な例を以下に示す。
case class Message(message: String) class MyActor extends Actor { def receive = { case Message(s) => println("received message "+s) case _ => println("received unknown message") } } val myActor = new MyActor myActor.start myActor ! Message("test")
アクターは様々なライフサイクル手法をとることができる。管理のために、アクターのリンク付け、Throwable動作をするよう宣言、異なる再起動戦略をもったフォールトハンドラの提供がサポートされている。
また、Akkaを使ってスケーラブルなチャットサーバーを実装した詳細な例もある。
Javaインテグレーション
Javaとのインテグレーションは"アクティブオブジェクト(Active Objects)"アプローチにより提供されている。これはAspectWerkz経由でAOPを利用することで、通常のPOJOをアクターモデルの動作を備えた非同期ノンブロッキングのアクティブオブジェクトに変換する。
MyPOJO pojo = ActiveObject.newInstance(MyPOJO.class, 1000);
非voidメソッドは、メッセージを非同期に送信し、Futureを使って応答を待つことにより、"send-and-receive-eventually"という動作に変換される。パラメータのイミュータブル性については送信側が保証する必要がある。さもないと、アクターモデルの動作を壊してしまうためだ。そこで、プリミティブではなくイミュータブルという注釈もないパラメータをすべてディープコピーするという設定項目も用意されている。
インテグレーションモジュール
Q: Akkaは他のインフラストラクチャ、ライブラリ、ツールとどのようにインテグレーションできるのですか?
AkkaにはすばらしいAMQPインテグレーション、RESTfulアクターのためのJAX-RSインテグレーション、Cometインテグレーションがあります。でも、私から見て、最も強力で役に立つインテグレーションは、Martin Krasserが作った新しいApache Camelインテグレーションです。これを使うと、AkkaはApache Camelがサポートするものすべてとシームレスに、ほとんどコードを書くことなく、インテグレーションできます。
Akkaはそのモジュラーアーキテクチャにより、様々なテクノロジーとのインテグレーションを提供している。Microkernelモジュールは、ランタイムオペレーションを提供する。Persistenceモジュールは、Redis、MongoDB、Cassandraによる高速で信頼性のあるストレージを提供する。他にも、Camel、REST、AMQP、Comet、Spring、Servlet、Guice、Liftといったモジュールがそれぞれのインテグレーションを担当する。
現在のリリースと開発
Q: このプロジェクトの将来についてですが、どんな計画がありますか?
短期的には、Scala 2.8対応、クラスタメンバーシップのためのもっとリッチなAPI、そして、OSGiのサポートですね。長期的には、分散STM、JTA/XA サポート、さらなるPersistenceバックエンド(現在のところ、Cassandra、Redis、MongoDBのみ)をサポートすることです。また、現在、Akkaを中心としたビジネスのスタートアップを進めているところです。まもなく、各種サポートパッケージと管理/監視、プロビジョニングといった商用アドオン機能を提供する予定です。
1月に0.6がリリースされて以降、この0.7リリースには非常に興味深い機能がいくつか追加されている。
- Apache Camelインテグレーション
- サーバーマネージド・リモートアクター
- Futureを返す!!!関数
- Clojureスタイルのエージェント
- Shoalクラスタバックエンド
- Redisベースのトランザクションキュー・ストレージバックエンド
- 分散Comet
- Springインテグレーション
Q: これまでどんなフィードバックがありましたか? 現時点では、どんな人がAkkaを使っているのでしょうか?
Akkaが役に立つユースケースは幅広いです。ゲーム、賭け、ソーシャルネットワーキング、データマイニング/エキスパートシステム、財務管理など、さまざまな業界の企業で使われています。Akkaを使ったシステムを製品化していたり、まもなく製品化する会社もあります。とてもエキサイティングな時期ですよ。
Akkaフレームワークを提供するとともに、私たちの質問に答えてくれたJonas氏に感謝する。