ソーシャルゲームデベロッパーの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は現実界
- 構成は堅く、シンプルに
- 環境は常に最新に