2014年2月4日火曜日

【GAE】インスタンス時間3

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

只今、クラウド基盤「Google App Engine(以下、GAE)」の連載しています。

さて、前回の記事で、GAEの料金の中核は「フロントエンド・インスタンス時間」であることをご紹介しました。
Google本家の情報によると、一日200万プレビューくらいまでは無料で行けるそうです。

はてさて、本当にそんなレスポンスが出るのか、今回はちょっとDOSアタックを仕掛けて検証してみましょう。

負荷要件

さて、Googleの言う200万プレビューというのは、「効率が良いロジックである場合」の話です。
一回のリクエストが重ければ200万プレビュー無料は達成出来るわけ無いです。

この為、今回の負荷テストでは「標準的な効率的ロジック」に対し、多数のリクエストを投げる要件で検証してみようと思います。

具体的には、「テーブルの主キー検索1件」です。
一回のリクエストでテーブルの主キーを検索し、1レコードを取ってくるという処理は、
DBを使ったものの中でも最も標準的なものですからね。

この要件に対し、大量アクセスをかけて検証してみましょう。

1リクエスト速度

この負荷要件の場合、「1回のリクエストは何秒なのか?」が重用になります。

GAEだと、1リクエストの時間は標準でログに出力されておりまして、簡単に正確な時間が分かります。
それがこれ。



  • ms=26

何と、1リクエストで26msです!!

これは速いですね。
ちなみに、GAEの場合、どれだけデータ量が増えても主キー検索の速度は変わりませんので、安定してこの速度が出せます。

では、この要件で負荷テストを実施します。

アタックバッチ

DOSアタックには、私が自前で作ったマルチスレッドのリクエスト送信バッチを使います。
指定本数だけリクエスト送信スレッドを立てて、無限ループでリクエストを送りまくるという単純なバッチです。

1スレッドの時は、同時に1ユーザがアクセス中。
10スレッドの時は、同時に10ユーザがアクセス中。

と見なすわけです。

お見せする程の価値のあるソースではありませんが、一応以下に張っておきます。

public class DosAtackBatch extends AbstractBatch {

   /** logger */
   private Logger logger = Logger.getLogger(DosAtackBatch.class);

   /** 送信先URL */
   private String URL = "http://genesis-gae-service.appspot.com/webapi/develop/SpinUpTime";

   private int threadCount = 1;

   private int attackTime = 30000;

   private static AtomicInteger count = new AtomicInteger();

   /**
    * @param args
    * @throws Exception
    */
   public static void main(String[] args) throws Exception {

      DosAtackBatch batch = new DosAtackBatch();
      batch.excute(args);

   }

   /*
    * (非 Javadoc)
    *
    * @see jp.co.tacy.batch.AbstractBatch#doExcute(java.lang.String[])
    */
   @Override
   public void doExcute(String[] args) throws Exception {

      final Date dateBefore = new Date();

      for(int i=0;i<threadCount;i++){

      Thread thread = new Thread() {
            /*
             * (非 Javadoc)
             *
             * @see java.lang.Thread#run()
             */
            @Override
            public void run() {

               while (true) {
                  RequestSender sender = new RequestSender();
                  try {
                     sender.sendPost(URL, null);
                     Date dateAfter = new Date();

                     long responseTime = dateAfter.getTime() - dateBefore.getTime();

                     logger.info("アタック回数:" + DosAtackBatch.count.incrementAndGet());
                     logger.info("レスポンス時間:" + responseTime);

                     if(responseTime > attackTime){
                        break;
                     }

                  } catch (IOException e) {
                     logger.fatal("エラーが発生しました。", e);
                  }
               }
            }
         };

         thread.start();
      }

   }

}

計測:1スレッド

では、このバッチを使ってアタックをかけてみます。

  • スレッド数:1
  • 実行時間:30秒
  • リクエスト総数:108回

結果はこの通り。



1インスタンスしか上がっていません。
まあ、1スレッド=1ユーザという想定ですから、1ユーザしかアクセスしていないのであれば、1インスタンスで足りるのは当然ですね。

計測:10スレッド

次は、一気に10ユーザ行ってみましょう。

  • スレッド数:10
  • 実行時間:30秒
  • リクエスト総数:1024回

どうやら私の作ったバッチは10スレッドを立ち上げても、1スレッド辺りのパワーは落ちないようです。
それなりに良いPCを使わせて頂いております。(^_^)

さて、肝心の結果ですが、何とこれでもインスタンス数は1コでした。
  • 10ユーザがF5アタックしているような状態でもビクともしない!!

計測:20~25スレッド


「性能が凄いのは分かったから、いつになったら変化するんだよ?」

という感じでしょうから結論を述べますと、25スレッドで変化が出ました。

  • スレッド数:25
  • 実行時間:30秒
  • リクエスト総数:2104回

25スレッドで実行すると、インスタンスが2つ立ち上がります。



流石に25スレッドともなるとPCの性能が追いつかなくなってきて、1スレッド辺りのパワーが下がってきているようです。

なので、多少数値が曖昧ですが、概ねの性能が出て来ました。

  • GAEは、20~25人のユーザがF5アタックしているような状態まで、1インスタンスで対処することが出来る。

キリの良い20スレッドで再計測しましたら、以下の実績で1インスタンスでした。

  • スレッド数:20
  • 実行時間:30秒
  • リクエスト総数:1564回

というわけで、この20スレッドの数字が1インスタンスの上限値と位置づけて、算出してみようと思います。


  • 30秒で1564リクエスト
  • 1分なら1564×2=3128リクエスト
  • 1時間なら3128×60=187680リクエスト
  • 1日なら187680×24=4504320リクエスト
  • 1ヶ月なら4504320×30=135129600リクエスト

1日で450万、1ヶ月で1億3000万リクエストまで無料!!

という概算見積もりとなりました。


まとめ

さて、私の計測結果だと、Googleの主張する1日200万プレビューの2倍以上の実績を叩き出してしまいました。

まあ、私がテスト用に作った機能は超軽量ですから、現実的にはもうちょっと重くなるのが普通でしょう。
となると、1日200万プレビュー無料という謳い文句は、妥当な数字であると言うことが出来るかと思います。

結論としましては、

  • GAEは1日200万プレビューまで無料まで実現可能

をキャッチフレーズにしても問題は無いのではないかと。

ただし、この数字はザクッとした見積もりですので、現実にプロジェクトとして導入するなら、もうちょっと細かく計算したいです。

私の計測の場合、1リクエストの処理時間が26msで1日450万という結果でした。ここから比例計算で、

  • 1リクエストの平均が26msの場合:450万
  • 1リクエストの平均が58msの場合:200万
  • 1リクエストの平均が100msの場合:116万
  • 1リクエストの平均が1000msの場合:12万

みたいな感じに算出することが出来ます。
各自、自分の作ったアプリの1リクエストの時間を見て、そこから上の比例計算で割り出してみると良いかと思います。

終わりに

今回の解析で、GAEのコスト効率が概ね見えてきましたね。

ちなみに現在、私はこのブログと平行して社内用を想定したアプリを作っているのですが、一番重い処理でも1リクエストの時間は200msです。

ここから考えて、

  • GAEに最適化した要件であれば、1日200万アクセスまで無料
  • 多少のカスタマイズを入れた業務用アプリなら、平均して1日50万アクセスくらいまで無料

これくらいが現実的な見積もりなんじゃないかと思っています。

それ以上になると有料になりますが、その場合は1時間当たり0.08ドルですから、
業務用としてWebサイトを運用する場合、

  • 1日50万アクセスくらいまで無料。
  • 1日100万アクセスなら毎月5000~6000円くらい。
  • 1万円出してくれれば1日120~130万アクセスくらい行けそう。

という予算感覚です。

こりゃ安いですね。
ビジネスモデルとしての展望が見えてきそうな感じです。

この先もまだまだ気合い入れて勉強していきたいと思います。

0 件のコメント:

コメントを投稿