面白ければいいんじゃない?

やくたいのないこと、痛々しいことばかり書きます。

LinuxでのMinecraftのMODサーバのパフォーマンスを上げたいのでいろいろ設定した

はじめに

私の運用するMODサーバのパフォーマンス向上テクニックについてメモ程度に解説します。
仕様は以下の通り

  • Minecraft1.7.10
    • Forge環境、工業化MOD盛りだくさん
  • OS CentOS7 64bit
  • JRE OpenJDK 1.7.0_71 Server
  • CPU PhenomII X6 1100BE (3.3GHz 6core)
  • MEM 16GiB ECC

コマンドラインオプション

java -Xmx10G -Xms10G -Xmn3G -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalPacing -XX:ParallelGCThreads=3 -XX:+AggressiveOpts -jar jarファイル名 nogui"

解説

長ったらしいですが、ひとつづつ解説します。

ヒープの設定
-Xmx10G -Xms10G

ヒープは適当に確保します。私は専用機なのでとれるだけ取っています。

NEW領域の設定
-Xmn3G

ガベージコレクタ(以下GC)のログを見て調整すると、NEW領域は1/3程度確保しておくとよさげです。
これはCPUやメモリのパフォーマンスとの相談ですが、大きくしすぎると一回のGCの時間がかかりすぎ、小さいとガベコレが頻発することになります。

パーマ領域の設定
-XX:PermSize=256m -XX:MaxPermSize=256m

このくらいパーマ領域がないとGregtechが入っている場合、起動しない。

GC方法の設定1
-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalPacing

メモリが十分にあるならば、コンカレントGCにしましょう。また、インクリメンタルの方が細かくGCするので他のスレッドが止まりにくい(はず)です。

GC方法の設定2
-XX:ParallelGCThreads=3

jvmに割り当てるCPUコアの数だけGCのスレッドを走らせるようにします。

高速化オプションの有効化
-XX:+AggressiveOpts

昔バグがあったそうですが、今は大丈夫っぽいのでせっかくだから有効にしましょう。

GUIは無駄に重い
nogui

CUI環境だから当たり前。

注意

ガベコレは沼ですが、ログ見てそれなりに設定するといいと思います。

RAM DISC

Minecraftは巨大なWorldデータを定期的に*1保存するので、Disk IO周りがすぐに飽和します。なので、RAM DISCに保存します。

やりかた

RAMディスクを作成、マウント

ルートになってRAMDISKを作る

# mkdir /mnt/ram
# mount -t tmpfs -o size=4096m tmpfs /mnt/ram/

naoyaが言うにはtempfsは動的に確保してくれるようなので*2、余裕をもった設定にしていいのですが、おおむね、RAMDISK容量(worldディレクトリの容量+余裕)+システムの使用量の残りをjvmのヒープに割り当てればいいんじゃないんでしょうか。メモリカツカツならうまくやらんとならんですが、だったらメモリ買ってきた方がいいです。

シンボリックリンクを張る

minecraft実行用のユーザーで、minecraftのディレクトリに移動して、シンボリックリンクを張る。

$ mkdir /mnt/ram/world
$ ln -s /mnt/ram/world world

バックアップ

当たり前ですが、RAM DISCはシャットダウンや再起動すると消えます。なのでcronで定期的にバックアップを取るようにしましょう。
バックアップについては、minecraft用の起動script*3に実装されているものでokですが、保存場所がRAM DISCに変わるので、その部分を書き換える必要があります。
この辺はいろいろと*4スクリプトの改良余地がありますが、面倒なのでやってません。

コアの周波数とスレッドの割り当て

私のサーバのCPUはAMDのPhenomII X6 1100BE ですが、これにはターボコアテクノロジーという技術が採用されており、6コアのうち、最大3コアがTDPの許す限り、3.7GHzに上昇します。しかし、OS側からは、P0ステートのままで変わりません。*5
IntelのTurbo boostについてはよく調べていませんが、似たような感じのはずなので、そこは適宜読み替えてください。
ここで、Minecraftは1tick(50ms)ごとにロードされているチャンクが解決されているために、最終的にはシングルコアのCPUパワー勝負*6になります。
よってシングルコアが最大限のパワーを発揮する設定にしなければりませんから、ターボコアの効く3コアにMinecraftのスレッドを張り付けて、クロック変更のオーバーヘッドを避けるために最大クロックで稼働させ、その他のコアはオンデマンドにして諸々のプロセスを処理させるようにします。

設定

3コアの速度を最高速度に設定
# cpupower -c 0 frequency-set -g performance
# cpupower -c 1 frequency-set -g performance
# cpupower -c 2 frequency-set -g performance

CPUの0-2の3コアを最大クロック設定にします。
ブート時に設定するためにサービスも有効化しておきます。

# systemctl enable cpupower.service

参考:CPU Frequency Scaling (日本語) - ArchWiki

最高クロックのコアを切り離す

カーネルが指定したCPUにプロセスを割り当てないように、まず、/etc/default/grubを編集して、GRUB_CMDLINE_LINUXにisolcpus=0-2を書き足します。あ、もちろんルートで。

GRUB_CMDLINE_LINUX="rd.lvm.lv=centos_eucalyptus/swap crashkernel=auto  vconsole.keymap=jp106 vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_eucalyptus/root isolcpus=0-2 rhgb quiet"

そしてこれをGRUB2に反映させて再起動する。

# grub2-mkconfig -o /boot/grub2/grub.cfg

プロセスの割り当て状況は下記で確認。

$ for pid in $(ps -eLf | awk '{print $2}'); do taskset -a -c -p $pid; done

参考:NAKAMURA Minoru's Diary (2012年7月)

マイクラ起動コマンドライン

最高速度に設定し、他のプロセスから切り離したコアにマイクラを突っ込みます。

taskset -c 0-2 java 以下コマンドラインオプション

謝辞

simltixさんにGC周りの協力してもらいました。

*1:デフォルトで2秒だったはず…

*2:tmpfs は本当に容量が動的なのか - naoyaのはてなダイアリー

*3:Tutorials/Server startup script - Minecraft Wiki

*4:例えば、シャットダウン時に自動的に保存し、起動時に復元するなど。

*5:4Gamer.net ― 「Turbo CORE」とは何なのか。Phenom II X6を使ってその挙動をねちねちと調べてみる

*6:ただし、GCはパラレルになる。

注意:ここに書かれていることは筆者の個人的見解であり所属する組織などの意志を表すものではありません。