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

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

タグ:swap

久しぶりのラズベリーパイネタです。

これまであまり意識することなかったんですが、ラズパイ(Raspbian) をデフォルトのまま使っている時のスワップサイズって 100MB しかないんですね。。
2019011001


ラズパイのメインメモリは 1GB 固定です。サーバー用途メインで、あまり重い作業をしなければこれで足りるのかもしれませんが、デスクトップ用途で使ってブラウザでタブをたくさん開いて・・・という使い方をしていると、結構な確率でメモリ不足になると思います。 というわけで、スワップファイル容量を変更する手順を調べたので以下に紹介します。

Raspbian の場合、スワップファイル容量は /etc/dphys-swapfile というテキストファイルで管理されています。スワップファイル容量を変更するにはこのファイルをテキストエディタで開いて、CONF_SWAPSIZE という変数の値を(メガバイト単位で)指定します。例えば以下の例では 2GB に指定しています:
CONF_SWAPFILE=2048

ただし、2GB 以上の値を指定する場合は同ファイル内にある CONF_MAXSWAP の値も変更する必要があります(32 bit カーネルを考慮しているせいか、この値を変更せずに CONF_SWAPFILE の値だけを 2048 より大きな値に変更してもスワップファイルサイズは 2048 に設定されてしまうようです)。例えば 4GB に設定する場合は以下のようにします:
CONF_SWAPFILE=4096
CONF_MAXSWAP=4096

設定変更後に以下のコマンドで dphys-swapfile を再起動すると、スワップファイルのサイズが変更されます:
$ sudo systemctl stop dphys-swapfile
$ sudo systemctl start dphys-swapfile

2019011002


当たり前ですがスワップファイルはマイクロ SD カード内に作られるため、マイクロ SD カードの容量とも相談して設定する必要があります。またあまり頻繁にスワップが発生するような使い方だと、ただでさえストレージとしては比較的寿命の短いマイクロ SD カードの劣化を意識する必要が出てくるかもしれません。

その場合はラズパイに USB メモリを挿してマウントし、上記の /etc/dphys-swapfile ファイル内の CONF_SWAPFILE でスワップファイルを USB メモリ内に作成するようにしてマイクロ SD カードから退避させる、という方法もあるようです(未確認)。


Linux を使っている時に、ディスクの余った領域を SWAP ファイルとして作成し、SWAP 領域を増やす手順です。OS を起動したまま、サービスを止めることなく変更します。


まず増やす前の状態を確認しておきます:
# free -m
             total       used       free     shared    buffers     cached
Mem:           996        918         77          3          3        586
-/+ buffers/cache:        328        667
Swap:         1023          1       1022

現在のスワップは約 1GB(1023 MB)になっています。この領域を 1024 MB 増やして、約 2GB にします。

方法としては /var/swapfile という 1GB のファイルを作り、このファイルをスワップとして利用します:
# dd if=/dev/zero of=/var/swapfile bs=1M count=1024
# mkswap /var/swapfile
# swapon /var/swapfile

ここまでの作業が出来たら改めて状態を確認します:
# free -m
             total       used       free     shared    buffers     cached
Mem:           996        918         77          3          3        586
-/+ buffers/cache:        328        667
Swap:         2047          1       2046

SWAP メモリが約 2GB に増えました。なお、このまま元の状態(SWAP メモリ 1GB)に戻す場合は swapoff コマンドを利用します:
# swapoff /var/swapfile

このままだと次回起動時には SWAP メモリは 1GB に戻ります。次回起動時以降は SWAP メモリ 2GB の状態で起動させたい場合は、以下のコマンドを実行して /etc/fstab ファイルを書き換えます:
# echo "/var/swapfile        swap                    swap    defaults        0 0" >> /etc/fstab

 

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/

 

このページのトップヘ