fbpx

MongoDBに必要なRAMを見積る #mongodb

はじめに

MongoDBテクニカルサポート担当の山森です。夏の終わりが見えてきましたね。そう思っていたら、これを執筆している本日、地元の気温が39度を超えたとニュースが出ていました。もう家から一歩も出たくありません。こんな時は用がなくても涼しいサーバ室に行きたくなります。

さて、システム運用を担当したことがある方なら、「このシステムに十分にRAMが足りているのか」を考えたことがある人は多いのではないでしょうか。私は、システムに必要なRAMを正常に見積もるには以下の3つについて知り、考慮する必要があると考えます。

  1. マシンに載せるアプリケーションがどのようにRAMを使うのかを理解する
  2. アプリケーションのハードウェア要件を知る
  3. OSにおけるRAMの扱いを知る

この記事では、MongoDBにおける1,2について、私が調査した内容をまとめています。ただし、3番についてはOSに関する内容であるため、今回は割愛します。私自身まだまだ勉強の途中であり、解説できる力量でないという、正直な理由もあります。

今回の話はセルフホストのMongoDBのみの話かと思われるかもしれませんが、Atlasでインスタンスを選定するときにも使える考え方です。

注意:今回はRAMにフォーカスした記事ですが、MongoDBパフォーマンスの低下の原因がRAM不足だけとは限らないことを事前に添えておきます。

MongoDBはどのようにRAMを使うのか?

MongoDBは複数の用途でRAMを使用します。メインはWiredTigerのキャッシュ、残りはソートや計算などのメモリ内操作、基盤のOSやその他のシステムサービスが使用します。

WiredTigerとは、MongoDBのストレージエンジンです。ストレージエンジンは、データベースからデータを読み出したり、書き込んだり、変更したりします。まさにデータベースの心臓部と言えます。MySQLではMyISAMやInnoDBにあたるポジションです。

WiredTigerのキャッシュとは具体的に何をしているのでしょうか。答えはMongoDB公式ドキュメント内の「Atlas Cluster Sizing and Tier Selection」にあります。

MongoDB uses the WiredTiger cache to hold most recently used data and indexes. The working set is the sum of all the indexes plus the set of documents that are accessed frequently. If your working set fits in RAM, then MongoDB can serve queries from memory, which provides the fastest query response times.

和訳:MongoDBは頻繁にアクセスされるデータとインデックスを保持するためにWiredTigerのキャッシュを使用します。ワーキングセットとは、すべてのインデックスと頻繁にアクセスされるドキュメントのサイズの合計です。ワーキングセットがすべてRAMに収まるならば、MongoDBはメモリからクエリを処理できるため、クエリの応答時間が最も早くなります。

ここでいうワーキングセットとはなんでしょうか?ワーキングセットは、一般的にはOSのメモリ管理で使われている用語のようですが、MongoDB内では「インデックス+頻繁にアクセスされるデータ」と定義しています。

デフォルトでは、RAMの50%をWiredTigerのキャッシュに割り当てます。つまり、ワーキングセットのサイズ < RAMのサイズの50% であれば良いわけです。

参考:WiredTiger - Memory Use

この章のまとめ

MongoDBは以下の用途でRAMを使用する。

  • WiredTigerのキャッシュ(デフォルトでRAMの50%を使用)
  • ソートや計算などのメモリ内操作
  • 基盤のOSやその他のシステムサービス

必要なRAMを見積る

MongoDBの公式ブログに、このような記事があります。タイトルは「Performance Best Practices: MongoDB Data Modeling and Memory Sizing」、今回の記事にドンピシャリなタイトルですね。このブログ内でも「Ensure your working set fits in RAM」、つまりワーキングセットがすべて載るぐらいのRAMを用意せよと言っています。

では、ワーキングセットのサイズはどう見積れば良いのでしょうか。これもMongoDBの公式ドキュメント「Atlas Cluster Sizing and Tier Selection」に確認方法と例が載っています。「Example: The Atlas Sample Data Sets」の章を見てみましょう。

This program returns the following results:

Obtaining stats for sample_airbnb
Obtaining stats for sample_geospatial
Obtaining stats for sample_mflix
Obtaining stats for sample_supplies
Obtaining stats for sample_training
Obtaining stats for sample_weatherdata
Total data size in GB: 0.32
Total index size in GB: 0.02

この例でのワーキングセットのサイズは、0.34GBです。WiredTigerのキャッシュがRAMの50%、そしてすべてのワーキングセットへのアクセスが常にアクティブであると仮定すると、必要なRAMのサイズは0.34×2 = 0.68 GBです。

公式ドキュメント内ではJavaScriptのプログラムを実行してtotalIndexSizeとtotalDataSizeを取得していますが、この2つの項目は、mongoshでもdb.stats()コマンドを使用することでも取得可能です。ただし、これは各データベースごとの値であることに注意してください。1つのインスタンスで複数のデータベースを運用する場合は、各データベースのワーキングセットを合計してください。

ここでいうデータベースの単位は、mongoshの「show dbs」コマンドで出てくるadminとlocal以外のことです。以下の例では9つのデータベースが存在しています。

Atlas atlas-2lwkkk-shard-0 [primary] test> show dbs
sample_airbnb        52.14 MiB
sample_analytics      8.88 MiB
sample_geospatial     1.24 MiB
sample_guides        40.00 KiB
sample_mflix        112.26 MiB
sample_restaurants    6.39 MiB
sample_supplies       1.05 MiB
sample_training      48.56 MiB
sample_weatherdata    3.66 MiB
admin               296.00 KiB
local                 1.54 GiB

公式ドキュメント内にあるもう一つの例「Example: Mobile App」を見ると、より理解が深まるかと思います。

この章のまとめ

MongoDBはワーキングセットがWiredTigerのキャッシュにすべて収まるとき、最高のパフォーマンスを発揮する。ワーキングセットのサイズはdb.stats()の出力から見積ることができる。

ワーキングセットのうち、頻繁にアクセスされるデータのサイズを見積るには、全体の何%が常にアクティブにアクセスがあるかを考えてみる。

さいごに:十分なRAMを用意できないとき

最近はクラウドサービスや仮想化基盤の普及により、RAMのお代わりは昔より容易になりました。MongoDB AtlasのCluster Tiers(選択できるインスタンスのサイズ)でも最大で768GBのRAMを搭載するM700が用意されています。しかし、コストなどいろいろな要因によって、十分なRAMを用意できないこともあるかと思います。

十分なRAMを搭載したマシンを用意できない場合は、シャーディングも検討してください。「Atlas Cluster Sizing and Tier Selection」の中でも「If you select a cluster tier without sufficient RAM, such as an Azure M200 with 256 GB RAM, sharding is required.」つまり十分なRAMがないクラスターを選択した場合はシャーディングが必要です、とあります。

ただし、シャーディングを選択すると、Atlasでもセルフホストでもコストが上がります。なのでRAMを追加すべきか、シャーディングすべきかは十分な検討が必要です。

冒頭でも述べましたが、MongoDBのパフォーマンス低下の原因がRAM不足だけとは限りません。記事の中でも引用したブログ「Performance Best Practices: MongoDB Data Modeling and Memory Sizing」では、データモデリングの重要性を一番最初に訴えています。

蛇足:今回のアイキャッチ画像はラムつながりにしてみました。ただしこちらはlambですね。

Author

MongoDB日本語サポート担当。ITインフラや運用・監視・保守が好きです。
無駄のない構成やアーキテクチャを見てうっとりしています。

k-yamamoriの記事一覧

新規CTA