狠狠撸

狠狠撸Share a Scribd company logo
失敗事例にみる
DBの負荷試験の重要性
株式会社マーベラス 開発本部開発部OL開発部
チーフアーキテクト
大西一嘉
自己紹介
大西一嘉
株式会社マーベラス 開発本部開発部
チーフアーキテクト / DBアーキテクト
職業:提督でありエンジニア
趣味:艦娘たちを愛でる
他にもNYの地下にもぐったり、
蠣崎氏で全国統一したり、
全米や全欧で運送業を営んだり、
フォーリナーの撃退をしてます
目標:全艦娘コレクション
目標達成まであと4名
弊社紹介
オンライン?コンシューマなどのゲームからアニメ?舞台など、日本の置けるエン
ターテイメントを網羅する総合エンターテイメント企業です。
ゲームタイトルにおける負荷
ユーザビリティに重きを置くゲームタイトルにおいて負荷とは、非常にクリティカ
ルな問題となります。負荷によって引き起こされる問題としては???
? レスポンスの遅延による厳しい苦情
? 登録?変更の反映不能によるデータ欠損
? そもそもゲームができない
ゲームタイトルは、ユーザにより支えられている側面が他のWEBシステムより
強いため、負荷によるユーザ不利益はそのまま収益につながります。
負荷による弊害
タイトルをリリースした後で問題が発覚しては、事態は一刻の猶予もなくなり、
運用と原因究明、対処法の確立を同時進行で進める必要が出てきます。
負荷遅延からの一時対応、そして事故のループは、ユーザの離反につながり、
最悪ゲーム自体の一時停止や終了につながり、収益を上げるどころか、反対
に損益しか出なくなることもあり得ます。
そうなると、当然事故の確立も上がります。
そのためも、事前の負荷試験での
問題点の洗い出しが重要になります。
限界や兆候を知ることが重要
漫然と負荷試験を行っても意味がありません。負荷試験で知るべき内容は3つ
です。
? 想定負荷に耐えられる事
? システムの限界点を知る事
? システムが限界点を迎える前に出る兆候を知る
事
想定負荷に耐えられる事は当然ですが、システムの限界点を知ることでサー
バ増設?減設計画が立てやすくなりますし、急な負荷がかかったとしても、兆候
が出ていなければ対応までの時間が稼げます。
今後の運用に余裕を持つことができるようになります。
負荷試験において重要な事
負荷試験で重要なことは、負荷をかける環境を可能な限り本番運用状況に近
づけることにあります。
システム構成
データ構成
ユーザの挙動
この3つを本番に近づけることで、より完成度の高い負荷試験となり、本番で起
こり得る状況をよりつかめるようになります。
では、弊社で起きた負荷試験起因の失敗事例を見ながら、
負荷試験が重要であるかを覚えていただければと思います。
弊社における失敗事例①
某ゲームポータルSNSの運用を行っていた時の出来事です。ゲーム部分の負荷試
験が十分に行っていました。ですがゲームポータルSNSは、すでにあるフリーのSNS
ソースを改修して作成しました。フリーのSNSソースは過去事例において十分に実績
があったので、負荷試験を省略した事例になります。運用1か月後ぐらいで、現象は
発生しました。
某ゲームポータルSNSの場合
ログインできない
他での運用実績も高いフリーのSNSソースです。まさかログインできないなどという
状況に追い込まれるとは思わず、原因究明は捗りません。その間にもユーザからの
問い合わせは激しくなる状況でした。
ゲームサーバ
OpenPNE WEB
MySQLクラスタ
弊社における失敗事例①
サーバ構成(ざっくり)
処理数からMySQLではさばき
きれないため、当初から
MySQLクラスタを使用して、処
理クエリ数を稼ぐ構成です。
クエリ自体も、単純なクエリしか
ない想定だった。
弊社における失敗事例①
諸所の状況を整理し、どうやらピークタイムはほぼログインできず、オフタイム時には
かろうじてログインできることが判明しました。となると、問題点はSNSの負荷試験で
洗い出せそうです。負荷試験のため、以下の環境を用意しました。
負荷試験による原因調査
負荷環境は、MySQLクラスタとWebサーバのみ、データは本番データからダンプした
データを用意、負荷サーバを起動し、ログインだけの負荷試験をアクセス数を増やし
ながら実施しました。
? 本番環境の最小システム構成
? 本番と同等のデータ
弊社における失敗事例①
負荷を掛けつつ、モニタ監視を行い状況を確認したところ、2つの事が分かりました。
実施結果
同時10アクセスぐらいでもう駄目っぽい
内部転送量がとんでもない数字
どうやら、ログイン時にMySQLクラスタのSQL-データノード間の転送量が多く、詰
まっているようでした。
ログイン時に取得するデータはユーザ情報だけですし、その後遷移するマイページ
で使用するユーザ情報とコミュニティ情報に各種お知らせぐらいですので、 SQL-
データノード間にてそんなにも多くのデータが転送されてしまうのが不可解でした。
弊社における失敗事例①
SQL-データノード間での転送量がネックになっている以上、原因はSQL周りにある
はずです。そのため、一つずつ使用しているSQLを外して、ログインを繰り返し、問題
になっているであろうSQLをあぶり出します。あぶりだした結果、一つのSQLを発見し
ました。
原因判明
SELECT * FROM t_community_user AS tcu
JOIN t_user AS tu ON tcu.user_id = tu.user_id
※ウロ覚えですが、ログインするたびに全コミュニティに紐づくユーザのログイン状況を取得するというものだったのは覚えてます。
そりゃ転送量喰うよ、全データだもの。
MySQL Clusterで絶対やったらダメなパターン
弊社における失敗事例①
反省点
? 「すでに安定稼働しているよ」という言葉を信じ
て、負荷試験を省いてしまった。
? 負荷試験さえすれば、発見できた問題だった。
? MySQL Clusterの特性を当時知らなかった。
? 全てのSQLについて負荷チェック?スロークエリ
チェックするべきだった。
弊社における失敗事例②
リリース前に負荷試験を十分に行ったが、リリース後のユーザ流入に耐えきれず、
データ破損の上でサーバダウン。最終的にサービス停止を行いシステムの立て直し
を図った例です。現象は以下の通り。
某ゲームの場合
? NoSQLクラスタがドミノ式にサーバダウン
する
? ドミノダウンの影響でBASE特性が悪影響
に働きデータが欠損した
この話を聞いたとき、使用しているNoSQLが低レイテンシで障害時も何らかの反応を
返すはずのものだったので、ある程度の驚きを隠せませんでした。
1
5
3
2
1
4
3
2
5
4
3
1
5
4
2
①アクセス集中
14
1
①アクセスが
集中しNo1
ノードダウン
②No4ノードがバック
アップを持っていたの
で復旧したが、アクセ
ス集中でダウン
③No2ノードがバック
アップを持っていたの
で復旧したが、やっぱ
りアクセス集中でダウ
ン
弊社における失敗事例②
ノードダウンの状況予測
予測したノードダウンの状況は、典型的なアクセス過多によるものだろうと思ってい
ました。ただ疑問点は残ります。何故1ノードだけに集中したのか?仮にノード集中し
たとしても、ドミノが止まらなかったのはなぜか?
負荷試験の内容に問題があったのでしょうか?事前の負荷試験では、十分にユー
ザの動きをトレースした試験が必要になるはずです。
今回の事例ですと、左図のように事前では平均負荷で負荷をかけていましたが、実
際の動きは右図のように、1データに集中する動きをしていました。そして、この動き
はチュートリアルやゲーム個別の仕様書に書かれていました。
データ
データ
データ
データ
データ
データ
データ
データ
データ
データ
データ
データ
データ
データ
アクセス
アクセス
アクセス
アクセス
アクセス
アクセス
アクセス
アクセス
弊社における失敗事例②
アクセス集中に対する負荷シナリオが不十分?
さて現状は分かったので、プロジェクトタイトルの立て直しの方針を決めます。
という制約がほぼトップダウンで決定されているため、選択肢は運用実績が高く且つ
確実に組めて修正が最小限に抑えられるであろうMySQLによるシャーディングに確
定、後は物理性能で抑え込むという方針が確定されました。
弊社における失敗事例②
プロジェクトの立て直し
? NoSQLクラスタは悪くないだろうけど、ほぼRDBMS
への変更が確定
? MySQL Clusterは、運用実績とクラスタという名前で
NoSQLを連想するのでダメ
? 1か月以内に無事故で再開
ユーザデータ(NoSQL)マスターデータ(MySQL)
WEBサーバ群
ログDB(MySQL)
弊社における失敗事例②
当初の構成(ざっくり)
WEBサーバ群
マスタ(MySQL) ユーザ(MySQL) ログ(MySQL)
Memcached
弊社における失敗事例②
変更後の構成(ざっくり)
構成変更とPHPの修正を行い、再度負荷試験を実施します。今回はリリース中のア
クセスログを参考にユーザの動きをチュートリアルを含めて再現しました。
弊社における失敗事例②
シナリオ負荷試験の実施
? 新規登録
? チュートリアル
? その後アクセスログから推定されるユーザの動
きを高速で永久ループ
以上の動きを再現したJ-materシナリオを作成し、負荷サーバを100台ほど並べて負
荷を掛け、落ちた状況を再現します。このシナリオで、登録からヘビーユーザまでの
流れを再現しつつ、現構成で問題ないことを確認していきます。
徹底的に無慈悲な負荷をかけることで、今回の障害における問題点が見えてきまし
た。
弊社における失敗事例②
負荷試験の結果
? WEBサーバリミテッドなシステムである
? DBコネクション数が異常に増大する
瞬間的にMAXまで食い尽くす。300でも3000でも30000でも
? 増大したコネクションエラーの発生により、WEB
のLAの暴走が始まる
? MySQLサーバの負荷はスカスカ。いくら負荷を
かけても快調そのもの
弊社における失敗事例②
とある瞬間に一気にMAXコネクションまでコネクション数が増えるのは明らかに異常
です。となると調べる部分はコネクション部分のコーディングになります。ソース解析
チームと共同でソース分析を行うと、とんでもないコードを見つけました。
原因判明
接続が失敗した場合、再接続する。
なお接続が確立するまで、
接続シーケンスを繰り返す。
コネクション閉じずに接続要求繰り返したらそ
りゃ喰いつくすよな、普通。
弊社における失敗事例②
反省点
? データ密度?アクセス密度を適切に見積れずに、
最初の負荷試験において平均的に分散させて
しまった。
? 負荷試験におけるユーザ行動シナリオが甘
かった。
? NoSQLの知見が足りてなかった。
? DBMSへの接続コーディングにおいて間違った
知識を有していた。
負荷試験でわかる事
このように負荷試験をかけてわかることは、そのほとんどの場合において
DBMSは悪くない!ということです。負荷の起因は、そのほとんどがコーディン
グやSQLによって引き起こされており、コーディングやSQLを改善するだけで、
負荷はかなり軽減されます。
システムや設定のチューニングに力を注ぐよりも
システムコーディングの見直し
SQLやINDEXの見直し
を行った方が効率的な負荷軽減になります。
まずはあわてずにコードを見直しましょう。

More Related Content

失败事例にみる顿产の负荷试験の重要性