純規の暇人趣味ブログ

手を突っ込んで足を洗う

マイクラ鯖に持って来い!!、LinuxでRAMディスク!!

      2017/01/06    HimaJyun

私がマイクラ鯖を立てるに当たって一番苦労した所、それがディスクI/O(RAMディスクの作成やバックアップ)です。

マイクラではチャンクと呼ばれる細かいデータの読み書きなどでディスクI/Oがやたらと多いからラグの原因になると言われており(実際どれくらい影響するのかは知りませんが)、RAMディスク上にデータを置いて動かした方が良いのです。

なのですが、どうも情報が散らばってて良く分からない。

散って美しいのは桜だけです、情報はまとまっていた方が美しいのです。

tmpfs

ご自身でググって欲しい所ですが、せっかくなので軽く触れておきます。

一般的に、LinuxでRAMディスクを作成する際には「tmpfs」なるモノを使います。

これを使うとどんな黒魔術が成立するのかと言うと

Windowsで実現しようとすると色々と困難を極める「動的に容量を確保するRAMディスク」が簡単に作成出来ます。

つまり、確保したRAMディスクが1GBでも、実際に置いてあるデータが500MBだけならば、それに合わせて500MBしかメモリを使わないのです。

これなら、搭載メモリが貧弱な鯖でも有効的にメモリを使用できますね。

ちなみにramfsもあるよ(はぁと

「tmpfs」、名前を見れば大体察せるかと思われますが、「tmp+fs=tmpfs」です。

説明の必要はないかと思われますが、tmpとはtemporaryの事で、「一時的」と言う意味です。(fsはファイルシステムですね。)

つまり、一時的なデータを置く事を想定しているのでしょう。(普通の用途に使用しても問題ありませんけどね)

逆に、「ramfs」と言う物もあり、「ram」は文字通りメモリの事です。

「ramfs」は「tmpfs」の様に容量を動的に確保する事は出来ませんが、容量が増減するたびに逐一malloc/free(もしくはそれに相当する物)が呼び出される事がないので更に高速に動作するかと思われます(あくまで予想ですが)

作成してみる。

特段難しい物では無いです、手順さえ分かれば余裕です。

なお、UbuntuServer 16.04にて検証しました。

CentOSなどの他ディストリでも大まかな手順は変わらないと思いますが、細かい部分が違う可能性が高いです。

今回の例では「/mnt/ramdisk」に512MのRAMディスクを作成します。

あくまで例なので、その辺りはよしなにお取り計らい下さいな。

(とりあえず)コマンドで作成してみる

# 1.RAMディスクにするディレクトリを作成
# 今回は例として「/mnt/ramdisk」で
sudo mkdir /mnt/ramdisk

# 2.sudoで作成した(所有者がrootのまま)なのでアクセス権を与える
sudo chown ${USER} /mnt/ramdisk
sudo chmod 775 /mnt/ramdisk

# 3.作成(この手順は本当は必要ないけれども、参考として。)
# 「mount -t tmpfs -o size=容量 tmpfs パス」
sudo mount -t tmpfs -o size=512m tmpfs /mnt/ramdisk

このままだと、再起動すると元に戻ってしまいます。

起動時に自動でマウントする様に設定しましょう。

起動時にマウントする設定

# 1.「/etc/fstab」を開きます。
sudo editor /etc/fstab

# 2.「tmpfs パス tmpfs size=容量 0 0」を追記
#tmpfs /mnt/ramdisk tmpfs size=512m 0 0
# 追記ここまで、保存してエディタを終了してね。

# コマンドでやるならこう
echo "tmpfs /mnt/ramdisk tmpfs size=512m 0 0" | sudo tee -a /etc/fstab

# 3.マウント。
sudo mount -a

再起動してみて、指定した容量のRAMディスクが確保されていればOKです。

が、今のままでは再起動するとファイルが消えてしまうのは変わりません。

そこで、シャットダウン時にファイルの中身を退避させて、再起動した際に復旧する様に細工します。

シャットダウンしてもデータを保持させる

起動時、終了時に実行するrsyncでどうたらこうたら、と言う手法がありますが、面倒なので私が使っているinitスクリプトをご利用下さい。

謹製initスクリプトを使って!!

これ1つでramdiskのデータの退避、復旧が簡単に出来ます。

# 1.ディレクトリを移動
cd /etc/init.d

# 2.initスクリプトをダウンロード
sudo curl -L -O https://gist.githubusercontent.com/HimaJyun/eb878435cf02b20943dfeae1bd909f04/raw/99f6ac1d17c07469010c80ed877c42da5f826550/syncramdisk

始めてGitHub Gistを使いましたが便利ですね、これ。

前まで1ファイル置くのにわざわざレポジトリ作ってたのがバカみたい

initスクリプト内にディレクトリのパスを設定する項目があるので、ここを設定してください。

sudo editor /etc/init.d/syncramdisk

ファイル内に以下の様な部分があります。

# === 設定 ===
# 要:末尾スラッシュ
DATA_DIR='/mnt/ramdisk/'
SAVE_DIR='/mnt/ramsave/'
# ============

このDATA_DIRとSAVE_DIRを環境に合わせて設定して下さい。

SAVE_DIRに指定する退避先は事前に作成しておいて下さい、以下、例

sudo mkdir /mnt/ramsave
sudo chown ${USER} /mnt/ramsave
sudo chmod 775 /mnt/ramsave

後は、実行権限を与えて登録すればOKです。

# 1.実行権限を与える
chmod +x /etc/init.d/syncramdisk

# 2.サービスを登録
sudo systemctl enable syncramdisk

電源喪失の対策

ただ、このままでは、シャットダウン時しかデータがコピーされず、電源喪失->再起動の流れだと、最後にシャットダウンした時点でのデータになってしまいます。

サーバ的に言うと、UPSなどを使って電源が落ちないのが本来なのですが、そんな設備にイチイチ割くお金なんて無いですし、あっても落ちる時は落ちます。

重要なのは、如何にして「落ちた時の被害を減らすか?」ですよ。

と言う訳で、定期的に(例として、1日に1度)退避ディレクトリにバックアップを取る様にします。

# 1.crontabを編集
crontab -e

# 2.以下の内容を追記。
# 0 0 * * * rsync -a --delete /(RAMディスクのパス)/ /(退避ディレクトリのパス)/ >/dev/null 2>&1

# こんな感じ
# 0 0 * * * rsync -a --delete /mnt/ramdisk/ /mnt/ramsave/ >/dev/null 2>&1
# (出力を/dev/nullに送ると椅子を投げられるが、説明簡略化の為に省略)

これで、毎日0時0分(つまり、日が変わった時)にバックアップが実行されます。

23時59分に電源が落ちた!!、とかだと悲惨ですがそんなクリティカルな状況はまずないのでとりあえずはこれで安心

心配性の方は「0 0 * * *」を「0 * * * *」にすると良いです、1時間に1度バックアップします。

 - サーバ運営