AWS (Amazon Linux) にswap領域を追加する方法

このブログはAWS (Amazon Linux) 上で運営しているのですが、ここ最近、ブログに接続できない状況がちらほら発生するようになっていました。

その原因を調べるとともに、対策としてLinux上にswap領域を追加しましたので、そのやり方について覚書的にまとめたいと思います。

<スポンサーリンク>

何が起こっているのか

apacheエラーログの確認

まず、なぜブログに接続できないという事象が発生しているのかを確認するために、Webサーバとして使用しているapacheのログを見てみることにしました。

apacheのログはデフォルトで”/var/log/httpd”ディレクトリの中に記録されますが、今回はそこに含まれているログのうち、エラーログである”error_log”を確認してみました。

$ sudo less /var/log/httpd/error_log

すると、”mmap() failed: [12] Cannot allocate memory”というエラーが多発していました。そのため、ブログに接続できないのはメモリ不足が原因のように思われます。

メモリ使用状況の確認

メモリの使用状況を確認する方法はいくつかあるのですが、今回はfreeコマンドを使いました。

$ free
             total       used       free     shared    buffers     cached
Mem:       1017368     865856     151512        656      14500      70036
-/+ buffers/cache:     781320     236048
Swap:            0          0          0

コマンド結果の見方ですが、「Mem:」行には主に、現在使用中(used)のメモリサイズと空きメモリ(free)のサイズが表示されます。

なお、LinuxにはI/Oを高速化するために使われるbufferとcacheという領域用にメモリが自動割り当てされており、これらのメモリサイズがusedのメモリサイズに含まれています。そして、これら領域はメモリ使用状況がひっ迫した際にはリリースされ、freeとして扱われます。

このようなメモリひっ迫状況を想定して「-/+ buffers/cache:」行には、usedからbufferとcacheを差し引いたメモリサイズとfreeにbufferとcacheを足したメモリサイズが表示されます。

さて、実はこのコマンドを叩く直前にサーバをリブートしたのですが、それにも関わらずメモリの使用割合はかなりのもので、トランザクションが一時的に増加した際にはメモリがひっ迫するものと考えられます。

対応策の実施

さて、対応策には、メモリを増やしたりメモリを食っているプロセスを特定してそのプロセスに特化した改善を行う方法などが考えられますが、今回はお手軽な方法として、swap領域を追加するという方法を採用しました。

swap領域とは

「swap」という言葉に聞きなじみのない方のために、簡単に説明しておきます。

swapとは、ハードディスク上に設ける領域で、メモリが不足した際にメモリに代わって使うことができるものです。今回のように一時的にトランザクションが増加してメモリが不足した際に、エラーを吐くのではなく、このswap領域をメモリとして代用して処理を継続することができます。

swap領域の追加と有効化

作業手順は以下の通りです。

①スワップ用の領域をハードディスクに確保する

$ sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
2048+0 records in
2048+0 records out
2147483648 bytes (2.1 GB) copied, 31.6365 s, 67.9 MB/s

ddコマンドは、ファイルをコピーして作成するためのコマンドです。

“if”にコピー元のファイルを、”of”に作成するファイルを指定するのが基本的な使い方です。

なお、”bs”にはコピー時に一度に読み書きをするサイズを、”count”はそれを何回実施するかを指定します。

また、”if”に指定されている”/dev/zero”とはlinuxに用意されている特殊なファイルで、これを”if”に指定することにより、”of”で指定したファイルの中身をNULL文字で埋めることができます。

つまり、上記の指定は、「”/”ディレクトリ直下に、”swapfile”という名称で、NULL文字で埋め尽くされた1MB * 2048 = 2GB分のファイルを作成する」ことを意味しています。

②作成したファイルのアクセス権限を変更する

$ sudo chmod 600 /swapfile

作成したファイルに対して、”600″(作成者であるrootユーザのみ読み書きができる)を指定します。これを行わないと、後述するswaponコマンド実行時に、”swapon: /swapfile: insecure permissions 0644, 0600 suggested.”という警告が表示されます。(警告が出ても、swap領域として使えるようではありますが。)

③swap用ファイルシステムとして初期化する

$ sudo mkswap /swapfile
Setting up swapspace version 1, size = 2097148 KiB
no label, UUID=1c922087-fa52-4d08-8454-1132cc95abe9

作成したファイルをswap領域として使用するためには、mkswapコマンドにより初期化を行います。

④swap用ファイルを有効化する

$ sudo swapon /swapfile

swap用ファイルを作成しただけでは、このファイルをswap領域として使うことはできません。swaponコマンドを使用して、swap領域を有効化します。

⑤確認

$ free
             total       used       free     shared    buffers     cached
Mem:       1017368     942788      74580        656      15232     176660
-/+ buffers/cache:     750896     266472
Swap:      2097148          0    2097148

最後に、swap領域が有効化されているか確認します。freeコマンドを叩くと、最後の行にswap領域として2,097,148Byte≒2GBが有効化されていることが分かります。

再起動後に自動的に有効化するための設定

有効化したswap領域ですが、OSを再起動すると無効化されてしまいます。そこで、再起動後に自動的に有効化されるよう設定を行います。

①/etc/fstabファイルの修正

$ sudo vim /etc/fstab
#
LABEL=/     /           ext4    defaults,noatime  1   1
tmpfs       /dev/shm    tmpfs   defaults        0   0
devpts      /dev/pts    devpts  gid=5,mode=620  0   0
sysfs       /sys        sysfs   defaults        0   0
proc        /proc       proc    defaults        0   0
/swapfile   swap        swap    defaults        0   0  ← この行を追加

OS起動時に、OSは”/etc/fstab”というファイルを参照して有効化するファイルシステムを決定します。そこでこのファイルの最後に、先ほど作成したswap領域に関する行を追加します。

具体的には”/swapfile swap swap defaults 0 0″という行を追加すれば、起動時にswap領域を有効化できるようになります。

②システムの再起動

$ sudo reboot

起動時に有効化されるかどうか確認するため、システムを再起動します。再起動するためのコマンドは”reboot”です。

③確認

$ free
             total       used       free     shared    buffers     cached
Mem:       1017324     773844     243480        276      12612     148188
-/+ buffers/cache:     613044     404280
Swap:      2097148          0    2097148

freeコマンドにより、swapが有効化されているか確認してみます。Swap行に値が入っていることにより、自動的に有効化されていることが確認できました。

その後

この設定を行ってから1週間程度経過しますが、今のところメモリ不足は発生していないようです。

継続的に状況を見て、再発するようであればまた別の対策を取り、ブログにまとめておきたいと思います。