やったことだけ書く備忘録

EC2上でffmpegを動かすと強制終了してハマった話

EC2上でffmpegを動かす時の注意点


社内の開発で最近流行りの動画を扱う機能を実装していたんですが、EC2インスタンス内で稼働しているDocker Container内でffmpegを使うと、結構な確率でプロセスが強制終了する問題に遭遇しました。
(さらに、一度終了するとメモリリークするのかどんどん失敗頻度があがるっぽい)
m4.largeのスペックでも起きるし、最初はパラメータの問題かffmpegの問題だと踏んでかなり時間をかけて調べてたんですが、的外れでした。何の事はない、OOM-KIllerにやられてたのでした。




tail -f /var/log/messages
...
Memory cgroup out of memory: Kill process 11587 (ffmpeg) score 136 or sacrifice child
Killed process 11587 (ffmpeg) total-vm:540752kB, anon-rss:69412kB, file-rss:0kB


うん、殺されてた。というか先にこのログ見ろよって話なんですけどね…

中のソースコードまで見てないけど、ffmpegはエンコード実行時にメモリをオーバーコミットしてるっぽくて、メモリが不足し始めるのが原因かなって思います。

参考:http://passingloop.tumblr.com/post/11957331420/overcommit-and-oom-killer
さらに、Amazon Linuxではswap領域が用意されないので(これが直接的な問題でした)、OOM-Killerの標的になるようです。

なので、EC2インスタンスの起動時にSwap領域を作ればffmpegは強制終了しなくなりました。具体的にはcloud-initで、




#cloud-config
bootcmd:
cloud-init-per instance $(fallocate -`cat /proc/meminfo | grep “MemTotal” | awk ‘{print $2}’`/swap.img)
cloud-init-per instance $(mkswap /swap.img)
cloud-init-per instance $(swapon /swap.img)
 


という感じで、起動時にメモリと同量のSwap領域を作ります。 http://dev.classmethod.jp/cloud/ec2linux-swap-bestpractice/ を大いに参考にさせていただきました。なお、m4.largeではインスタンスストアは指定できないので、仕方なくEBS上に作成しました。起動して確認すると、




$ free
total used free shared buffers cached
Mem: 8179480 2218940 5960540 432 191844 1440456
-/+ buffers/cache: 586640 7592840
Swap: 8179476 30532 8148944



作成されていますね。ただし、AutoScaling Groupに対して設定するには、起動設定を作りなおさないといけなくて、これがとても面倒でした…。

オンプレミスなサーバでやってると、当然のようにSwap領域は準備されているものなので、自分もそう思い込んでいました。反省。AWSでffmpegでハードなエンコードをする時はこの設定を行うことを推奨します。

« 前の記事 次の記事 »

0件のコメント

コメントを投稿する

 画像に表示されている文字を入力してください。