Upgrade to Pro — share decks privately, control downloads, hide ads and more …

大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~

 大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~

2012年のオープンソースカンファレンス北海道(OSC-do)でセミナー発表した際に使用したスライド資料です。

Infiniteloop

July 12, 2023
Tweet

More Decks by Infiniteloop

Other Decks in Programming

Transcript

  1. Q. で、最近どうなの??(1) A. 以前と比べるといろいろ起きているかも? ソーシャルゲームがニュースで話題になることが増えた → ドリランド増殖およびそれに付随するRMT問題 → コンプガチャ騒動 →

    なんだか世間の風当たりが強くなった → 後ろめたいものを作っているつもりはない → エンジニアとしては技術に集中したい 実際の影響は、今のところ無い → 特に自分の周りに関してはあまり影響が無いようだ → ただし周りの全然ソーシャルゲームに興味がなかった人までが、  「大丈夫?」と聞いてくるという影響が
  2. Q. で、最近どうなの??(2) 開発者から⾒た最近のソーシャルゲーム開発 スマホが主戦場になってきている → ネイティブアプリはもちろん、Mobage・GREEも → ガラケー界隈は少し落ち着いて来た印象 → PC向けのゲーム(主にFlashを使用)は安定した需要

    やっぱり全然人は足りていない → クライアント・サーバ・インフラなど全てが足りない → DBA(DataBase Administrator)が重宝される → HTML5+JSエンジニアのニーズが増えそう → とはいえ二極化が始まり、なんちゃっての業者/エンジニアは   そろそろ淘汰されはじめるかも
  3. Q. で、最近どうなの??(3) 少しずつ変わっていくソーシャルゲーム開発 役割の変化 → 開発規模の拡大に伴いエンジニア求められるものも変わってきた → 役割分担の明確化(エンジニア≠企画、餅は餅屋に、歴史は繰り返す) 求められる能⼒ →

    継戦能⼒(続く運営・アップデート、終わりがない) → 情報の横への共有化、他者/他社への展開能⼒ → 安定したリソース提供、⻑期を⾒越した教育スキームの確⽴ → 海外展開能⼒ ソーシャルゲーム以外への応用も → 高負荷Webサービスへの回帰、ゲーミフィケーションへの応用 → 従来のコンシューマーゲームのネット化とそのバックエンド開発
  4. Q. インフラはどうしていますか?(1) A. 最近では国内のクラウドサービスを利⽤しています GMOクラウドを使うことが多いです、あとはAWS (ステマじゃないです) 【インフラ選びは非常に大事!!】 こんなポイントを⾒て選んでいます → コストや安定度(障害履歴)は当然⾒る

    → 共有LBがあり、それが強⼒であること → インスタンスの追加が容易で速いこと(電話やメールとかは論外) → ディスクへのI/Oが速く安定していること → ⾼価でも強⼒なスペックのインスタンスが⽤意されている、   または物理マシンとの併⽤が可能(最後の⼿段的な使い⽅)
  5. Q. 言語やフレームワークは何をつかっていますか A. 言語は主にPHPを使っていますが、 何でもいいと思います。フレームワークは自作です 開発言語 → PHP, Perl, Rubyあたりをよく聞く

    → 得意な言語でよいと思うが、開発リソースの補充や、   新⼈教育が容易な⾔語が向いている フレームワーク → 自作フレームワークを使っている → 以前はあえてのベタ書きだったが、開発効率や再利⽤性など   の⾯からフレームワークを作成し利⽤するように → symfonyなどの既存フレームワークを改造して使っている   などの話しも聞くが、最終的には魔改造されているようだ
  6. Q. 負荷テストはどうしていますか?(1) A. JMeterを使ってやっています まずはテストプレイなどから数値目標を⽴てる ・予想される同時接続数 ・1ユーザが1プレイで操作する時間 ・1ユーザが1分間に⾏うリクエストの数 【例】 同時接続数:

    10000人(同時接続数とは1時間で接続があったユニークユーザ数とする) 1ユーザが操作する時間: 10分操作し続けて離脱と想定 1ユーザが1分間に⾏う平均リクエスト数: 5回 → 10分間の同時接続ユーザ数: 10000 / 6 = 1667ユーザ  → 1分間にリクエストされる回数: 1667 * 5 = 8335回   → 1秒間にリクエストされる回数: 8335 / 60 = 139回 = 平均「139リクエスト/秒」を満たせればよい
  7. Q. 負荷対策はどうしていますか?(2) 実際に使われている負荷対策チェックリスト 【共通処理編】 (1) 共通処理内で何をしているかを全て把握しているか → どういう処理が⾏われるか、SQLは何回流れているか、などを完全に把握すること → 共通部分に処理を⾜すときは、かならずチーム内で許諾を取ること

    (2) そもそも、その処理は本当に必要なのか → 最も効果的な負荷対策は、処理の速度を速めるより処理⾃体を無くすことである → 特にクライアント - サーバ型のアプリの場合は、相当処理が削れる → クライアント側でキャッシュや処理できるような処理がないか⾒直す (3) キャッシュはできないか → APCキャッシュ > memcache >>>>> MySQL の順で速い (APCはWebサーバ単位でのキャッシュであることに注意) → 共通処理内では、SQL実⾏回数がゼロが望ましい
  8. Q. 負荷対策はどうしていますか?(3) (4) 無駄なものの発⾒ → 無駄なrequireを潰すにはオートロードの導入が楽 → XHProfのcallgraphでチェック → Jenkinsや自作スクリプトで、

      無駄な定数や使われていないメソッドなどを掃除 (5) その他注意点 → ロガーやエラーハンドラなど、思わぬところがネックになることもあるので、   呼ばれる回数が多いものは、必ずチェック&チューニングすること → $_SESSIONの利⽤は最低限に留めること
  9. Q. 負荷対策はどうしていますか?(4) 実際に使われている負荷対策チェックリスト 【個別処理編】 (1) 遅いPHPランキングを作る(モグラ叩き法) → 実⾏速度を記録する仕掛けを作り、最も遅くて呼ばれる回数の多い順に対処 → Apacheログからanalogなどで集計する方法も

    (2) SQLの⾒直し → 遅い場合のほとんどはSQLが原因で遅い(アプリロジックでの負荷軽減は難しい) → 実際の本番とデータ数が違うと参考にならない、データは常に多めに入れておくこと → インデックス未使用のクエリやスロークエリログに載ってくるクエリを潰す → mk-query-digestで早くても実⾏回数の多いクエリを発⾒しチューニング → cactiなどのグラフから問題を発⾒する (3) 仕様で⾒直す → 仕様をほぼ満たしつつも、影響なくルーズに作れるところがないかを常に検討 → どうしてもダメなら仕様の⾒直しを相談
  10. Q. 負荷対策はどうしていますか?(5) DBマスターの負荷対策 負荷対策の基本は「サーバ台数を増やして対処すること」である。 ただしWebサーバやDBスレイブは、台数を増やすことで対応できるが、 DBマスターは単純には増やすことができないため、ここがネックとなる。 よって、負荷をなるべく他のサーバに分散する必要が出てくる KVS(memcachedなど) に向ける →

    情報が古い可能性があることに注意、トランザクション処理にはあまり使えない DBスレイブに向ける → 通常はスレイブに接続し、トランザクション開始(BEGIN)でマスターに接続する  (フレームワークレベルで実装) → マスターオンリーで開発を進め、安全なクエリから順にKVSやスレーブに   振っていくやり方も → インフラの構築方針にも絡んでくる
  11. Q. 負荷対策はどうしていますか?(6) DBマスター分割 複数ワールドに分けられないタイプのゲームや、同時収容人数の 多いゲームの場合、マスター分割は避けて通ることができない。 垂直分割 → 切り離しやすいテーブルを他のDBに持って⾏く(例:掲示板だけ別DB) 水平分割 →

    ユーザID単位で分割する → グローバルDBを持ち、そこにユーザIDと格納DBを記録したテーブルを持つ → 新規登録時には最もアクティブユーザ数の少ないDBに登録 現状はアプリ側で複数のDBを順にトランザクション開始⇒コミットしている → 分割DBが多くなるほど性能が劣化する → バックアップ時の整合性や、エラー時の処理が⼤変 → ユーザ間の関わりが強いようなアプリは作りづらい → MySQL Clusterに期待したい
  12. Q. 負荷対策はどうしていますか?(7) ロック競合対策 負荷はかかっていないがパフォーマンスが出ない、 Lock wait timeoutが多発する、などの場合はロック競合を疑う マスター分割されている場合は、 デッドロック検出がされないので更に厄介 【対策】

    トランザクション時間は可能な限り短く → アプリ側に検出の仕掛けをいれている → MySlowTranCaptureなどのツールを活用 ロックが多くかかるテーブルは細かく分ける → ⾏ロックをかけるので、2つのポイントを同時に更新できない → ポイント系のテーブルなどで陥りがちな罠 user_point_tbl ・user_id ・energy_point ・battle_point user_energy_point_tbl ・user_id ・energy_point user_battle_point_tbl ・user_id ・battle_point × ◦
  13. Q. 参考にしている情報は何ですか?(1) A. 愛読書をご紹介します ・Webエンジニアのためのデータベース技術[実践]入門   松信嘉範氏著  → 後半、特に12章はソーシャルゲーム開発者は必読 ・エキスパートのためのMySQL[運用+管理]  トラブルシューティングガイド 奥野幹也氏著

     → 通称「鍵本」、ロックを理解するのにオススメ ・Mobageを支える技術 〜ソーシャルゲームの舞台裏〜   DeNA著  → 出たばかり、まだ読めてないけど超期待 技術書以外だと ・雑誌としてWEB+DB PRESS、SoftwareDesign ・とりあえず、はてぶの「コンピュータ・IT」カテゴリは全部⾒てます