« 第14回 yokohama.rbに参加しました。 | トップページ | Mongoidの限界について »

2011年11月15日 (火)

MongoDBをアプリで使う時に気をつける点

ソーシャルゲームのアプリにMongoDBを使っていて困った点

1. joinがないため、マスタデータの参照が多いページのレスポンスが遅い

2. 複数collectionにまたがって更新が必要な場合に、ShutDown,バグ等により中途半端にコレクションを更新して、データの不整合が発生することがある。

3.集計関数には、MapReduceを使う必要があるが、リアルタイムで行うには負荷が重い。

4. Mongoidがレースコンディションに弱い。
a.条件を指定した更新ができない。
b. incとpushを同時に行うとようなAtomicな操作を行えない。
c. HashやArrayに対して、pushではなく、全体をセットしてしまう。

上記の弱点は、1作目で発覚したため、2作目以降は下記の対応を行った。

1.に関しては、マスターデータをMongoDBに格納するのではなく、Hash形式にしてAmazon:S3にUploadして、Webサーバ起動時にS3からDownloadして参照できるようにした。
わざわざS3を使う訳は、管理画面でマスターデータを登録するようにしているため。管理画面でデータの更新をするとそのデータがS3にUpされるので、次回のWebの起動時に反映される。

2.に関しては、Embeded Documentを活用し、なるべく1つのDocumentで更新が完了するよう心掛けた。
また、どうしても複数Documentの更新が必要な場合は、updateをsafe=>trueで呼び出し、確実に更新されたことを確認した後次のDocumentを更新するようにし、Documentの更新が途中までしか進まなかったとしても、対応可能なように設計。
例えばアイテム購入の場合は、アイテム所持情報にアイテムを追加し、ユーザ情報の金額を減らすという2つのDocumentの更新になるが、まずアイテム所持情報を更新の完了を確認してから、ユーザ情報の更新をするため、たとえユーザ情報の更新失敗しても、ユーザには不利益がでないようになるなど。

3.に関しては、AWSのSimpleDBはKVSでありながら、集計関数も使えるため、simpleDBを使用。集計関数を使いたい箇所はランキングなため、SimpleDB用のランキング用のライブラリを作成した。
ranking-simpledb
ただし、遅い。largeインスタンスでTop10表示が5.49req/sec。Topのみだと16.32req/sec。
理由は、Webサーバ側のCPU負荷。負荷試験をすると、CPUは次の値。user:67.55%,nice:0.0%,system:2.32%,iowait:0.0%,steal:27.98%,idle:2.15%
Webサーバを2台にすると、16.32req/sec→32.38req/secに
スループットが向上。

4.に関しては、更新時は、Mongoidではなく、Mongoドライバを使うようにした。

|

« 第14回 yokohama.rbに参加しました。 | トップページ | Mongoidの限界について »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/68673/53247963

この記事へのトラックバック一覧です: MongoDBをアプリで使う時に気をつける点:

« 第14回 yokohama.rbに参加しました。 | トップページ | Mongoidの限界について »