はじめに
この記事を開いた方は、少なくとも「FiveMのサーバーを立ててみたい!」や「自分のFiveMサーバーにもっと人を入れたい」と考えていることでしょう。
本記事では、私が実際に同接200人Overのサーバーを構築・運営する上で、主にサーバー/システム側で気をつけたこと、最適化のポイントを6つに絞って解説します。
運営していたサーバー
私が運営に携わって、200人Overを達成したFiveMサーバーは「TGSGTA Vol.03」です。
2週間の招待制サーバーでしたが、期間中は毎日200人以上の接続を維持し、最終日には230人Overを達成しました。
1. メインサーバー選定
「ラグ=メモリ不足」と考えがちですが、FiveMサーバー(FXServer)のメインスレッド処理はCPUのシングルコア性能に大きく依存します。
- CPU: コア数が多いCPUよりも、シングルコアのクロック周波数が高いCPUを選択してください。コア数は6コア程度あれば十分です。
- Network (回線): 通常、ボイスチャット(Mumble)の音声データもFXServerを経由するため、帯域は5Gbps以上を推奨します。転送量は1週間で約2TBに達するため、従量課金ではなく、転送量無制限や安価なホスティング業者を選定するとコストパフォーマンスが良いでしょう。
2. インフラ構成の分散
メインサーバーにDBを同居させると、スクリプトの読み込みやイベント処理と、DBのI/Oが競合し、パフォーマンス低下の原因になります。そのため、FiveMで使用するMariaDBは別サーバーでホストすることを強く推奨します。
- CPU/メモリ: DB単体なのでハイエンドである必要はありませんが、メモリが極端に少ないとバッファプール(キャッシュ)が枯渇するため注意が必要です。
- Disk I/O: なるべく高い数値が出る環境を選びましょう。書き込み速度が250MB/s程度あると安心です。
- ネットワーク: パブリックネットワーク経由ではなく、**VNIC(仮想ネットワークインターフェース)**などを利用してローカルネットワークで接続してください。レスポンスタイムが格段に向上します。
可能であれば、Mumble(VCサーバー)も別サーバーで構築できるとさらに理想的です!
3. DBのチューニング
DBサーバーを分けたからといって安心はできません。データが増えるにつれて検索(SELECT)に時間がかかり、サーバー全体のTick Rateが低下する原因になります。しっかりとチューニングを行いましょう。
以下は私が実際に適用したチューニング例(my.cnf / server.cnf)です。
[mysqld]
# --- メモリ・キャッシュ設定 ---
# データをメモリ上にキャッシュする領域のサイズ。物理メモリの70%-80%程度を割り当てる。
innodb_buffer_pool_size = 18G
# バッファプールを分割して、スレッドの競合(取り合い)を減らす。
innodb_buffer_pool_instances = 4
# 更新データをディスクに書き込む前のログサイズ。
# FiveMの頻繁なデータ更新に耐えるため、デフォルトより大きめに設定。
innodb_log_file_size = 512M
# OSのファイルキャッシュを経由せず、直接ディスクに書き込みます。
innodb_flush_method = O_DIRECT
# --- 接続・スレッド設定 ---
# 同時接続数の上限設定。
# 通常はコネクションプールを使うため、そこまで巨大な数値にする必要はない。
max_connections = 251
# 接続スレッドのキャッシュ数。
# 新規接続時のスレッド作成オーバーヘッドを減らす。
thread_cache_size = 32
# --- クエリキャッシュ(無効化) ---
# 頻繁に更新されるゲームDBにおいてクエリキャッシュは負荷原因になるため無効化。
query_cache_type = 0
query_cache_size = 0
# --- 名前解決のスキップ ---
# クライアント接続時のDNS逆引きを無効化(遅延対策)。
skip-name-resolve
# テーブル定義のキャッシュ数。
# 多くのスクリプトが大量のテーブルを作成するので少し多めに設定。
table_definition_cache = 512
# --- スロークエリログ(監視・分析用) ---
# 実行に時間がかかっているクエリを記録。このログを見て更にチューニングを行う。
slow_query_log = 1
# 1秒以上かかったクエリをログに出力。
long_query_time = 1
# ログの保存場所
slow_query_log_file = /var/lib/mysql/slow-query.log
# インデックス(Key)が使われていないクエリもログに記録。重要なチューニング指標。
log_queries_not_using_indexes = 1
innodb_buffer_pool_size はサーバーの搭載メモリに合わせて調整してください。
- Indexについて: 配布されているスクリプトの中には、作者がIndexを全く設定していないケースが多々あります。スロークエリログを確認し、WHERE句で使われているカラムには自分でIndexを追加しましょう。
4. フレームワークについて
今から新しいサーバーを構築するのであれば、Qbox Project(フレームワーク)の使用をお勧めします。
メリット
現在主流のQBCore環境では、ox_lib 等の高機能な外部リソースを導入すると機能が重複しがちです。Qboxは最初からOXリソースの利用を前提に設計されているため、重複コードが少なくCoreシステムが段違いに軽いのが特徴です。
デメリット
- 日本での採用例がまだ少なく、ドキュメントも英語が中心のため、学習難易度は高めです。
- QBCoreの一部のイベントがQboxでは使用できないため、既存のQBCore用スクリプトがそのままでは動作しない可能性があります。
これらのデメリットを考慮しても、Qboxについて学習し、コアシステムとして採用する価値は十分にあります。
5. 負荷が大きいイベント/スクリプトの検出
FiveMクライアントでデベロッパーモードを有効にすることで、詳細なパフォーマンス情報を閲覧できます。
デベロッパーモードを起動するにはFiveMの起動引数に下記を追加してください。
+set moo 31337
Resmon
デベロッパーモード状態でF8コンソールに resmon true と入力すると、どのスクリプトがCPUリソース(ms)を消費しているかが一目でわかります。
NetEventLog
同様にコンソールに neteventlog true と入力すると、送受信されているネットワークイベントがリアルタイムで表示されます。
頻繁に呼び出されているイベントは、サーバー負荷や帯域圧迫の原因となっている可能性が高いです。
6. NPCを減らす
200人規模のサーバーであれば、プレイヤーだけで十分に賑わっているため、NPC(歩行者)や野良車両の湧きを制限しても問題ありません。これによりクライアント側の描画負荷を大幅に軽減できます。
local density = 0.05 -- 0.05 = 5%の湧き率。0.0でも可。
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
-- 車両とNPCの湧きを抑制
SetVehicleDensityMultiplierThisFrame(density)
SetRandomVehicleDensityMultiplierThisFrame(density)
SetParkedVehicleDensityMultiplierThisFrame(density)
SetPedDensityMultiplierThisFrame(density)
SetScenarioPedDensityMultiplierThisFrame(density, density)
end
end)
まとめ
以上の対策を行うことで、技術的には200人以上の接続を捌くことが可能です。
もちろん、導入するスクリプトの品質によってはDesync(同期ズレ)が発生することもあります。どうしても改善しない場合は、スクリプトをより軽量なものに入れ替えるか、自作に挑戦してみてください。
この記事を見てサーバーを運営したい人が増え、日本のFiveMコミュニティがより活発になることを心から祈っています。
質問について
記事内容に関する簡単な質問はコメント欄へ。
運営規模や環境、スクリプトに依存する相談は XのDM でも受け付けています!
