2017/04/06

MongoDB環境構成時のポイント

公式MongoDBチェックリストから安定運用のポイントをまとめてみました

  • 何は無くとも公式資料をよく読み込む事、特にOperationChecklist。v3.0以降の情報は書籍でも追いついていない所があります。今回のまとめはほぼ以下の抜粋と補足です。
  • シャーディングは経験がほぼ無いのでもっと知見を増やしていきたい、、、
    • https://docs.mongodb.com/manual/contents/
    • https://docs.mongodb.com/manual/administration/production-checklist-operations/

用途

  • MongoDBのみを稼働させ、他用途に使わない。

アーキテクチャ

  • 64bitOS必須
    • 32bitOSだと使用可能なメモリ容量が実質1.5G程度しかない
  • リトルエンディアンのマシンにする。
    • ビッグエンディアンのMAC、SPARK、PowerPC等のアーキテクチャは避ける。

CPU

  • CPUバウンドの負荷はほとんど無いので、あまり考慮は不要。
  • 但し、オンメモリ稼動(インデックス+ワーキングセット>RAMの状態)でも高負荷であればCPUバウンドの場合も有り、スケールアップを後から検討する。

メモリ

  • MongoDBパフォーマンスの一番の肝
  • オンメモリ稼動(インデックス+ワーキングセット>RAMの状態)になるように出来るだけ多く積む。
  • オンメモリ稼働できない場合はページフォルトとしてディスク側へのデータ読み込みを行う。当然速度は低下するので極力避ける。

ディスク

  • SSD推奨
  • xfs推奨(ext4だとパフォーマンス上の懸念有)
  • RAID10推奨
  • dbPathにNFSを使用しない

ジャーナル

  • 基本的に有効にする。メモリ書込み~ディスク書込みまでに予期せぬ停止が起きた場合の障害を最小限に抑えられる。

ストレージエンジン

  • V3デフォルトのWiredTigerを使う。(MongoV3~) http://qiita.com/fetaro/items/050a20f695652c6acc94 http://qiita.com/fetaro/items/cd570d70623b58b5deef#_reference-820e25a3d04877ff37e7
    • 従来のエンジン「MMAP」と比べて以下のメリットがある。
      • ロックがのDB単位からドキュメント(レコード)単位に変わり、ロック待ちが減った。
      • メモリ使用量の制限が可能になった(cacheSizeGB)
        • 従来はシステムメモリを青天井で使い切ってしまう
      • データ圧縮(CollectionBlockCompressor)、インデックス圧縮(PrefixCompression)が出来るようになった。
      • データのフラグメンテーションが発生しない。 データ挿入時にフラグ部分のコンパクションが行われる。
      • インデックス、データそれぞれ保管場所を指定可能。
      • ジャーナルの仕様が変更された(従来と異なり、ジャーナル無効でドキュメント更新中にMongoがクラッシュしてもレコードが壊れることはない。古いデータを残して新しいデータを追記するから。)
    • (必須)CachSizeGBは搭載メモリ容量の5割程度におさえる。

OS

  • THP(Transparent Huge Page)をオフにする
    • Linuxでメモリ効率化のための仕組みだが、Mongoと相性が悪いので起動時にオフにするオプションを指定する。
    • https://docs.mongodb.com/v3.0/tutorial/transparent-huge-pages/
  • NUMAアーキテクチャをオフにする
    • パフォーマンス低下につながる可能性有り
    • http://rdma.hatenablog.com/entry/2014/05/26/010641
  • TCP keepaliveを調整
    • https://docs.mongodb.com/v3.0/faq/diagnostics/#faq-keepalive

レプリケーション

  • 最低3台で構成されるレプリカセットを1セット以上構成する
    • 2台以下だと自動フェールオーバ出来ない。
      • 自動フェールオーバ時のプライマリ再選出の基準になる「過半数以上の投票」という条件を満たせない。
  • レプリカセット内のメンバーは同一のntpサーバを使い時刻同期をさせる
  • レプリカセットメンバー内で3つ以上の奇数投票権がある事を確認する。
  • 更新記録用のoplogsizeは必ず大きめのサイズに変更する。
    • MySQLで言うバイナリログのようなもの。大きな違いとして保管サイズが決まっており超過分は古いデータから押し出しで自動削除されるので要注意。
    • 扱うデータ量によっては、「デフォルトのoplogSizeだとロールフォワード可能な期間が極端に短かった。短期間止めただけなのにロールフォワードNGで結局対象サーバ全復旧するしかねえ!」なんてことになりかねない。
    • まずは5%を目安とし、最終バックアップからの更新をカバーできるように設計を行うと良いかも。
  • レプリケーションメンバーのストレージサーバはスペックを統一させる。
  • レプリカセットのメンバー登録はホスト名ベースで行う。hosts登録済である事も要確認

シャーディング

  • 水平スケーリング(シャーディングしているか)
    • インデックスサイズ+ワーキングセットサイズ > RAMサイズを大きく超えていないか
    • 書込み負荷が高くないか

インデックス

  • インデックスはあるか、適切か
    • –>getIndexes()でインデックス一覧確認、explain()で実行時間、対象数、検索キー数、検索ドキュメント数、適用インデックス名は要確認。
    • 作りすぎても更新負荷やサイズ増につながるのでインデックスの乱用は避ける。
  • インデックスサイズ+ワーキングセットサイズ > RAMサイズとなっていないか、 なっている場合はディスクパフォーマンスが悪くなっていないか(iostat)
    • –>db.statsで確認。インデックスサイズ(indexSize)+データサイズ(dataSize)を確認。またディスク側への影響をiostatで確認。どちらも単位はbyte。
  • データのコンパクト化は出来ているか
    • –>db.statsで確認。storageSize »» dataSizeとなっていればコンパクションを検討する。どちらも単位はbyte。 storageSize、dataSizeの仕組みは以下参照 http://blog.mlab.com/2014/01/how-big-is-your-mongodb/