明けましておめでとうございます。今年もよろしくお願いします。
さて、早速ですが。
AWSで様々なアプリケーションを動かしていると、普段は c3/c4 シリーズに適した使い方なんだけども稀に大量のメモリを一度に使うことがある、というものに出くわすことがあります。
このような状況ではswap(仮想メモリ)の仕組みが動いていると非常に効果的なのですが、デフォルトではオフになっています。c3/c4シリーズを使う上では通常は後継のc4を使うのが筋なのでしょうけれども、swap領域として使用するストレージは、c3シリーズのみに提供されるインスタンスストアを使うのが気持ちイイです。
この記事では、今更ながら、c3でswap領域を確保する手順を確認します。
※この記事は 第67回 紅白歌合戦 を視聴しながら書きました。
インスタンスのlaunch
インスタンスをlaunch(作成)する際は必ず、インスタンスストアを使う宣言をするのを忘れないようにします。デフォルトでは使われません。
Management Console で言うと、この画面ですね。「Add New Volume」ボタンがミソです。
まずは負荷テスト環境の整備
指定した量のメモリを確保するには、stress
コマンドが便利です。
stress
コマンドは標準のyum
リポジトリからインストールが可能です。
$ sudo yum install stress
メモリを確保する
例
$ stress --vm 1 --vm-bytes 2G --vm-keep --timeout 60s
ここで指定しているオプションの意味は以下のような感じです。
- 1つのプロセスで(
--vm 1
)、 - 2GBytesのメモリを確保し(
--vm-bytes 2G
)、 - メモリの確保&解放を繰り返さずに確保しっぱなしにして(
--vm-keep
)、 - 実行開始から60秒経過したら終了(
--timeout 60s
)
詳しいオプションの説明はman
を見るか、 stress(1): impose load on/stress test systems - Linux man page あたりが参考になるでしょう。
初期状態のマシンで 4GB のメモリを確保
次のコマンドを実行すると 4GBytes のメモリの確保を試みます
$ stress --vm 1 --vm-bytes 4G --vm-keep --timeout 60s
しかし、c3.large が搭載しているメモリは 3.75 GBytes ですので、これは次のようなエラーになります。
stress: info: [2823] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd stress: FAIL: [2824] (494) hogvm malloc failed: Cannot allocate memory stress: FAIL: [2823] (394) <-- worker 2824 returned error 1 stress: WARN: [2823] (396) now reaping child worker processes stress: FAIL: [2823] (451) failed run completed in 0s
これからswapの設定をする訳ですが、同じ操作をしてエラーにならなければ、正常に設定できていることの確認になると言えます。
インスタンスストア1基丸々swapにする
通常は、AWSの公式マニュアルに沿った操作をするのが良いでしょう。
Instance Store Swap Volumes - Amazon Elastic Compute Cloud
コマンドだけ挙げると
# 確認用 $ swapon -s $ lsblk # インスタンスストアのswap用初期化 # ※c3.large に「普通に」インスタンスストアを付けると /dev/xvdb と /dev/xvdc になる。ここでは xvdb を使っている $ sudo mkswap /dev/xvdb # swapとして利用開始する $ sudo swapon /dev/xvdb
OS再起動に耐える設定にする
reboot(OS再起動)すると、上記の「swapとして利用開始する」のところだけ忘れ去られてしまいますので、fstab
の設定を入れておくと起動時に再設定することができます。
fstab
設定内容は前述のマニュアルを見るのが良いでしょう。
※後述の設定をする場合はfstab
の設定は不要です。
stop / start に耐える設定にする
stop / start すると、インスタンスストアの中身は忘却の彼方へと消え去ってしまいます(当然ですね)ので、上記の「インスタンスストアのswap用初期化」のところからやり直しになります。
start時にこれらの作業を自動で実施させるには、/etc/rc.local
を使うのが便利です。
末尾に mkswap
と swapon
を仕込みましょう。
設定後は次のような状態になりました。
$ cat /etc/rc.local #!/bin/sh # # This script will be executed *after* all the other init scripts. # You can put your own initialization stuff in here if you don't # want to do the full Sys V style init stuff. touch /var/lock/subsys/local mkswap /dev/xvdb swapon /dev/xvdb
なお、この設定が存在するとき、stop / start ではなくて reboot を実施したときに mkswap
がエラーを吐きます。既に設定済みであるからです。神経質な方は他の手法を探しましょう。
Immutable Infrastructure として捉えた設定
一度 launch したインスタンスは stop することなく、利用停止時は terminate される、という前提を持ち込むと、これらの mkswap
や swapon
は /etc/rc.local
ではなく cloud-init などの仕組みに乗せるのが便利でしょう。
swap確保後のメモリ確保テスト
top
コマンドを別端末で動かしながら $ stress --vm 7 --vm-bytes 2G --vm-keep
のように 14GBytes のメモリを確保しようとしても、(数十秒かかりますけれども)落ちずに頑張ってくれます。
これなら気持ち良く新年を迎えることができますね!
今年もメモリ負荷なんかに負けない、良い一年でありますように。