ゲームを題材に学ぶ 内部構造から理解するMySQL

第2回 ゲーム系で確認すべきパラメータ

この記事を読むのに必要な時間:およそ 2 分

 本記事は,『Software Design 2019年8月号』の第2特集「ゲームを題材に学ぶ 内部構造から理解するMySQL」をWeb掲載用に再編集したものです。
 本記事のテーマを,より基本的なところから丁寧に解説した『SQLの苦手を克服する本 データの操作がイメージできれば誰でもできる』が2019年8月26日に発売されました。本記事と併せてご活用ください。

RDBMSで検討すべきパラメータとは

 前回は,非常に大まかにRDBMSの構造についてお話ししました。もし,これまでの構造で考慮していない部分があったら,いくつかのパラメータの内,見直すべきものがあると理解できたのではないでしょうか。とはいえ,ゲームの種類によって要件はまったく違いますから,確実に「こうすれば良い」というパラメータ設計はありません。要件に応じて,確認・検討すべきおもなパラメータとお考えください。詳しくは,設定ファイル(my.cnf)についてマニュアルなどで確認しましょう。

ページサイズについて

 MySQL(InnoDB)では,デフォルトのページサイズは16KB注1で,ほかに8KBと,4KBを選ぶことができます。ゲーム系は,OLTP(On-Line Transaction Processing)型と呼ばれるタイプのシステムになり,通常,1ユーザのデータに対して読み書きすることが多い,つまり,細かいデータアクセスが多くなるシステムです。そのようなシステムの場合,小さいページサイズのほうが有利な可能性が高いです。

注1
Amazon RDSなどの共用インスタンスはほとんど16KBで変更ができません。

 小さいページサイズには,もちろんデメリットもあります。それは,小さいページサイズにすると利用されない空白が多くなるということです。

 たとえば,平均のレコード長(TEXT,BLOBなどのデータ型は別ページに保存されるのでそれ以外で)が2,500Byteで,ページサイズが4KBのものを選ぶと,1ページにほぼ1レコードしか保存できず,メモリまたはHDDの37.5%が空白のまま利用されないということになります。逆に,ページサイズが大きいほど,データが細密に充填されメモリやHDDの利用効率が上がりますから,大量のデータを読み込み集計をするような処理に向いています。

 ページサイズは検討されずにデフォルトのまま利用されていることが多いですが,非常にパフォーマンスに影響するためよく検討してください。

ログファイルのサイズ

 ゲーム系ではイベントやキャンペーン時にアクセスが集中します。アクセスの集中時にログファイルが溢れて,HDDへのフラッシュ(実データの書き込み)が大量に起きると,サーバの負荷は一気に高まります。

 イベントやキャンペーン時に乗り切れるサイズを検証し設定しましょう。

ログファイルへの書き込みタイミング

 たとえば,イベントやキャンペーン時には,1秒間に数万回という書き込みが発生することがあり,ログファイルを大きくして,HDDへのフラッシュが起きないように設定しても高負荷になることがあります。そのようなときには,⁠innodb_flush_log_at_trx_commit」というパラメータを2に設定して,ログファイルへの書き込みタイミングを1秒に1回にすることでHDDへの書き込みの負荷を減らすことができます(デフォルトのパラメータは1でコミットごとの書き込みになっています)⁠ただし,HDDへは二重に遅延書き込みを行うことになり,最大で1秒間に更新されたデータがロストする可能性もあります。

 しかし,最近のネットゲームでは図1のように,⁠RDBMSへの書き込みはバトル終了時に一度行う」というゲームも増えているようです。

図1 ネットゲームの書き込み処理

図1 ネットゲームの書き込み処理

 このようなゲームでは,RDBMSと,クライアントやAPサーバ間でデータの不整合が常に起きている状態で運用されているため,ユーザからみれば,障害が起きたときには数十秒から数分のロールバックが起きるので,ログファイルへの書き込みを1秒に1回にしてもユーザ価値は大きく変わらないと考えられます。ですから,⁠innodb_flush_log_at_trx_commit = 2」という設定値も検討されたら良いでしょう。

 ただし,課金に関する処理は,コミットのタイミングでログファイルに書き込まれるように,⁠innodb_flush_log_at_trx_commit = 1」で設定した別のデータベースで行い,コミットされたデータのロストを防ぎましょう。

ログバッファサイズ

 ⁠innodb_flush_log_at_trx_commit = 2」として,ログファイルへの書き込みタイミングを1秒に1回とする場合,ログバッファサイズはこれまでより大きく設定する必要があります。バッファが足りなくなったときは,1秒経っていなくても書き込みが行われることになるため,⁠innodb_flush_log_at_trx_commit = 2」にする意味がなくなりますから,1秒間に書き込まれるログが十分に入るだけのサイズを設定してください。

各ワークメモリ(スレッドバッファ)サイズ

 セッション単位で利用されるワークメモリのサイズです。設定値と最大の同時接続数との掛け算が最大の使用量となりますので,割り当て過ぎに注意しましょう。各処理が行える量以上に割り当てないようにしましょう。

データバッファサイズ

 ⁠innodb_buffer_pool_size」というパラメータで調整します。これは,チューニングの基本とされるパラメータで,できる限り大きくとってください。⁠物理メモリの8割を目安に」などとされていることが多いですが,メモリの増減が簡単なクラウドサービスを利用していれば8割という数値に意味がありません。ですから,目安になる数値としては,⁠キャッシュヒット率」が良いでしょう。ゲームに限らずデータベースを長く運営しているとデータが増え,キャッシュヒット率が下がる傾向にありますから,目標とするキャッシュヒット率になるように設定値を定期的に見直してください。

 業務系では,95〜99%を目標値として調整することが多いですが,目標値はゲーム(システム)によって違ってきます。たとえば,一連のチューニングを終えて,満足できるパフォーマンスが出ている時点のキャッシュヒット率を目標値とするとパフォーマンスを維持しやすいでしょう。

 物理メモリを増やしても,⁠パラメータを修正しない限り増やしたメモリは利用されない」ということにくれぐれも注意しましょう。

著者プロフィール

生島勘富(いくしまさだよし)

株式会社ジーワンシステム 代表取締役。
フリーランスのエンジニアを経て,2003年に株式会社ジーワンシステムを創業する。その後,プレイングマネージャーとして多くのシステム開発に従事し,現在ではデータベースを中心としたコンサルティングを行っている。
メール:info@g1sys.co.jp
Webサイト:http://www.g1sys.co.jp/
ブログ:https://sikushima.hatenablog.com/ Twitter:@Sikushima