CassandraとSEDAのアーキテクチャの対応関係
Cassandraで、SEDAのアーキテクチャをどのように実装しているかを調べてみました。SEDA対応部分は、concurrent.utilのお陰でとてもシンプルな実装でわかりやすいですね。
https://svn.apache.org/repos/asf/incubator/cassandra/trunk/
以下、概要です。
SEDA Stageに対応するもの
以下の二つ
- Event queue + Thread Pool
- StageManagerで定義されているThread Pool Executor
- application handler
- MessagingServiceに登録されているVerbHandler
SEDA Resource controller
- SEDA Thread pool controller
- StageManagerにあたる。ただ、動的なリソース管理はしていない。
- Cassandraで定義されているStage (StageManager)
public final static String READ_STAGE = "ROW-READ-STAGE"; public final static String MUTATION_STAGE = "ROW-MUTATION-STAGE"; public final static String STREAM_STAGE = "STREAM-STAGE"; public final static String GOSSIP_STAGE = "GS"; public static final String RESPONSE_STAGE = "RESPONSE-STAGE"; public final static String AE_SERVICE_STAGE = "AE-SERVICE-STAGE"; private static final String LOADBALANCE_STAGE = "LOAD-BALANCER-STAGE";
メッセージ配送処理
メッセージ配送の主要ロジック
MessagingServiceのrecieveメソッドからがメッセージ配送処理の肝。以下が概要。
- MessagingServiceは、Messageのタイプをみて、Stageを取得
- StageをStageManagerから取得して、メッセージ配送タスクに処理を委譲
- メッセージ配送タスクでは、メッセージのverbにしたがって、verbHandlerを取得して、VerbHandlerを実行
- VerbHandler中で処理を実行(doVerb)して、MessagingServiceでメッセージ配送(sendOneWayで)
メッセージ送信部分
こちらもMessagingServiceで。
- sendRRでmessage送信するときに、taskCompletion_に突っ込んでおいて、sendOnewayでメッセージを非同期送信。
- Futureパターンで、getAsyncResultメソッドでメッセージ受け取り。TcpConnectionのpoolからTcpConnectionを取得して、データ送信。
所感
SEDA対応部分の実装は、java.util.concurrentのパワーのお陰でとてもシンプルな実装でわかりやすいなと。
他に思ったのは、APIサーバーは、SEDAモデルと相性がいいかもなぁと。Stageが1個だけでいいケースも割と多そうなので、ステージを分割する意味がでるケースがどれだけあるかは少し微妙かもしれないけど。ただ、SEDAのアーキテクチャ的には、1個のステージでもいいわけで、汎用のAPIサーバーを作りたければ、SEDAのアーキテクチャは面白いかもなぁと思いました。
cassandraの実装を見て、concurrent.utilとNIO系のフレームワークを組み合わせて、SEDAのアーキテクチャをベースにして、APIサーバーを作れば、割と現実的なものができそうだなぁと思ったのでした。コード的にはさほど量を書かなくても書けそうです。
# SEDA部分意外も実装として面白そうなので、読みすすめようかなと思ってます。