backend(mBaaS)。採用していただいた、素晴らしいゲームアプリがリリースされました。もの悲しげ世界観、ロボット同士の殺し合いを見つめながら、孤独な宇宙へメッセージを送る...シルエットのやさしい見た目とは裏腹にハードな設定の「ひとりぼっち惑星」。リリース後数日で徐々に人気が加速し、ついにはストアの一位に到達するなど、非常に好調なスタートを切ったのですが...6/26(日)の夕方、急激なユーザー増加によりニフティのサーバーに巨大な負荷がかかってしまったため、サービスを一時停止する措置となってしまいました。ユーザーの皆さまにはご迷惑をおかけする形になり、申し訳ありません。その舞台裏と原因、対策についてレポートいたします。エヴァンジェリストとして様々なゲームアプリ開発者へ紹介を行っておりまして、「ひとりぼっち惑星」の作者、ところにょりさんもその一人でした。使っていたのですが....)実はリリースのすぐ後の頃に、ところにょりさん宛にインタビューの打診をしていました。「データストア」機能によって実現されていたので、ぜひ活用事例として広めたい、と考えていたからです。(インタビューは後編で公開します)。backendのテクニカルサポートと連絡を取りながら、原因究明に努めました。1日半後の6/28(火)昼過ぎ、ついにサービスの復旧をしていただくことができました。こえの送受信機能を使用するには、両OSともver1.1.1の最新アップデートに対応して頂く必要があります。ver1.1.0以前のバージョンではこえの送受信はできませんので、よろしくお願いいたします。2016年6月28日ところにょりさんは少し前から、ユーザーの増加に伴い有償のエキスパートプランに加入していました。一時停止をうけてテクニカルサポートが日曜の夕方には対応し、まずは改善案を提示、月曜にはソースコードをお預かりして詳細調査。夜には原因が判明したため、どんな手段がいちばん良いかを検討・相談して、午前中に反映。いうハイペースのサポートになりました。オプション機能を追加利用していただくことにより、ゲームの内容を変えることなく復旧しました。現在では同様のデータ量でも、安定した動作が可能となっています。重くなってしまった要因:count処理ユーザー数が非常に多くなったとはいえ、メインで扱っているデータは数百字の文字列です。これは「ボイス」という、ゲーム中のメッセージ送受信システムに当たる部分なのですが.....重くなってしまった原因は、データ送受信の流量やAPIコール数ではありませんでした。中にため込まれたデータを検索する処理に、データ件数に応じて重くなってしまう部分があったのです。データストア機能を使って保存するデータの種類を「クラス」としています。そのクラスの件数を取得するために「CountAsync」メソッドが存在しています。http://mb.cloud.nifty.com/doc/current/sdkguide/unity/query.html「count」の処理は、クラスの中から対象となるオブジェクトの数を数え上げる処理のため、数え上げるオブジェクトの数が多くなるに従って負荷が増加していきます。ユーザー数が爆発的に増えたことでこの処理が増大し、本アプリのAPIコールがいわゆる「スロークエリ」という状態になっていました。通常規模の個人開発アプリであれば問題ないのですが、ストア1位まで上り詰めると、同時接続数も検索するデータ量も途方もないものになってしまいます。今回の復旧が早かった理由として、iOS/Androidで配信直後だった最新バージョンでは、すでにこのcount処理を無くした修正が入っていました。元々はアップデートでユーザーさんを徐々に移行する計画だったようですが、旧バージョンを利用できなくして一気に最新版に乗り換えさせる形にしてもらいました。アップデート版(ver1.1.1以降)では、countを使用しない代わりに、order(ソート)を使用して必要なデータを取得する処理に代わっています。復旧後もより良いレスポンスでゲームを楽しんでいただくため、order処理をさらに高速化するべく、追加にて「インデックス機能」をご提案しました。http://mb.cloud.nifty.com/customize.htm#indexデータストアで頻繁に実施される検索・取得処理やソート処理がある場合、データストアの検索対象となるフィールドに対してインデックスを追加しておくと、処理が効率化され、レスポンスタイムを早くすることができます。利用方法としては、実は管理画面でクラスを指定し、どのフィールドにインデックスを付与するか設定するだけです。「クラス」以外にも、「会員クラス」にインデックスを指定することもできます。利用方法は下記にまとまっています。http://mb.cloud.nifty.com/doc/current/dashboard/addIndex.htmlこちらはカスタマイズプランになりますので、有償の機能になります。いうわけで、今回はアプリ実装面においての効率化(count処理→order処理)orderを高速化する有償オプション機能を追加の2通りの対策で、負荷を抑えることに成功しました。ご利用のゲームを開発中の皆さまには、countの処理はクラスに登録された全オブジェクトなど、たくさんのオブジェクトを数える使い方は多用しないようにしていただければと思います。countを使う場合は、まず検索条件などを付けることで、そもそも数え上げるオブジェクトの数を減らす対策が有効です。countはインデックス機能を追加して検索が速くなった場合でも、クラス内容の確認がある関係上、オブジェクトの数が増加するとパフォーマンスが落ちてしまうのでご留意ください。インデックス機能ですが、無料プランにおいても活用の術があります。システム側でインデックス済みのフィールドが存在し、それらは何も設定しなくとも、高速な検索が可能になっています。インデックス済みのフィールド一覧:データストアの場合、objectIdを使った検索であれば高速に処理することができます。今回の事例をオープンにしたのは、同じ方針の利用方法を考えているユーザーさんが同じ状況にならないように...と考えてのことです。backendは、ご利用されるアプリによってその活用方法も多種多様になります。今回の件も含めて、実装時の注意点についてまだまだドキュメントでご案内できていない部分もあるかと考えていますので、こちらは鋭意改善に努めたいです。ニフティでは、負荷上昇を可能な限り未然に検知し、改善をご提案する取組みもしていますが、異常な負荷が発生した場合は、そのアプリへのサービス提供を一時停止し、今回のようにすぐに改善に向けたテクニカルサポートを実施するようにしています。日本のサービスなので当たり前ですが、開発者さんへ日本時間で日本語のテクニカルサポートを行い、今後も一刻でも早くサービスが再開できるよう努めます。大ヒットゲームアプリ「ひとりぼっち惑星」の裏側~後編~※記事中のサンプルコード、説明の図式は2016年6月29日現在のものです。Service)とは、スマートフォンアプリでよく利用される汎用的な機能をSDKとクラウドから提供するサービスです。backendのちょっと便利な使いかた・非公式SDKやアプリ開発の関連情報などをお届けするブログです。※記事内には、サポート対象外の内容も含みます。本ブログではコメント機能を公開しておりません。アプリ開発を行う上での課題解決には、ユーザーコミュニティやもくもく会などもご活用ください。LIMITEDスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。