まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:ec2

Amazon EC2IDCF のサーバーインスタンスを使っていますが、どうしても気になるのはデフォルト状態ではスワップ領域が確保されていないことです:
2015020601


↑メモリは1GBで残り65MBほど。
 もうすぐメモリが足りなくなりそう、でもスワップ領域はゼロ・・・


特に高速化のために memcached とかを使うアプリを動かそうとすると、どうしてもメモリが不足しがちになります。スワップ領域がない状態で、一瞬でもメモリが足りなくなってしまうとアウトです。回避するにはなんとかしてスワップ領域を確保する必要があります。


EC2 や IDCF クラウドでは静的にスワップ領域が確保されているわけではないため、EBS などの追加ディスクを使う方法もありますが、これだとスワップ領域のために料金がかかる上、EBS は I/O にも課金されるので、スワップファイルを作る先としてはコスト的に不利です。

というわけで、インスタンスの起動時にディスクの空き部分を使ってスワップファイルを作ってスワップ領域とする、という方法を紹介します。これなら(ディスクに空きがあれば、の前提が必要ですが)ディスクを追加せずにスワップ領域を確保することができます。

具体的には /etc/rc.local あたりに以下のような内容を追加します。この例ではスワップサイズをメモリ量から動的に変更するようにしていますが、あくまで一例です。固定値を書き込んでしまってもいいと思います(青字は僕のコメント):
  :
  :
SWAPFILENAME=/swap.img スワップファイル名
MEMSIZE=`cat /proc/meminfo | grep MemTotal | awk '{print $2}'` 現在のメモリ量(KB)を取得

メモリ量からスワップ領域のサイズを決定
if [ $MEMSIZE -lt 1012293 ]; then
  SIZE=${MEMSIZE}k メモリ 1GB 以下の場合、スワップ領域はメモリサイズと同じ
elif [ $MEMSIZE -lt 2097152 ]; then
  SIZE=${((MEMSIZE * 2))}k メモリ 2GB 以下の場合、スワップ領域はメモリサイズの倍
elif [ $MEMSIZE -lt 8388608 ]; then
  SIZE=${MEMSIZE}k メモリ 8GB 以下の場合、スワップ領域はメモリサイズと同じ
elif [ $MEMSIZE -lt 67108864 ]; then
  SIZE=${((MEMSIZE / 2))}k メモリ 64GB 以下の場合、スワップ領域はメモリサイズの半分
else
  SIZE=4194304k メモリ 64GB 以上の場合、スワップ領域は8GB
fi

スワップファイルを作成してスワップオン
fallocate -l $SIZE $SWAPFILENAME && mkswap $SWAPFILENAME && swapon $SWAPFILENAME
  :
  :

/etc/rc.local は他の初期化スクリプトが実行された最後に実行される設定コマンドファイルです。なのでサービスやらの自動実行が行われた最後にこのコマンドが実行され、/swap.img というスワップファイルが作成されて、スワップ領域として動き始めます。このスワップファイルのサイズは物理メモリサイズに応じて動的に切り替わるようにしています。


これでサーバーインスタンスを再起動すると、今度は起動時に上記のスクリプトが実行され、スワップ領域が動的に作成されます。これで少し安心:
2015020602



(参考)
http://dev.classmethod.jp/cloud/ec2linux-swap-bestpractice/

 

ネットワークパフォーマンス(端的に言えば回線速度)の計測方法は多々有りますが、クラウドのネットワークパフォーマンスを計測しようとすると、1つ問題が生じます。

多くのクラウドでは、サーバーインスタンス契約後に使えるインターフェースが SSH に限られています。つまりテキストのコンソール画面だけが使える状況です。その制約の中で「どこまでわかりやすくネットワークパフォーマンスを 計測できるか?」という課題があるのでした。

 自分が使っているのは speedtest と呼ばれるツールです。この導入から利用、そして実際の出力結果までを紹介します。

まず導入方法ですが、おそらく最も簡単で多くのケースで利用できるのが、この wget を使ったやり方です:
# cd /usr/local/bin
# wget -O speedtest-cli https://raw.github.com/sivel/speedtest-cli/master/speedtest_cli.py
# chmod +x speedtest-cli
上記例では /usr/local/bin という Path の通ったディレクトリにあらかじめ移動してから、そこにダウンロードしてくる、という方法を取っています。これで speedtest-cli という実行ファイル(実体は Python スクリプト)が用意できました。

そのまま(パラメータなしで)実行するだけでもアップロード速度とダウンロード速度を計測してくれます:
# speedtest-cli
Retrieving speedtest.net configuration...
Retrieving speedtest.net server list...
Testing from Kddi Corporation (XXX.XXX.XXX.XXX)...
Selecting best server based on latency...
Hosted by Too late (Ishikari) [847.06 km]: 38.316 ms
Testing download speed........................................
Download: 47.94 Mbits/s
Testing upload speed..................................................
Upload: 23.04 Mbits/s
# 

ダウンロードが 47.94 Mbps、アップロードが 23.04 Mbps という結果でした。まあこれは実行タイミングにも影響されると思いますが、1つの目安にはなると思います。

そして、このツールの特徴の1つでもある "--share" オプションがあります。これを付けて実行すると、実行結果を png 画像にして提供してくれます:
# speedtest-cli --share
Retrieving speedtest.net configuration...
Retrieving speedtest.net server list...
Testing from Kddi Corporation (XXX.XXX.XXX.XXX)...
Selecting best server based on latency...
Hosted by Too late (Ishikari) [847.06 km]: 38.316 ms
Testing download speed........................................
Download: 47.94 Mbits/s
Testing upload speed..................................................
Upload: 47.94 Mbits/s
Share results: http://www.speedtest.net/result/3980766722.png
# 

"Share results:" に書かれた URL にアクセスすると、このような画像が表示されます:


上記例は僕の自宅内のサーバーから行ったもので、契約している au ひかり(KDDI)から実行されたことも判別してくれています。また総合判断としての "GRADE: B" という記載もされています。

面白そうだったので、いくつかの環境から実行してみました:

(AWS EC2)


(DTI ServerMan/VPS)


(IDCF)



AWS の EC2 が "GRADE: A+" で速いことになってる!(悪意なし) ネットワークそのものは速いんでしょうかね、でも体感に直結しないのはやはり海外リージョンのせいなのか。。

そして IDCF クラウド、うちの au ひかりよりも速いってこと!? こうなると自宅サーバーで運用中のサービスの移行も検討しないといけないかな・・・


Amazon EC2 インスタンスの負荷測定をどうやって行うべきか、という問題です。結論を先にいうと「EC2 インスタンスの場合は top コマンドではなく、CloudWatch を使うべき」ということになります。

きっかけは自分が先日ツイートしたこの現象に気付いたことでした:


EC2 で運用しているサーバーの CPU 負荷を測定すると、CloudWatch で測定した場合は80%超え(上図左)になってアラート出まくりなのに、直接ログインして top コマンドで測定するとせいぜい10%前後(上図右)になる、というものです。

なぜ測定方法によって負荷値が異なるのか? CPU 負荷の定義が違うのか? だとしたらどちらを信用すべきなのか、どちらかはそもそも信用してはいけないのか、・・・・

よくわからんなあ・・・ と思っていたのですが、ある日こんな情報を見つけました:
EC2 monitoring: the case of stolen CPU


簡単に言うと、「例えば CPU が 0.1 個割り当てられた仮想マシンでは、(topコマンドでの)CPU 負荷 = 10% の状態でその仮想マシンのCPU的には100%になっている」ということです。なので EC2 上の(Xen上の)仮想インスタンスを1台のマシンとみなして負荷を計測するのであれば CloudWatch を使うべき、ということになります。逆に言えばこの環境下での top コマンドの結果には注意が必要です。


上記ページには "If you’re an IBM cus­tomer with a pSeries frame these ques­tions aren’t entirely new to you"(IBM の pSeries の顧客であれば特別目新しいことではない) とも書かれてます。へぇ、AIX ってそうなんだ。知らなかったけどね・・・ :P


 

このページのトップヘ