モチベーション
ある遅延と変動が大きい国際間通信について、往路、復路のどちらが通信に影響しているのか調べたい。PingによるRTT遅延測定ではなく、往路復路別々に測定したい。現状片道遅延が難しい理由は測定する2ノードの時間が正確に同期していなければならないため。ただ、今回のような国際回線はRTT 100msもあるので最寄りNTP同期で良しとする。せいぜい誤差数msだろうし、理論的な最短片道遅延も推測でき、そこからNTP同期ズレ値もある程度推測できると想定。
また、処理オーバーヘッドを考えると本来スクリプトで処理するべきではないけど、スクリプトにしたところで昨今のサーバなら1msも誤差を生じないだろう、ということで、楽ちんなPythonを選択。
かんたんにいうと、「ざっくり、てきとうに手抜きして」
手法
クライアント~サーバー間でupdパケット1往復
- クライアントは(a)開始時刻を保存しサーバへパケット到着時間を問い合わせる
- サーバは(b)そのパケットを受信した時間をクライアントへ返信
- クライアントは(c)サーバからの返信を受信した時間を記録
- (b) - (a) = 往路遅延 / (c) - (b) = 復路遅延
コード(minimum)
Server
# !/usr/bin/env python
import socket
import time
host = '0.0.0.0'
port = 12345
bufsize = 512
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((host,port))
while True:
data,addr = sock.recvfrom(bufsize)
sock.sendto("%.6f" % time.time(), addr)
Client
# !/usr/bin/env python
import socket
import time
host = 'localhost' # とりあえず自IPを指定
port = 12345
bufsize = 512
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
stime = "%.6f" % time.time()
sock.sendto(stime, (socket.gethostbyname(host), port))
data, addr = sock.recvfrom(bufsize)
etime = "%.6f" % time.time()
print "forward : " + str(float(data) - float(stime))
print "backward: " + str(float(etime) - float(data))
print "total: " + str(float(etime) - float(stime))
time.sleep(1)
sock.close()
実際はパケロスもひどいので、リトライ処理とか、タイムアウト処理も必要だし、もう少し扱いやすい出力で実装したけど、今は省略。
とりあえずローカルホストで実行
同一ホスト内(localhost)で実施
$ python owpingserver.py &
$ python owpingclient.py
forward : 0.000324964523315
backward: 4.81605529785e-05
total: 0.000373125076294
$ ping localhost -c 1
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.017 ms
--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.017/0.017/0.017/0.000 ms
ping より精度が少なくとも1桁は劣る。。。主に往路のオーバーヘッドが重いなあ。まあ10μsと100μsの精度の差、だいたい想定どおり。国際回線じゃ無視していいだろ。(あきらめが肝心)
実際の国際回線での測定結果
青線:往復、オレンジ:往路、緑:復路。半日ぐらいバッチで走らせて、グラフ化して読み取れることは
- 明らかにRTT遅延に対する往路遅延の影響はでかい
- 地理的経路はほぼ同じ(はず)で片道15msはやや短めな気がするので、ノードの時間が最大3msぐらいずれてるかも。
- 私は休日の早朝からなにやってるんだろう。
ちなみに同じデータセンタの違うインスタンスで試したら1マイクロ秒ぐらい未来の時間が帰ってきたw
追記
2017/2/26: Cで等価なコードに書いてみたけど150μs減ぐらい。思ったより改善しなかった。当面pythonでいいや。