【AWS EC2】インスタンスに仮装メモリを作る

EC2でサーバーを運用しているのですが、最近メモリ使用率がいっぱいになってしまいアプリケーションが動かないという事がありました。
情報を集めていると、擬似的にメモリを作ってスワップさせる方法に行き着きました。

さて、
今回はEC2インスタンスに仮装メモリを作る方法について触れます。

一体どういうことなのか?

今回実装する内容をまとめると下記のイメージです。

f:id:nakahashi_h:20190724224718p:plain

そもそも、
なぜアプリケーションが動かなかったというと、(図の右上の様に)物理メモリ(RAM)がオーバーフローした事です。
「もし、あの時メモリに1GB余力があれば…」という状況でした。

どうすれば1GBの余力を温存できたか??

一番手っ取り早いのは、サーバーをアップグレードして1GB多いサーバーを使用する事です。
しかし、サーバーの性能を上げれば比例してコストも上がります。

今まで問題がなく、今回一時的にオーバーフローしたのであれば、
(原因にもよりますが)コストをかけてでもサーバーの性能をあげる必要はあるのでしょうか?

メモリもストレージも元を多度せばデータを保持する事が目的です。
だったら、(インスタンスの)ストレージはメモリに比べて容量があるので、間借りして1GB分(一部)メモリにしてしまおうというのが今回の内容です。
確保したストレージの領域の事をスワップ領域と言い、ストレージ内に作ったメモリを仮想メモリと言います。

しかし、懸念もある…

メモリとストレージではデータ通信速度が明らかに違います。

ストレージでは、メモリほど通信測度が早くないためアプリケーションの遅延が発生します。
しかし、アプリケーションが落ちるよりもはるかにマシです。

そのため、
緊急時は一時的にメモリをスワップ(交換)してアプリケーションを落とさない様に設定します。

作業手順

基本的には、AWSドキュメントに参考にして説明します。

aws.amazon.com

また、インスタンスのディストリビューションは「amazon linux 2」なので、redhat系になります。
他のディストリビューションの場合は違う箇所があるかもしれませんので、それぞれの環境に合わせて変えてください。

access.redhat.com

環境について

使用するインスタンスの使用については下記です。

項目 内容
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

使用率が高いプロセスを確認

そもそも、何が原因でメモリが使われているのかを確認するには、vmstattopコマンドがあります。
手っ取り早くどのプロセスが一番メモリ使用しているか確認したい場合は、topコマンドを使って次の様に確認することが出来ます。

$ top -o %MEM
// 省略
  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
(プロセスが一覧で表示されます。)

領域確保

領域の決め方

AWSのドキュメントでは次の様に書かれています。

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でも代替えは出来そうにないですね。

©︎2017-2018 WebSandBag