大きいファイルはスループットが速いサイトからダウンロードしたい
OSのインストール用ISOのように大きめのファイルをダウンロードする場合は、スループットの速いサイトを利用したいものです。ネットワーク上の距離(ホップ数)が少ないならさらにベターです。しかし、自分の居場所からのスループットが速いサーバを調べるのは意外にめんどくさいものです。
そこで、適切なミラーサイトを見つけるためのデータを収集するスクリプトを書いてみました。
実行例
スクリプトを実行すると、こういう出力が得られます。
$ ./centos_mirrorsite_speedtest.sh
mirror.fairway.ne.jp rtt min/avg/max/mdev = 16.641/17.757/25.294/2.529 ms 5.092 Mbit/s
ftp.iij.ad.jp rtt min/avg/max/mdev = 3.095/3.426/4.586/0.421 ms 80.299 Mbit/s
ftp.jaist.ac.jp rtt min/avg/max/mdev = 17.870/18.271/19.266/0.515 ms 29.983 Mbit/s
ftp-srv2.kddilabs.jp 78.340 Mbit/s
ftp.nara.wide.ad.jp rtt min/avg/max/mdev = 9.681/10.608/15.241/1.696 ms 45.502 Mbit/s
ftp.riken.jp rtt min/avg/max/mdev = 3.966/4.133/4.550/0.170 ms 79.223 Mbit/s
ftp.tsukuba.wide.ad.jp rtt min/avg/max/mdev = 4.069/4.396/5.642/0.455 ms 71.108 Mbit/s
$
この出力は、サイトごとに以下の情報を出力しています。
- ping の実行結果
- curl での速度計測結果
ダウンロードのビットレートは Linux のカーネルイメージである vmlinuz をそれぞれのサイトからダウンロードして計測しています。
上記の例ではビットレートだけを見れば ftp.iij.ad.jp を使うのが最も良さげに見えます。しかし ping の実行結果を見ると ftp.riken.jp のほうが mdev (標準偏差) が小さいのでびっトレードの変動が少ないかもしれません。速度比較となるとビットレートだけを気にしてしまいがちですが、通信経路の安定性も気にするほうが良いと思います。
さらに言えば traceroute でホップ数を取得して比較してみたいのですが、サイトや経路によってはうまく行かないことがあります。なので、確実に比較できる情報としては ping の実行結果とビットレートの2つです。
なお、上記結果の中で kddilabs.jp で ping の結果が表示されないのですが、これはこのサーバがどうやら icmp をフィルタされているためです。
実装
動作確認は CentOS7 だけで行っています。ping の出力メッセージの仕様が CentOS7 とは異なる場合は想定通りに動かないかもしれません。ただし curl がインストールされていれば少なくとも速度計測は正しく行えます。
またスクリプト自体は大変シンプルな実装ですので、CentOS以外のミラーサイト比較も容易に行えます。この場合はサイトのURL一覧とTARGETPATHを目的にあわせて修正してください。
#!/bin/bash
# CentOS のミラーサイトに対する ping の RTT やスループットを測るスクリプト
#
# ・行っていること
# ping を10回実効して、RTTの結果だけを抽出する。ave や mdev の値が小さいほうがベターと思われる。
# CentOS7 の isolinux/initrd.img (約40MB) をダウンロードする時間を測る。
#
# ミラーサイトの一覧はここらへんを参照
# https://www.centos.org/download/mirrors/
#TARGETPATH="7/os/x86_64/isolinux/initrd.img"
TARGETPATH="7/os/x86_64/isolinux/vmlinuz"
targetfile=${TARGETPATH##*/}
for mirrorsite in $(
cat << EOL
http://mirror.fairway.ne.jp/centos/
http://ftp.iij.ad.jp/pub/linux/centos/
http://ftp.jaist.ac.jp/pub/Linux/CentOS/
http://www.ftp.ne.jp/Linux/packages/CentOS/
http://ftp.nara.wide.ad.jp/pub/Linux/centos/
http://ftp.riken.jp/Linux/centos/
http://ftp.tsukuba.wide.ad.jp/Linux/centos/
EOL
); do (
downloadpath=${mirrorsite%/}/${TARGETPATH}
testpath=${downloadpath%/${targetfile}}
url_hostname_path=${testpath#http://}
targethost=${url_hostname_path%%/*}
# 速度テスト用のファイルがあるかどうか?
curlresult_test=$( curl --head --silent --output /dev/null --write-out "%{http_code}" ${downloadpath} )
# ファイルが無いならスキップ
if [ "$curlresult_test" -ge 400 ]; then
echo "[abort] cannot find centos mirror path"
exit
fi
# 別のURLにリダイレクトされたら、そのURLからホスト名を取得する
if [ "$curlresult_test" -ge 300 ]; then
downloadpath=$( curl --head --silent --output /dev/null --write-out "%{redirect_url}" ${downloadpath} )
testpath=${downloadpath%/${targetfile}}
url_hostname_path=${testpath#http://}
targethost=${url_hostname_path%%/*}
fi
# ping で RTT を調べる
echo -n "${targethost}"
pingresult=$( ping ${targethost} -c 10 | tail -1 )
echo -en "\t${pingresult}"
# ダウンロード速度を調べる
curlresult=$( curl --location --silent --output /dev/null --write-out "%{speed_download}\n" ${downloadpath} )
curlresult=$( echo "scale=3; 8*${curlresult} / (1048576)" | bc )
echo -e "\t${curlresult} Mbit/s"
);
done