VPS(Lightsail)の空きメモリ状況を常時収集してpandas+matplotlibで可視化
やりたいこと
タイトル通りです。VPS(Amazon Lightsail)インスタンスの空きメモリ状況を常時収集し、可視化します。
目的
現在友人で集まるゲームのマルチプレーサーバーを運営しています。ログイン人数が増加した際などに時折サーバー側のアプリケーションがクラッシュするので、まずどのような場合にクラッシュするのか、特にメモリ不足の可能性について検討します。
サーバー側設定
サーバーの種類
今回使用しているサーバーはAmazonが運営しているVPSサービスであるLightsailのメモリ4GBプランを利用しています。OSはUbuntu 18.04.2 LTSです。
ちなみに、OS情報は/etc/os-release
等を見ることで調べることができます。
$ cat /etc/os-release
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.2 LTS"
VERSION_ID="18.04"
︙
サーバーの状態を取得
LightsailのUbuntuにはデフォルトでvmstat
というコマンドが入っており、マシンの状況を調べることができます。調べていませんが、その他のLinux OSにも大体入っているかと思います。vmstat
の使い方・結果の見方はこちらの記事を参照してください。
サーバーの状態を常時監視するためにはvmstat
の結果を常時どこかに出力しておく必要があります。今回はこのようなスクリプト(vmstat.sh
)を用意しました。1秒ごとにvmstatの結果を出力し、1時間ぶんを書き出したらgzip圧縮して保管します。
DATETIME="$(date +'%Y%m%d-%H%M%S')"
cd /home/username/logs/
vmstat -t 1 3600 > vmstat-"${DATETIME}".log
gzip vmstat-"${DATETIME}".log
このvmstat.sh
を1時間ごとに実行すれば毎時間ごとにファイル分けされたログを得ることができます。
定期的にファイルを分ける理由はサーバーのリソース不足時にできるだけログが破壊されないようにするためと、データ圧縮のためです。サイズについては一ヶ月分溜めると無圧縮では約300MBほどになりますが、圧縮すれば約40MBと無視できない差になります。
1時間ごとにスクリプトを実行するにはcronを利用します。詳細はこちらの記事などを参照してください。今回は/etc/crontab
を編集します。原則、crontabの編集にはsudoが必要です。
# m h dom mon dow user command
︙
1 * * * * root /path/to/vmstat.sh
この行を/etc/crontab
の末尾に追加すると、毎時1分にvmstat.shを実行してくれます。
注意:crontab
の最後の行の後には改行を必ず付けましょう。
末尾が改行でないと無効なファイルとして扱われ、動作しません。
編集したらcronを再起動します。sudo service cron restart
を実行すればOKです。
解析側設定
解析の流れは以下のようになります。
-
vmstat
の結果を一括でダウンロード - gzipを解凍し、不要な行(ヘッダー)を除いて整形
- 必要な行を抽出し、プロット
今回は1, 2をシェルスクリプト(bash)で、3をpython3+matplotlibで行います。
今回のスクリプトを実行するためにはpython3にpandas, matplotlib, seabornが必要です。anacondaやpipで入手してください。また、データを自動でダウンロードするためにサーバーには事前にssh keyを登録しておきましょう。
#!/bin/bash
rsync -amuvh --size-only --progress user@server_address:logs/*.gz .
rsync -amuvh --size-only --progress user@server_address:logs/*.log .
ls -1 *.gz | xargs -L1 gunzip -k
ls -1 *log | tail -n48 | xargs cat | grep ":" > concat.log
python plot_vmstat.py concat.log
rm vmstat-*.log
analyze.sh
はrsync
でサーバーのログがあるディレクトリ(今回は${HOME}/logs)からデータをダウンロードします。
次にls -1 *.gz
でダウンロードした.gzファイルの一覧を取得し、
その各ファイルに対して(xargs -L1
)gunzipを適用します。
-k
オプションにより既にダウンロードしたファイルを削除せず、次回以降のダウンロード量を節約します。
その後ls -1 *.log
で解凍した.logファイルと最新の圧縮されていない.logファイルの一覧を取得し、
-tail -n48
で直近48ファイル(48時間相当)についての結果のファイル名を取得します。ファイル名に時間が入っているので、ファイル名を辞書順に並べたとき後ろが最新です。
xargs cat
でそれらのファイル名に対応するファイルの中身を表示します。
grep ":"
でテンプレートでない部分(タイムスタンプの":"
)を抽出し、concat.log
に保存します。
最後にplot_vmstat.py
で中身をプロットします。
plot_vmstat.py
の中身は以下のようになっています。
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# register matplotlib converters for "parse_dates" of pd.read_csv
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
sns.set(rc={'figure.figsize':(11, 4)})
# read vmstat log file
data = pd.read_csv("concat.log", delim_whitespace=True, header=None, parse_dates=[[17, 18]])
data.sort_values(by="17_18")
date_time = data.loc[:,"17_18"] # date-time
free = data.loc[:, 3]//1024 # freemem (KB to MB)
free_cache = (data.loc[:, 3]+data.loc[:, 5])//1024 # free+cache (KB to MB)
# plot
plt.figure()
plt.plot(date_time, free, color="r", linewidth=1, label="Free memory")
plt.plot(date_time, free_cache, color="b", linewidth=1, label="Free+Cache memory")
plt.xlabel("Date")
plt.ylabel("Memory size [MB]")
plt.legend(bbox_to_anchor=(1, 1), loc='upper right', borderaxespad=0, fontsize=14)
plt.tight_layout()
plt.savefig("free_memory.png")
複数のスペースで整形されているテキストファイルはdelim_whitespace=True
できれいに読めます。時刻は0から数えて17番目(date)と18番目(time)にあります。スペースで区切られていますがparse_dates=[[17, 18]]
で連結してくれます。空きメモリ(free)は0から数えて3番目のカラムにあり、ページキャッシュ (cache)は5番目のカラムにあります。ついでにKBからMBに変換しておきます。
プロットするカラムを変えれば他の指標もプロットできます。
出力
このようなグラフが出力されます。サーバーは空きメモリがなくなるとキャッシュを使用し始め、キャッシュも足りなくなるとアプリケーションがクラッシュしメモリが解放されているようです。しかし、すぐに再起動してまたメモリが消費されていることがわかります。
結論
メモリ状況を常時収集し、必要なタイミングで可視化するという目的は達成できました。メモリの割り当てを調整するか、よりメモリの多いインスタンスを借りる必要がありそうです。
なんらかの事情でログが取れなかった場合にグラフが飛んでしまう(06-19 15時あたりの斜め線がそうです)ことの解決等、細かい課題はありますが、概ね目標は達成できました。
追記・修正
コメントに従い、シェルスクリプトの${}
を"${}"
に変更しました。
Author And Source
この問題について(VPS(Lightsail)の空きメモリ状況を常時収集してpandas+matplotlibで可視化), 我々は、より多くの情報をここで見つけました https://qiita.com/nakanohito_piyo/items/b5176f121dd808603150著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .