【CEDEC 2016 フォローアップ】秒間100万クエリを受け付ける大規模ソーシャルゲームのバックエンドDBシステムの設計・運用ノウハウ


どうも皆さん、こんにちは!!
株式会社Cygames で Database Administrator をしております。浦谷です!

今回は「CEDEC2016」に参加した時のフォローアップ記事を書いて行きますので、
よろしくお願いします!!

さて、今回のCEDEC2016での発表は、
秒間100万クエリを受け付ける大規模ソーシャルゲームのバックエンドDBシステムの設計・運用ノウハウ」のタイトルで発表してきました。

今回発表したセッションの資料を公開しておきますので、
会場に来られた方、来ていない方も是非ご覧ください。

CEDECの内容を更に補足していきます!!

ショートセッション(25分間)と短い時間ではありましたが、Cygamesでどの様なデータモデルを設計しているのか?どの様な運用をしているのか?等のノウハウを紹介いたしました。

ただ、ショートセッションと非常に短い時間での発表となったため、余り多くの事を伝える事が出来なかったかもしれませんので、CEDECでお話した内容をいくつか補足いたします。

今回CEDECで発表した内容は、

  • ドメインを意識したデータモデルの改善
  • generalログを使用したボトルネックの改善
  • 自動化+見える化によるボトルネックのキャッチアップ方法

この3つのアジェンダの内容を発表しましたので順番に補足していきます。

ドメインを意識したデータモデルの改善

皆さんの中でどのくらいドメインを意識した設計を行っている方がいるでしょうか?

因みにドメインは「属性が取り得る値の範囲や制約」の事で、
簡単に言ってしまうと「データ型」の事です。

それでは何故、「ドメインを意識したデータモデルの改善は必要!!」なのか?

その理由は、

  • データの不整合を防ぐため
  • ストレージのサイズに影響を与えないようにするため

である、と考えているからです。

自分はプロジェクトを横断的に見ている立場なのですが、
ドメインを意識しないで開発している事が多々あります。

ドメインを意識しないと、どの様な問題が起こるのか?の例を上げると…

例えば、「user_id」は本来INT型で、「AテーブルはINT」だけど、「BテーブルはMEDIUMINT」の場合は、Bテーブルのデータは不整合が発生してしまいます。
(マイナスを許容しないにも関わらず、「UNSIGNED」を付けないのも同様です。)

また、その逆も然りですが「card_id」は本来MEDIUMINT型で、「AテーブルはINT」だけど、「BテーブルはMEDIUMINT」の場合はデータの不整合は発生しませんが、データの持ち方としては不必要なデータサイズを確保する事になります。

これらは改善させる必要があります。

それから、
”数値型だったら全て「INT型」でいいでしょ!!”と、
楽観的に考えている方もいるかもしれません。

たとえ今がビッグデータの時代であったとしても、ストレージのサイズは無限ではありませんので、限られたリソースの中で無駄なく使用していく事が大事なのです。

なので、ドメインの「属性が取り得る値の範囲」を正しく守る事は非常に大事な事だと考えています。

但し、弊社では、主にアジャイル開発を取り入れているため、
ドメインを意識した設計は難しいので、チェックして改善させる必要があると思っています。

generalログを使用したボトルネックの改善

CygamesではAPIを実行して個々のクエリを解析してボトルネックを改善させているのですが、何故API毎のクエリを把握する必要があるのかと言うと、「クエリの発行数を減らすため」に実施している訳です。

API毎のクエリを把握する事が出来れば、

  • 発行する必要のないクエリが発行されていないかどうかを確認する
  • ループしてクエリを発行している箇所等、纏めることが可能なクエリは1回に纏めて実行する(IN句やバルクインサート等で対応する)
  • データがなければ「INSERT」、あれば「UPDATE」の場合は「ON DUPLICATE KEY UPDATE」を使用する
  • キャッシュ化出来る箇所はキャッシュ化する

等の確認や改善を行う事が出来ますので、確実に「クエリの発行数を減らす事が可能」になります。

また、改善する前はロジックを素直に書いている事が多いため、
クエリの発行数が多くなるロジックとなってしまいます。

クエリ数を減らすためにAPI毎に
「クエリを実行→リファクタリング→クエリを実行…」
を何回か繰り返し実施する事で改善させて行くと良いでしょう。

個々のクエリは軽くても、「塵も積もれば山となる」と同じく、
「軽いクエリも積もればレスポンスタイムが劣化する」ため、
ユーザーが快適に遊ぶ事が出来なくなってしまいます。
なので、1つでも減らす事が可能なクエリがあれば減らしていく様に努めています!!

自動化+見える化によるボトルネックのキャッチアップ方法

リリースされたら運用のフェーズになるのですが、
当然の事ながらアプリをリリースしたら終わりという訳ではなく、
ユーザーを飽きさせない為の施策として「イベントや新機能」等の追加が定期的に入ります。

自分もアドバイスに入れる時は入るのですが、全てのプロジェクトを見て回るには限界がありますので、主にはプロジェクトのメンバーでデータモデルの作成やクエリの作成を行って貰っています。
メンバー1人で作成するのであれば、その人がボトルネックにならない様に意識すれば良いのですが、チームで開発しますので、いろんな人がロジックを作成します。
そうなると、ソースコードは複雑化して自らボトルネックを生み出してしまうかもしれません。

なので、ボトルネックになってユーザーが快適に遊べなくなってしまうのは困るので、
「自動化+見える化」で即時ボトルネックをキャッチアップする様にしています。

例えば、「slowクエリログ」や「generalログ」を使用してボトルネックをキャッチアップする方法で、CEDECでは、slowクエリログの解析結果を見える化するツール「Slow_Query_Analyzer」を発表しました。

Slow_Query_Analyzerは、
日々出力されるslowクエリログをプロジェクト毎に集計して、
解析した結果を見える化するツールです。
※Cygamesの自社製ツールのため、社外には公開しておりません。

slowクエリログが出力されたら「取得」・「解析」して、その結果を「画面表示」して、
slowクエリログのボトルネックのキャッチアップを自動化している訳です。

特にイベント時は負荷が上がってくるため、徐々にslowクエリログが増えていきます。
更に、ユーザーが増えるとクエリの発行数やデータも増えますので、益々ボトルネックとなるクエリが増えていきます。そうなる前にslowクエリログの推移を見ながらボトルネックになりそうなクエリを改善していきます。
また、前日と比べて「slowクエリログがどの位増えたのか?」等を確認して、
前日よりも増えて来たクエリが存在した場合は改善していきます。

最後に

今回のCEDEC2016のテーマは「Now is the time」でした。
「Now is the time」は「今こそ〜するチャンスだ!!」と言う意味で、
VR元年には持ってこいのテーマでした。

当然、VRの特集企画「VR Now!」も組まれるくらいVRは盛り上がっていました。

なので、「今こそ”DB”をアピールするチャンスだ!!」と思い、発表してきました。
「VR」と「DB」を間違えてくれないかなと思いながら(笑)

冗談はさておき、セッションを受けに来てくれた方々はVRとDBを間違える事なく、
本当にDBに興味がある方々が集まってくれました。
自分が部屋へ入場すると同時に部屋が満席になり、立ち見も出て大盛況でした!!

自分にとって、すごく良い経験になりました。

このフォローアップ記事を見てCygamesに興味を持っていただけた方は、こちらの採用ページをご確認ください。

また、登壇のチャンスがあるのであれば、今回はショートセッションだったので、
次回は「レギュラーセッション」を狙って行きます!!!