MongoDB:
Case Study for AMN
小山哲志@アジャイルメディア・ネットワーク
        @koyhoge
about me

‣ 小山哲志 - koyhoge
‣ アジャイルメディア・ネットワーク社員
‣ 合同会社ほげ技研 代表社員
‣ PHPユーザ会スタッフ
‣ 日本UNIXユーザ会幹事
‣ その他いろいろ
about AMN

‣ アジャイルメディア・ネットワーク株式会社
 ‣ http://agilemedia.jp/
‣ 2007年2月設立
‣ ソーシャルメディアマーケティング / キャンペー
 ン、イベント運営等
‣ 広告配信もやってます。今日はその話。
AMNパートナーブロガー

‣ 2007年に6ブログからスタート
‣ 2011年11月現在で91ブログ
‣ 他に Tweet アドネットワークが 16媒体
配信規模

‣ ブログアドネットワーク
 ‣ 月間 2000万 imps (公式)
‣ Tweetアドネットワーク
 ‣ 月間 2500万 imps (公式)
‣ 通常は 20∼120 req/s、ピーク時で 300
 req/s くらい
サーバ構成

‣ フロントWebサーバ2台
 ‣ Apache + PHP 5.3 + memcached
 ‣ フレームワークなし
‣ 静的ファイル配信用Webサーバ1台
 ‣ nginx
‣ DBサーバ2台(マスター/レプリケーション)
 ‣ PostgreSQL 9.0
Log! Log! Log!

‣ 広告配信なので表示数の記録はたいへん重要
‣ 以前は配信ログも PostgreSQL に記録していた
 ‣ AM 4:00 に集計バッチ処理が走る
‣ 2011年4月のサーバ構成変更時にログDBもマ
 スター/レプリケーションにしたところ、負荷に
 負け始める
PostgreSQLとの闘い

‣ パラメータチューニング
‣ 起動直後は安定して処理をさばく
‣ 数分∼数十分後(不定)に処理に負け始め、接続数
 不足に陥る
‣ cronで5分おきに再起動を仕掛ける回避策
‣ そうして逃げてる間に抜本的な解決策を探る
Key Value Store

‣ シンプルなデータを大量に保存するので、KVS
 向きだった
 ‣ ただし集計用に group by 機能が欲しい
‣ まずは AWS SimpleDB を試してみる
 ‣ すいません、クラウドサービス使いたかったん
  ですw
Amazon SimpleDB

‣ http://aws.amazon.com/jp/simpledb/
‣ AWSサービス群のひとつ
‣ PHP用の公式 AWS SDK があるのでそれを使う
‣ 使い方はすごく簡単
‣ SQLのような select 構文が使える
SimpleDBの結果?

‣ インサートが遅かった
‣ バッチ挿入も試したが少しましな程度
‣ 複数台に分散してインサートすると良い?
‣ ということでキュー (Queue) に入れることにし
 てみる
Amazon SQS + SDB

‣ Simple Queue Service
‣ REST APIでキュー/デキューできる
‣ 処理の流れ
 ‣ WebサーバからSQSにデータを突っ込む
 ‣ SQSから取り出してSDBに入れるワーカーを
  EC2でつくる
‣ ワーカーを増やせばスケールするんじゃね?
SQS+SDB?

‣ インサート速度は申し分なし
‣ PHPで書いたワーカーも無事に動作した
‣ 本番サービスにテスト的に追加
 ‣ PostgreSQL と同時に SQS にもログ保存
‣ 一日運用したコストが$130
 ‣ かなりお高いです...
いよいよMongoDB
‣ SaaS な KVS は諦め、ソフトウェアを探す
‣ MongoDB良さそうだったので、開発用の仮想
 マシンサーバ上にテスト環境を構築
 ‣ ReplSet 3 x Sharding 3 = 9台
 ‣ バージョンは当時の安定版 1.8.1
‣ Mongo用のPHPドライバも無事動作
‣ インサートすごく速い
‣ 負荷めちゃ軽い
MongoDBをEC2で

‣ AWS EC2上にMongoDBのテストベッド構築
‣ Microインスタンス3台で ReplSet
 ‣ ただしそれぞれのリージョンは分ける
 ‣ 東京A, 東京B, シンガポールA
‣ Shardingもやろうとしたけどうまく動かなかっ
 た
‣ ストレージは EBS 1TB
EC2テストベッド続き

‣ データ入力部分が出来たところで、本番データを
 流し始める
‣ Microインスタンスでも問題なく処理可能
‣ その環境をターゲットにバッチ処理部分の開発を
 進める
EC2 Smallの限界?

‣ ある程度バッチ処理の開発ができてきた
‣ Mongoに対しても、日時の集計処理を走らせる
 ようにcron設定
‣ 翌日集計は完了していたが、ReplSetの
 Primary が東京A → 東京B に変わっていた。
‣ さらに翌日には、Primary が東京Aに戻ってい
 た。
Primaryピンポン
‣ バッチ処理が走る
 ‣ groupを呼び出す比較的重い処理が複数
‣ Primaryが過負荷になってSecondaryの要求に
 応えなくなる
‣ S「Primary落ちてるんじゃね?」
‣ S「わーい投票投票」
‣ S(東京B)「俺近いし次プライマリーやるわ」
‣ P(東京A)「仕事をしていたらいつの間にかプラ
 イマリーではなくなっていた...」
本番環境はLargeに

‣ 御存知の通りMongoDBは 32bit Linux では実
 用にならない。
‣ EC2 Small インスタンスでは 64bit Linux は
 使えない。
‣ 自動的に Large 3台構成に
 ‣ 配置は Micro の時と同じ
‣ Large だとさすがにピンポンは起きませんでし
 たw
ある日のプライマリーさん
知見

‣ Shardingなしでも十分速い
‣ 大規模障害対策として、AWS 東京+シンガポー
 ルは使える
‣ シンガポールのSecondaryを見ても、ほとん
  ど遅れなく同期している
‣ JSスキーにとってはMongoかわいい
EC2使用料

‣ Large x 3
‣ CloudWatch (Monitoring)
‣ Reserved Instances
‣ 月額 $800 くらい
まとめ

‣ MongoDB のおかげで急激なトラフィックにも
 恐れること無く、枕を高くして眠ることができま
 す。
‣ doryokujinさんいつもありがとうございます。
‣ Fluent 使いたいです!
‣ Aggregation Mongo 使いたいです!!
提供
アジャイルメディア・ネットワーク株式会社

MongoDB: Case Study for AMN