分散システム 電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/dsys-1997/1998-02-10
/physical-clock.html
あるいは、次のページから手繰っていくこともできます。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/
http://www.hlla.is.tsukuba.ac.jp/~yas/index-j.html
けっこうふらつく。
カウンタは、いいものが作れる。
国際原子時(International Atomic Time): 1958年1月1日0:00:00からのセシウム133の振動数で定義。 世界各地の振動数の観測を、BIH (Bereau International de 1'Heure) 平均し て、91億9263万1770で割る。
平均太陽日よりも3ミリ秒少ない。
12月31日23:59:59の後に12月31日23:59:60を入れる。
GMT (Greenwich Mean Time) は、もう古い。
今までに30秒以上入っている。 最近入ったのは、 1997/07/01 08:59:60
#include YHM_Escape(tv_sec は、1970年1月1日 0:00:00 からの経過時刻。閏秒に関しては、未定義。) struct timeval { long tv_sec; /* seconds */ long tv_usec; /* and microseconds */ }; main() { struct timeval t ; struct timezone tz ; gettimeofday( &t, &tz ); }
設定は、settimeofday()
。
int adjtime(struct timeval *delta, struct timeval *olddelta);時計の進み方を調整する。
図 NTP で使う offset と delay
offset[i] = (t[i-1]+t[i-2])/2 - (t[i1]-[ti+3])/2この時刻差が0になるように adjtime() で調整する。
参考:RFC1305 Network Time Protocol (Version 3) Specification, Implementation and Analysis
通常の方法:メッセージに固有の識別子を付ける。 サーバは、メッセージの識別子をすべて保存する(history)。 再転送の時に、重複が検出できる。 (ニュース・システムと類似)。
問題点
解決方法:メッセージにタイムスタンプを持たせる。
コネクションごとに、最も新しいメッセージのタイムスタンプを記録する。 記録しているものより古い時には、重複として捨てる。
history を expire するために、次の式を計算する。
G = CurrentTime - MaxLifetime - MaxClockSkewG より古いものは、捨てる。
ファイルを書き込む時に、古いキャッシュを無効化するのがたいへん。
クライアントがファイルを要求すると、そのコピーがどれだけの時間有効かを 規定するリース期間(lease)が与える。
リース期間が切れても、まだ必要ならば、クライアントは、サーバに最新のも のかどうかを問い合わせる。
書き込みが起きると、リース期間の繰り上げを行う。クライアントからの繰り 上げに対する応答がない時には、リース期間が切れるまで待つ。(リース期間 がないと、クライアントがダウンしているか、単に返事が遅いだけなのか、区 別ができない。)