掲題の通り、MongoDBのベストプラクティスのPDFを読んだメモです。
Linuxの設定系
- ファイルシステムのatime設定(アクセス時間機能)を無効にすること
- WiredTigerの場合、xfsのファイルシステムがストロングレコメンド
- raid組むなら0 or 10を推奨
- LinuxのHugepageの機能はオフにすること
Mongo系
- ジャーナルファイルとデータファイルを別々のストレージに保存すると、パフォーマンスアップする
- GCPでは通常のSSDを使う場合は一緒で良いと言っています(おそらく容量によってストレージパフォーマンスが変わるため、分けないほうがコスパが良くなるのかと。)
- インデックスとコレクションを別々のストレージに保存できる
- Zone機能でシャーディング分割できるから、RDBMSのパーティション的なことを出来る
- directoryPerDBを使えば、DBごとに使うディスクを変更できる
- MongoDB Compassを使うとアナライズが捗るよ(自社の宣伝かな)
- WiredTigerの場合、ReadAhead(先読み)のサイズは0に設定してね
- blockdev -setra コマンドで、readaheadblockのサイズを0に設定出来る
- WiredTigerの使用可能なRAMは、デフォルト60%に設定されている
- WiredTigerは、ファイルシステムのキャッシュが減るとパフォーマンスが低下する可能性があるから、メモリ使用量をデフォルトから上げる場合は注意すること
アプリケーション側
- 配列の更新を、v3.6から強化したよ。
- ドライバは、2ヶ月に一回更新してるから、可能な限り最新を使ってね。
- MongoDBは、ドキュメントレベルでACID準拠を提供するよ。だから、すべてのデータを1つのドキュメントに保存してね。
- 16MBがMAXサイズだから、超えそうなら仕方ないね。
- ビデオや画像などのバイナリデータを保存する場合は、GridFSの使用を検討してね。
- バイナリデータを多数の小さな文書に自動的に格納する機能だよ。
- MMAP MAPv1エンジンを使っている場合は、ドキュメントが後から増加しないようにパディングデータを入れるなど検討してね。
- WiredTigerの場合は、圧縮するからパディングは必要ないよ。
- 不必要に長いフィールド名は使用しないでね。WiredTigerの場合圧縮するからディスクには影響が少ないけど、RAMには影響するからね。
感想
最後のフィールド名を短縮する話だが、あまりに短い名称は、何を格納しているのか?コードまで追わないとわからないため、短すぎるのもどうかと思う。
※追記 ↑に関しては、各コレクション単位で簡単なドキュメントを用意するようにすれば良いから、短いのが推奨かもと最近は思います。
あと、RDBMSやっている人ならインデックス関係とかは、すっと入ってくる内容だと思う。
マルチマスターでレプリカセット増やせば良いじゃんという、ゆるふわMongoDBだけど、ちゃんとパフォーマンスを意識した使い方をしたい。
追加でGCPのMongoDBの話
# ■TCP キープアライブ時間を短縮する(推奨120秒)
sysctl net.ipv4.tcp_keepalive_time
sudo sysctl -w net.ipv4.tcp_keepalive_time=<value>
# ■ulimit設定(推奨設定)
$ ulimit -a
$ limit fsize unlimited unlimited # (file size)
$ limit cpu unlimited unlimited # (cpu time)
$ limit as unlimited unlimited # (virtual memory size)
$ limit memlock unlimited unlimited # (locked-in-memory size)
$ limit nofile 64000 64000 # (open files)
$ limit nproc 64000 64000 # (processes/threads)
# ■swappinessの設定変更
$ cat /proc/sys/vm/swappiness
$ sysctl vm.swappiness=1
# ■ファイルシステムは、XFSを推奨
# ■ファイルシステムのReadAhead(先読みサイズ)変更
$ sudo blockdev --getra /dev/sda1
$ sudo blockdev --setra /dev/sda1 0
# ■ファイルシステムのatime(ファイルアクセス時間)設定をオフにする
$ sudo vi /etc/fstab
...
# /dev/mapper/VolGroup-lv_root / ext4 defaults 1 1 ← コメントアウトして
/dev/mapper/VolGroup-lv_root / ext4 defaults,noatime 1 1 ← これを追記 (noatime)
...
$ sudo reboot
$ mount | grep " / "
/dev/mapper/VolGroup-lv_root on / type ext4 (rw,noatime) ← noatimeが設定されました
# ■現在のI/O量の確認
$ iostat -xmt 1
# ■huge-pagesのオフ設定(設定値が多いので下記を参照)
https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/
他にも、ガイドあります(登録が必要だけど。。)
https://www.mongodb.com/collateral/mongodb-architecture-guide
https://www.mongodb.com/collateral/mongodb-operations-best-practices