Continuous Ops

Exploring the world of 'Infrastructure as Code'

AWS Summit Tokyo 2014: AWS + Windows(C#)で構築する.NET最先端技術によるハイパフォーマンスウェブアプリケーション開発実践

ソーシャルゲームデベロッパーのGraniの河合さんによるC#のウェブアプリケーションの解説です。

私はWindowsでアプリケーションを書いたことも運用したこともないのですが、かなり昔にMS-DOSでシステム管理は少しやったことがあるので、Microsoftの技術には愛着を持っています。

一番驚いたのは、C#の機能をを活かして処理をほぼ非同期で行っているというところでした。 PHPなどでは絶対無理な処理なので、これはすごいなと。 私のプロダクトでやるならScalaになるのでしょうが、ここまでの境地に達するのはよほど言語に精通していないといけない気がします。

ソーシャルゲームのレスポンスで全て100msecを切るように返すことの大変さは分かっているつもりなので、レベルの違いを感じました。 Redisのパイプライン処理いいですね。

とにかくクールだなと思いました。ひたすら感心。

門外漢のC#やWindowsの話をあえて聞いてみてよかったです。

  • AWS + C#によるウェブソーシャルゲーム
  • C# 50%, AWS 20%, その他 30%ぐらいの話
  • AWSだからといってC#を使うのに特別なことはない

using CSharp;

  • C#の開発にとことんこだわっている
  • もとはPHPだったが開発効率に不満を感じた
  • 半年後にC#に全面移行
  • AWSを使っていたのでそのまま移行した

  • クライアントサイドからサーバーサイドまで全てをC#で!

AWS + C#は全く問題ない。

  • 100 server
  • 10000 req/sec
  • 1000000000pv/day

IIS8 + RDS + Redis(r3.2xlarge)20台

なぜRDBMSを選択するのか

  • NoSQLでいい?けれど複雑化をおさえたい
  • RDBMSは単純なクエリなら1msec以下で返すがDynamoDBは・・・
  • 周辺ツールが充実
  • スケールアップや分割で対応できるなら、スケールアウトに固執することもない

何よりRDSが良い

手放し管理、Restore To Point in Timeには救われた

  • SQL Server vs MySQL
    • C#としてはSQL Serverのほうが相性はいい
    • しかしRDSとしてみるとSQL Serverは貧弱
    • 今はあるがMulti-AZも無かったし、ProvisionedIOPSの限界値も低かった
    • 結果、MySQLを使っている

r3.8xlargeが最強

垂直分割 vs 水平分割

機能単位の垂直分割を採用

水平分割は避ける: 記述可能なクエリに大きな制限がかかってしまう アドホックなクエリでの集計が不可能になる ほとんどのアプリケーションは、水平分割をする必要はないのでは?

DB管理はGUIで HeidiSQLがおすすめ phpMyAdminやCUIは積極的にdisりたい

アプリケーションからはMasterのみ参照 いまどきのRDSは十分パワフルなので、Slaveに分散するのは無用な複雑さを生むだけ レプリケーション遅延は起きるので。

同一AZに配置する AZを越えると普段0.5msec程度のクエリが2msec程度になる

C#的な活用としては、コネクションを型で分けるとコンパイルでチェックできる 生のSQLを書いている

テーブル定義から自動生成 テーブルと1:1でひもづいたクラスがある T4テンプレート + ADO.net

半自動生成くらいの位置づけ

  • 全階層でのキャッシュの徹底

    • データベース
    • Memcache-Redis
    • Static変数: アイテム名など不変の情報はキャッシュ 
    • リクエスト単位

アプリケーションコードによるJOIN

LINQ to Objectsで簡単。SQLよりもずっと楽

Redis

RDSの不得意な部分を補える 高パフォーマンスなのでMemcached代わりのキャッシュ用途に 用途ごとのグループ分けと単純分散

Master Slave構成をとっている dump出力時にCPUをくうので

ElastiCache Redisは試したときにパフォーマンスがでなかったので使っていない

Protocol Buffersを使っている 高速・省サイズなので

Performance + Async

100msecを切るように作っている C# 5.0を活用

言語構文レベルでサポートされる非同期 同期と同じように非同期が書ける Graniではコード全体が非同期で書かれている

Redisならパイプライン化可能 全てが非同期で自動でパイプライン化される

性能と設計を両立できる

Log for performance

外部通信を全て記録する アプリケーション側で送信前後をフックして記録 後述するGlimpseやSumo Logicで解析する アプリ側でやると負荷がない

Glimpse – 可視化

全体の実行時間のほか、あらゆるメトリックスを常時可視化 http://getglimpse.com

Explainの常時表示 手動でExplainはやらない Redis送受信の表示

日常的開発

Git + GitHub Jenkins DeployはValentia(自社ツール)

Sumo Logicでログ解析 New Relicでモニタリング

Semantic Logging + Redshift + Tableau http://slab.codeplex.com

まとめ

  • C# + AWSは現実界
  • 構成は堅く、シンプルに
  • 環境は常に最新に