概要説明
メモリが少ない環境、例えばDigitalOcean(以下DO)の最安プランだと512MB。
こういう環境でRailsのassets:precompile等の大量にメモリを使う処理を実行するとOut Of Memory(以下OOM)で処理がKillされてしまう事がありました。
今回はその具体的な例を書きながらその対処法を書いてみたいと思います。
問題発生 > 焦る自分 > 対処 > 解決まで
それでは早速、問題発生から対処、解決までを時系列で簡単に説明して行きたいと思います。
今回はRailsアプリを、DOのサーバーにCapistranoでデプロイ中にassets:precompileが失敗した例を使って説明していきます。
※この問題が発生した簡単な環境説明を下の方に書いたので、興味があれば是非そちらも見てみて下さい。
Railsアプリの更新、修正が完了。
↓
Stagingにデプロイしてみる。
↓
大丈夫そうなのでProductionにデプロイしてみる。 カチャカチャカチャ…ッターン! (`・ω・´)
↓
assets:precompileでエラー発生! ワッザ!? (@ω@;)
↓
何度やってもassets:precompileでエラーが出る。(´;ω;`)
↓
SSHKit::Runner::ExecuteErrorって何だ?permissionとかも書いてある、スーパーユーザーでやってるのに何でだろう?…
↓
試しにsshでアクセスしてassets:precompileをやってみる。
↓
ちゃんと実行出来るので問題は権限関係じゃ無さそう、んでやっぱり失敗するなー。(´・ω・`)
↓
グーグル先生に聞いてみた。
↓
下記の記事を発見。
Capistranoのdeploy時にrake assets:precompileでerrorがでたら
自分の場合、残念ながら記事の内容を実行しても解決せず…
↓
しかしコメントにヒントを発見。
syslog見るとメモリ不足で落ちてました。
http://qiita.com/DQNEO/items/be026d978ef5dcf1e44e
でswap領域を増やすと落ちることはなくなりました。
↓
早速syslogを見てみる。
Nov 23 16:00:29 ****** kernel: [68714.309228] Out of memory: Kill process 2078 (ruby) score 288 or sacrifice child
Nov 23 16:00:29 ****** kernel: [68714.309486] Killed process 2078 (ruby) total-vm:956608kB, anon-rss:148736kB, file-rss:0kB
正にそれだった!
↓
DOでswapを設定する時の作法を調べてみる。
↓
下記のページを発見。
How To Add Swap on Ubuntu 12.04 | DigitalOcean
↓
詳しくは上記のページを見て貰えば良いのですが、取り敢えず実行すべき事だけを簡単に書いて行きます。
# 現在のスワップやスペックの確認。
sudo swapon -s
df
# スワップの生成: 今回は1GBに設定しました。
dd if=/dev/zero of=/swapfile bs=1M count=1024
sudo mkswap /swapfile
sudo swapon /swapfile
# スワップがちゃんと生成されているか確認
swapon -s
# スワップの設定
sudo nano /etc/fstab
# /swapfile none swap sw 0 0
# 上の行を追加
echo 10 | sudo tee /proc/sys/vm/swappiness
echo vm.swappiness = 10 | sudo tee -a /etc/sysctl.conf
# 権限関係の設定
sudo chown root:root /swapfile
sudo chmod 0600 /swapfile
上記を実行後、もう一度Productionにデプロイ!
↓
エラー無しでデプロイ完了!ヽ( ´ω` )ノ
と言う感じです。
まとめ
つまり何か大量にメモリを食う処理でエラーが発生している場合はOOMが起こっている事を考えてみましょう。
OOMだった場合&メモリを簡単に増やせない時は、一度スワップの設定を確認してみましょう!って感じです。
因みにですが「DigitalOcean assets:precompile error」等で検索すると、DOの公式フォーラムで「メモリが足りないかもしれません。利用プランをアップグレードしましょう。」みたいな事をスタッフの人が書いてるのが幾つか出てきて、解決後「まぁ確かにそうだけど違う解決法も有るのになー」とか思っちゃいました…
まぁそう言うサービスなので仕方のない事かもしれませんが、何となくモヤっとしてしまいました…
(´・ω・`)
まぁ今回の教訓はStagingを作るなら、OSや使用するソフト等以外にスペックやスワップ等、その辺もしっかり合わせておきましょうって事ですね。
それとレンタルサーバーのスワップ設定をちゃんと確認しておきましょうって感じですかね…
同じ様な問題に遭遇した人が居たら、この記事が少しでも参考になれば幸いです。
問題が発生した環境
以下は上記の問題が発生した時の、簡単な環境説明です。
Development
- OS: Ubuntu 14.04 x64
- 説明: VMwareを使ってWindows7上で起動して使ってます。まぁ直接インストールした方が良い気もするのですが、何かと使い勝手が良いのでこの状態で開発してます。
Staging
- OS: Ubuntu 14.04 x64
- DBとかその他諸々: Chefを使ってDevelopmentと同じ様な感じにしています。
- デプロイ: デプロイにはcapistranoを使用しています。
- 説明: ローカルにVagrantを使って建てたやつ、仮想化には色々早いと聞いたLXCを使ってます。
LXCについては以下の記事をご参照ください。
15分で分かるLXC(Linux Containers)の仕組みと基本的な使い方
第1回 LXCとコンテナの基本:LXCで学ぶコンテナ入門 -軽量仮想化環境を実現する技術
自分は下記のBoxを使わせて貰いました。
https://vagrantcloud.com/fgrehm/boxes/trusty64-lxc
確かに起動が早くて良い感じです。Linuxを使ってる人は是非一度試してみて下さい!
(`・ω・´)b
Production
- OS: Ubuntu 14.04 x64
- DBとかその他諸々: Stagingとほぼ同じ(ユーザー名とかDB名等がちょっと違う)レシピを使ってChefで構築しました。
- デプロイ: デプロイにはcapistranoを使用しています。
- 説明: DOの最安プランで運用してます。Vagrant用のプラグインがあって、とても簡単に扱う事が出来ます。
DOとVagrantの組み合わせについては以下の記事を見てみて下さい。
VagrantとSSDなVPS(Digital Ocean)で1時間1円の使い捨て高速サーバ環境を構築する
vagrantではじめるクラウド開発環境(DigitalOcean編)
上記記事でも紹介されていますがプラグインについては以下の物を使わせて貰いました。
Vagrantを通して使えるコマンドの一覧があるので、一度見ておくと良いかなと思います。
https://github.com/smdahlen/vagrant-digitalocean
いやぁ、便利な世の中になったものです!w