EC2でサーバーを運用しているのですが、最近メモリ使用率がいっぱいになってしまいアプリケーションが動かないという事がありました。
情報を集めていると、擬似的にメモリを作ってスワップさせる方法に行き着きました。
さて、
今回はEC2インスタンスに仮装メモリを作る方法について触れます。
一体どういうことなのか?
今回実装する内容をまとめると下記のイメージです。
そもそも、
なぜアプリケーションが動かなかったというと、(図の右上の様に)物理メモリ(RAM)がオーバーフローした事です。
「もし、あの時メモリに1GB余力があれば…」という状況でした。
どうすれば1GBの余力を温存できたか??
一番手っ取り早いのは、サーバーをアップグレードして1GB多いサーバーを使用する事です。
しかし、サーバーの性能を上げれば比例してコストも上がります。
今まで問題がなく、今回一時的にオーバーフローしたのであれば、
(原因にもよりますが)コストをかけてでもサーバーの性能をあげる必要はあるのでしょうか?
メモリもストレージも元を多度せばデータを保持する事が目的です。
だったら、(インスタンスの)ストレージはメモリに比べて容量があるので、間借りして1GB分(一部)メモリにしてしまおうというのが今回の内容です。
確保したストレージの領域の事をスワップ領域と言い、ストレージ内に作ったメモリを仮想メモリと言います。
しかし、懸念もある…
メモリとストレージではデータ通信速度が明らかに違います。
ストレージでは、メモリほど通信測度が早くないためアプリケーションの遅延が発生します。
しかし、アプリケーションが落ちるよりもはるかにマシです。
そのため、
緊急時は一時的にメモリをスワップ(交換)してアプリケーションを落とさない様に設定します。
作業手順
基本的には、AWSドキュメントに参考にして説明します。
また、インスタンスのディストリビューションは「amazon linux 2」なので、redhat系になります。
他のディストリビューションの場合は違う箇所があるかもしれませんので、それぞれの環境に合わせて変えてください。
環境について
使用するインスタンスの使用については下記です。
項目 | 内容 |
---|---|
EC2インスタンタイプ | t2.micro |
Linuxディストリビューション | amazon linux 2 |
現状確認
まず、現在の状況を確認します。
メモリ使用率を調べるには、free
コマンドで確認できます。
$ free total used free shared buff/cache available Mem: 1007348 172680 354144 540 480524 631892 Swap: 0 0 0
物理メモリの確認
物理メモリの使用状況は/proc/meminfo
からでも確認できます。
$ grep Mem /proc/meminfo MemTotal: 1007348 kB MemFree: 353528 kB MemAvailable: 631240 kB
仮想メモリの確認
仮装メモリの使用状況も同じく/proc/meminfo
から確認できます。
当然ですが、インスタンスを立ち上げた段階ではスワップ領域はありません。
$ grep Swap /proc/meminfo SwapCached: 0 kB SwapTotal: 0 kB SwapFree: 0 kB
使用率が高いプロセスを確認
そもそも、何が原因でメモリが使われているのかを確認するには、vmstat
やtop
コマンドがあります。
手っ取り早くどのプロセスが一番メモリ使用しているか確認したい場合は、top
コマンドを使って次の様に確認することが出来ます。
$ top -o %MEM // 省略 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND (プロセスが一覧で表示されます。)
領域確保
領域の決め方
AWSのドキュメントでは次の様に書かれています。
- 物理 RAM の量: 2 GB 以下の RAM
- 推奨されるスワップ領域: RAM 容量の 2 倍 (32 MB 以上) スワップファイルを使用して、Amazon EC2 インスタンスのスワップ領域として動作するようにメモリを割り当てるより一部引用
t2.microの場合、メモリは1GBです。
そのため、2GBのスワップ領域を用意します。
スワップ領域確保
次に、インスタンス内にスワップ領域を設定します。
インスタンス内に、swapfile
という領域を作ってそこを仮想メモリとして使用します。
$ sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 $ sudo chmod 600 /swapfile $ sudo mkswap /swapfile
メモリサイズが大きすぎる場合
ブロックサイズは実際に割り当てるメモリより小さい領域を当てる必要があります。
t2.microインスタンスの場合、下記の様に1Gのブロックを2個にしようとするとブロックサイズが大きすぎるため領域を作ることができません。
$ sudo dd if=/dev/zero of=/swapfile bs=1G count=2 dd: 大きさ 1073741824 バイトの入力バッファによりメモリを使い果たしました (1.0 GiB)
スワップ機能を有効にする。
上記で、スワップ領域を設定しました。
次に、スワップ機能自体を有効にします。
スワップ機能の設定はswapon
で行います。
$ sudo swapon /swapfile $ sudo swapon -s ファイル名 タイプ サイズ 使用済み 優先順位 /swapfile file 2097148 256 -2
永続化
これで、スワップの領域を割り当てることができました。
次に、再起動時にもスワップ領域を設定できる様にします。
再起動時の設定は、/etc/fstab
で設定することができます。
$ vi /etc/fstab
ファイルを開いて、末尾に設定を追加します
(既存の設定) /swapfile swap swap defaults 0 0
確認
有効になったか確認します。
現状確認でも使用したfree
コマンドを使用して確認すると、Swap
という項目で、空き容量が空いているのがわかります。
$ free total used free shared buff/cache available Mem: 1007348 151520 67496 536 788332 671404 Swap: 2097148 256 2096892
雑感
ふと思った事をまとめました。
特に、裏付けのある話でもありませんのでゆるーくお読みください。
メモリとSSD
HDDよりSSDの方が早いというのは聞きますが、SSDでメモリの代用はできないものでしょうか?
各通信規格の測度を一覧でまとめた方がいらっしゃいます。
qiita.com
情報元がわかりませんのであくまで参考値ですが、
SSDの通信速度が10MB/s
に対して、メモリの速度は10GB/s
です。
単純計算で1000倍なので、SSDでも代替えは出来そうにないですね。