困ったことに、Railsアプリの本番環境で利用しているUnicornが起動しません。
ERROR -- : Cannot allocate memory - fork(2) (Errno::ENOMEM)
本番環境は下記の通りです。
環境
- AWS EC2(t3.micro)
- Rails 6
- Nginx
- Unicorn
翻訳してみると下記の通りです。
Cannot allocate memory = メモリを割り当てることができません
ということでgoogle先生に聞いてみると、分かりやすい記事がありました。
記事と同様に現状のメモリ使用状況について調査してみます。
$ top
top - 21:31:53 up 70 days, 5:32, 1 user, load average: 0.03, 0.01, 0.00
Tasks: 208 total, 1 running, 167 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.3 sy, 0.5 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.2 st
KiB Mem : 980012 total, 64996 free, 799364 used, 115652 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 51004 avail Mem
4行目がメモリに関する記載です。見やすく整理すると、
Total | 980,012KiB |
free | 64,996KiB |
used | 799,364KiB |
buff/cache | 115,652KiB |
たしかにfreeが少ない。。
そして、Swapに関してはtotal 0のため、Swap領域を作ることでメモリ不足を解消できる可能性があります。
スワップ領域の作り方は下記記事を参考にさせて頂きました。
まず、スワップ用ファイルを作成します。
サイズは2GiBにします。
$ sudo dd if=/dev/zero of=/Swapfile bs=1M count=2048
=> 2048+0 レコード入力
2048+0 レコード出力
2147483648 バイト (2.1 GB) コピーされました、 14.9788 秒、 143 MB/秒
続いて、
$ ls /swap
=> No such file or directory
swapディレクトリがなく、ルート直下にSwapfileが生成されていたため、下記にて対応します。
# swapディレクトリを作成
$ sudo mkdir swap
# Swapfileをswapディレクトリへ移動
sudo mv Swapfile swap
権限を変更します。※これをしておかないと、後々エラーがでます。
#swapディレクトリへ移動
$ cd swap
#権限変更
$ sudo chmod 600 Swapfile
mkswapでスワップファイル用としてフォーマットします。
$ sudo mkswap Swapfile
=> スワップ空間バージョン 1 を設定します。サイズ = 2 GiB (2147479552 バイト)
ラベルはありません, UUID=e0a25838-3c6d-4212-856c-cc1596216592
スワップファイルを有効化します。
$ sudo swapon Swapfile
結果を確認してみます。
$ top
top - 22:14:22 up 70 days, 6:14, 1 user, load average: 0.02, 0.01, 0.00
Tasks: 212 total, 1 running, 171 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.3 sy, 0.3 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.3 st
KiB Mem : 980012 total, 60028 free, 819368 used, 100616 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 38540 avail Mem
5行目にSwapが追加されました。
ユニコーンを起動してみます。
# ユニコーン起動
$ bundle exec unicorn_rails -c config/unicorn.conf.rb -E production -D
# 起動確認
$ ps -ef | grep unicorn | grep -v grep
無事起動確認できました。
同様のエラーがあれば、参考にしてもらえると嬉しいです。