2009年5月18日月曜日

SWE622ふりかえり

この春セメスターを多忙にしていた主原因の一つがこのコース、SWE622です。振り返ってみると、主に以下の3つの理由により、このコースはとてもきつかったです。
  1. このコースのトピック「分散コンピューティング」がただでさえ難しい
  2. 量の多いReading Assignmentが毎週出た
  3. グループプロジェクトの課題も大変だった
期末試験も難しい上に量が多く、ほとんどの学生はテスト時間いっぱいまで教室にいたので、私を含めみんな全問回答はできてなかったのではないかと思います。ただ、先週成績が発表され、幸い「A」をいただくことができ、ほっとしています。やはり先生も全問回答することは期待していなかったようです。

このコースで学んだ内容
このコースのタイトルは「Distributed Software Engineering」ということで、分散コンピューティングについて学びました。個人的に、コンピュータサイエンスという分野の中で、分散コンピューティングはもっとも難しい内容の一つではないかと思います。
このコースでは、タネンバウム教授著の教科書「Distributed Systems: Principles and Paradigms 2nd Edition」におおむね沿って進められました。その中で、やはり「同期」は難しい問題だと思います。「同期」と一言で言っても、排他制御だけでなく、複数ノード間での時計の管理や、複製されたデータの一貫性管理など、分散コンピューティングならではの悩ましい問題も含みます。グループプロジェクトでも、これらのうち排他制御と時計(時間)管理について取り組みました。

とても多いReading Assignment
このコースの一番嫌だったのは、毎週出たReading Assignment。量が多かったので、毎週金曜日はほとんどこの宿題のためだけに費やしていたような気がします。大体記述式の問題に答える必要があったので、ほとんど英語の勉強をしているような感覚でした。
大変だけど楽しかったグループプロジェクト
上記のようにReading Assignmentは嫌でしたが、一方でグループプロジェクトは楽しむことができました。というのも、動くものを作るプログラミングだったからです。私の所属したグループには私以外に、アメリカ人一人、インド人一人、中国人一人の、合計4人でとても国際色豊かなグループでした。

プロジェクトの課題はざっくり要点をまとめると(実際の課題内容はここ
  • 「Trader」と「Exchange」という2種類のプログラムで構成された分散アプリケーションをJavaで実装
  • 複数のTraderと複数のExchangeが複数のコンピュータに配置されn対mの関係で相互作用する
  • 複数のTraderは複数のExchangeに対し、前もって「登録」を行う
  • Traderは登録したExchangeに対しメッセージを送信することにより、「買い注文」または「売り注文」を行うことができる
  • 注文を受けたExchangeは、登録された全Trader群に対しその注文をエコー送信する
  • Exchange間でメッセージ送受信は必要ない
  • Exchangeは、登録された全Trader群について、注文が行われた「順番」を正しく管理しなければならない
  • TraderおよびExchangeが配置されている複数のコンピュータの時計が完全に同期していると仮定してはならない
  • コンピュータがダウンしても、残りのコンピュータで分散アプリケーションは稼動し続けなければならない
  • メッセージ送受信には、Java RMI、Socket、Web Service等の通信手段を用いる。上記要件に基づきメッセージの種類に応じて望ましい通信手段を選択することが望ましい
どうやってイベント発生順序を管理する?
上記のうち、課題を難しくしているのはやはり「注文が行われた「順番」を正しく管理しなければならない」というところです。コンピュータ間で時計が同期していると仮定できないので、コンピュータAがメッセージを送信したタイミングと、異なるコンピュータBがメッセージを送信したタイミングのどちらが先だったのか、何らかの方法で知る必要があります。一つの方法は、Berkley Algorithm等のクロック同期アルゴリズムを使ってコンピュータ間の時計を合わせることが考えられます。
もう一つの方法は、コンピュータ間の時差を計算しておいて、メッセージが送信されたタイムスタンプに対しその時差を織り込む、という方法があります。私達のグループは後者の方法を採用しました。結果的にどのグループも同じ方法を採用していました。コンピュータ間の時差の計算方法は、NTPでも採用されているものです。以下の図において、T1およびT4はComputer A上の時計の時刻、T2およびT3はComputer B上の時計の時刻です。このとき、Computer AからBにメッセージを送信した際のNetwork Latencyと、BからAにメッセージを送信した際のNetwork Latencyが同じだと仮定すると、そのLatencyは(T4-T1 + T2 -T3)/2で計算できます。この値を使うことで時差を計算することができます。
ただし、大規模ネットワークにおけるルーター等の存在を考えると、上記仮定は必ずしも成り立たない上に、各コンピュータのクロックデバイスはそれぞれ特性があるために時差は徐々に変わっていきます。したがって、この時差の計算は何らかの周期でやり直す必要があります。

設計
他のグループと比較し、私達のグループのもっともユニークだった点は、Java RMIとSocketの2種類の通信手段を両方サポートし、比較評価を行ったことです。他のグループはいずれもRMIまたはSocketのいずれか一方のみを使って実装していました。以下が私達のグループの設計(イメージ図)です。
上記のように、ミドルウェアがアプリケーションに対し2種類の通信手段の詳細を隠蔽します。ミドルウェアとアプリケーションとの間にはキューがあるため、アプリケーションにとってメッセージ送受信は全て非同期に行われることになります。

このプロジェクトで私はミドルウェアを全て実装しました。上記のようにミドルウェアは多くのスレッドが相互作用する難しい実装でしたが、とても楽しかったです。このミドルウェアがちゃんと動作しないと、アプリケーション開発に支障が出るので、かなり早い時期に実装を完了するよう努力しました。おかげで、とても安定したミドルウェアを実装することができ満足しています。

0 件のコメント: