並行分散ソフトウェア/並列分散ソフトウェア 電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.cs.tsukuba.ac.jp/~yas/sie/pdsoft-2005/2006-02-17
あるいは、次のページから手繰っていくこともできます。
http://www.cs.tsukuba.ac.jp/~yas/sie/
http://www.cs.tsukuba.ac.jp/~yas/
参考文献
Marko Boger: Java in Distributed Systems: Concurrency, Distribution and Persistence, John Wiley & Sons, 2001. ISBN: 0471498386
http://www.dpunkt.de/buch/3-932588-32-0.html (ドイツ語) jivs code
1999年に、サン・マイクロシステムズ社のビル・ジョイらによって開発され発 表された。
Jini の目標は、ネットワークで Plug & Play を実現すること。 機器をネットワークに接続しただけで、特別な設定 をしなくてもすぐに利用可能になること。
目標
JavaSpaces は、内部的に Jini のルックアップ・サービスの実現で使われて いる。JavaSpaces も、Jini でアクセス可能なサービスの1つと考えることも できる。
Microsoft の、Jini に対抗した技術。
サービスの登録と検索
ルックアップ・サービス自身も、最初から知られている必要はない。 ネットワーク上で自動的に探される。 Discovery と Join。
Java のオブジェクトが Lease。
リース期間は、延長することができる。 延長されなかった lease は、ルックアップ・サービスから削除される。 登録されているサービスを明示的に削除する仕組みは、存在しない。
サービスが削除された時には、分散型イベント配送サービスにより関係してい る所に知らされる。
トランザクションのインタフェースは定められているが、具体的な実現は各サー ビスにまかされている。
サービスの提供者とサービスの利用者の間は、最終的にはに RMI で接続される。
ServiceIDLister インタフェースを implements する。
package com.sun.jini.lookup; public interface ServiceIDListener extends java.util.EventListener { void serviceIDNotify(net.jini.core.lookup.ServiceID serviceID); }ルックアップ・サービスからコールバックされる。
Discovery の実現方法
図1 マルチキャストによる Discovery
図2 Join
RemoteBall.java Ball.java
グループは、名前(文字列)で区別される。
Jini パッケージは、JoinManager という参照クラスを含む。
public JoinManager(Object obj, Entry[] attrSets, ServiceIDListener callback, LeaseRenewalManager leaseMgr) throws IOException public JoinManager(Object obj, Entry[] attrSets, String[] groups, LookupLocator[] locators, ServiceIDListener callback, LeaseRenewalManager leaseMgr ) throws IOException
BallStarter.java
図3 Lookup
サービスは、次の3つで区別される。public ServiceTemplate(ServiceID serviceID, Class[] serviceTypes, Entry[] attrSetTemplates)サービス(オブジェクト)の探し方
Bat.java
信頼性が低いネットワークと、どう戦う方法の1つ。
lease には、期限がある。
期限の長さは、交渉可能。 期限が短い(1分以下、数秒)というのは、あまり想定されていない。
リースの利点
Jini のサービスを提供しているオブジェクトは、Lease インタフェースを実 装している。
public interface Lease { long FOREVER = Long.MAX_VALUE; ... long getExpiration(); void renew(long duration) throws LeaseDeniedException, UnknownLeaseException, RemoteException; void cancel() throws UnknownLeaseException, RemoteException; ... }getExpiration() で、リースの残り時間がわかる。ミリ秒単位。
renew() で延長する。 延長できない時には、LeaseDeniedException が返される。
もう使わなくなった時には、cancel() できる。 期限切れと同じことになる。
リースの管理には、LeaseRenewalManager を使う。
プログラミング言語は、ネットワークの存在や通信をさまざまな度合いで隠し ている。
問題:
ネットワークの機能はある。
利用者は、常にどの計算機を使っているのかを意識する必要がある。
コマンド
分散型オペレーティング・システム
利用者は、仮想的な1台の計算機を使っているように感じ、計算機と計算機の 境界線が見えなくなる。分散透明性(network transparency)が実現されてい る。
目標
注意: 負荷分散の分散(load sharing/balancing)とこの講義のタイトルの分散 (distributed)は意味が違う。
一般的な特徴
Emerald の目標。
メソッド呼出しの引数も参照で渡される。オブジェクトの場所が違うと、重た い。コピーの方が速い。
Call by reference が重たい。
A note on Distributed Computing [Waldo 1994]
例:
分散の難しい問題は、まだ汎用的に解ける技術はない。 汎用性がないと、プログラミング言語には採り入れにくい。
IMobility mobileObj = Momility.of(obj); mobileObj.moveTo("url");非同期メソッド呼出しがある。
IA a1 = (IA) Factory.create("A","//sun:8000"); a1.method(param1,param2); // 同期 Result r1 = Future.invoke(object, "method", // 非同期 new Object [] {param1,param2}); if( result.isAvailable() ) { int x = r1.readInt(); }メソッド名を文字列で渡す。結果として、Result 型を返す。isAvailable() メソッドで終了を待つ。readInt(), readByte(), readObject() で、int, byte, オブジェクトに戻す。
Voyager Space を使ってマルチキャストができる。
ISubspace subspace = (ISubspace) Namespace.lookup("//sun:9000/Subspace"); A a1 = new A(); subspace.add(a1); a1.method1( param1, param2 ); Object [] params = new Object [] { param1, param2 }; Multicast.invoke(subspace,"method1",params,"A");
DjProcessor p1 = new DjProcessor("sun:8000"); DjHello hello = new DjHello(p1); hello.moveTo("mac:9000");
DjProcessor p1 = new DjProcessor("hostname:port");これにより、ホスト
hostname
上の
ポート番号 port
で新たな
仮想プロセッサが作られる。
ホスト hostname
では、事前に
Voyager デーモンを走らせておく必要がある。
class A
(.dj) から、自動的に
スタブ(プロキシ)となる
class DjA
が生成される。
コンストラクタの引数が1個多い。
DjA a1 = new DjA( Aの引数・・・, DjProcessor );これで、遠隔の仮想プロセッサでオブジェクトが生成され、 遠隔参照(remote reference)が返される。 通常の参照と同じになるように頑張っているが、 一部違う。
DjA a2 ; a2 = ... ; ... if( a2 == a1 ) // 遠隔のオブジェクトではなくてローカルのスタブの比較 { ... }equals() メソッドは、遠隔でも働く。
ローカル・オブジェクトを引数にして、 リモート・オブジェクトを呼ぶと、自動的に遠隔にコピーが渡される。 (遠隔オブジェクトが作られて、遠隔参照が渡されるのではない。)
DjX
型のオブジェクトを
遠隔にリターンすることはできる。
DjX
がみつからなければ、
X
のコピーが返される。
remote.getCopy() で、ローカルのコピーが得られる。
DjA a1 = new DjA(p1); A a2 = a1.getCopy();3つのメソッド呼出しのセマンティクスがある。
DjA a1 = new DjA(p1); B b1 = a.method1( 10 ); // 同期 B b2 = a.method1( 10, Dejey.ASYNC ); // 非同期 a.method1( 10, Dejay.ONEWAY ); // 一方向非同期には、完了待ちの方法が2種類ある
B b1 = a.method1( 10, Dejey.ASYNC ); b1.method2(); // wait by nesessity B b2 = a.method1( 10, Dejey.ASYNC ); if( b2.isAvailable() ) { b2.method2(); } else { // do something b2.waitForResult(); b2.method2(); }
2レベルの名前。
DjProcessor p1 = new DjProcessor("lin:8000"); p1.registerByName("p1"); DjA a1 = new DjA(p1); a1.registerByName("a1");
DjProcessor p1 = Dejay.getProcessorByName("p1"); DjA a1 = p1.getObjectByName("a1");
DjProcessor p1 = new DjProcessor("PersistProc","ProcesssorDB","lin:8000"); DjA a1 = new DjA(); if( p1.isPersistable ) { p1.persist(); p1.flush(); }persist() を呼ぶと、データベースに保存される。 flush() を呼ぶと、メモリが GC で回収可能になる。
persist() でデータベースに保存されたオブジェクトも、 使われる自動的にデータベースから回復される。
仮想プロセッサ全体がデータベースに保存できる。 次のようにして回復できる。
DjProcessor p1 = Dejay.getProcessorFromDB("PersistProc", "ProcesssorDB","lin:8000");