AWS上にハイパフォーマンスMongoDBを構築する方法
AWSインスタンスの選定
以下のインスタンスボリュームが付随しているプロダクトラインが候補になる。
個人的にはi2.xxx が好みである。
- r3.xxx
- メモリ最適化インスタンス
ただし、インスタンスボリュームはスナップショットが取れず、揮発性なので取り回しが悪い。
Provisioned IOPS (SSD) ボリュームも検討候補になるが、高くつく事になるのでお金持ちの人用。。
バックアップ戦略
流石にバックアップを全く取らずに運用する事は出来ないので
以下様にレプリカセット構成を組み、バックアップを取る。
最後のノードはバックアップ専用なので、SSD以外は非力出よい。
ただしあまり小さいインスタンスを選択するとネットワーク容量が足りなくなるのでそこを考慮して選定する。
構成例
- i2.4xlarge
- i2.4xlarge
- r3.large + 2400GiB EBS Magnet
もちろん負荷に依るが、この様な構成でも成立する。
AWS 周りの必要知識
- //docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/i2-instances.html">i2インスタンス:基本使用ボリュームが大きいほどIOPSが高くなる
SSDオーバープロビジョニングの為に、10%ほど未使用領域を残す。激しく使うならi2.2xlarge以上。そうじゃないとネットワークが負ける。
- //docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/InstanceStorage.html#InstanceStoreTrimSupport">TRIMサポート:i2 と r3 のインスタンスボリュームは TRIM がサポートされてる。
- //docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/storage_expand_partition.html">パーティション/ファイルシステム設定関連:
手順
2. デバイスを確認
# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT xvda 202:0 0 40G 0 disk └─xvda1 202:1 0 40G 0 part / xvdb 202:16 0 745.2G 0 disk
`xvdb` がインスタンスボリューム
3a. インスタンスボリュームが1つの場合はオーバープロビジョニング用の未使用領域を10%確保
インスタンスボリュームのサイズは800GiB単位で、インスタンスの大きさによって複数のインスタンスボリュームが付随する。
1つだった場合はそのまま使えば良いがSSDの性能を生かす為にオーバープロビジョニングの設定をする。
# gdisk /dev/xvdb * パーティション(/dev/xvdb1)作成 Command : n Partition number : 1 FirstSector: 2048 LastSector: XXXX ※ 最後のセクタから10%程余らせた部分を指定する GUID: 8300 * 名前変更 Command : c Enter name: Linux * GUID生成 Command : x Expert command : g unique GUID: R * 確認 Expert command: p Disk /dev/xvdb: 1562822320 sectors, 745.2 GiB Logical sector size: 512 bytes Disk identifier (GUID): 4E2273AF-9E75-401A-8D3E-365A4D9674AC Partition table holds up to 128 entries First usable sector is 34, last usable sector is 1562822286 Partitions will be aligned on 2048-sector boundaries Total free space is 156284525 sectors (74.5 GiB) Number Start (sector) End (sector) Size Code Name 1 2048 1406539775 670.7 GiB 8300 Linux * 反映 Command : w
3b. インスタンスボリュームは2つの場合はRAID0を設定する
本来は各SSDにオーバープロビジョニングを指定した方が良いと思うが、そもそも大容量のストレージを常に使い切りそうな使い方自体がマズいので、運用上、常にある程度の未使用領域が残っている状態が保たれるはず。
そうなると、ある程度TRIMだけで対処できるのではないか?という想像の元にこうしている。
※ 誰か詳しい人が居たら教えてください
`mdadm` が無ければ apt-get install mdadm
インスタンスボリュームが4個の場合
# mdadm --create /dev/md0 --level=0 --raid-devices=4 /dev/xvdb /dev/xvdc /dev/xvdd /dev/xvde
以降、/dev/xvdb1 は /dev/md0 に読み替えてください。
5. マウント
TRIMを有効にする為にdiscardを指定する
# mkdir -p /data # mount -o discard /dev/xvdb1 /data
== /etc/fstab == /dev/xvdb1 /data auto defaults,nobootwait,discard 0 2 # raidしている場合は `blkid /dev/md0`で取得できるuuidを指定する UUID="**uuid**" /data auto defaults,nobootwait,discard 0 2
6. TRIM が効いてるか確認
# fstrim -v /data/ /data/: 3199094800384 bytes were trimmed
7. ここで一回リブートする
8. MongoDBディレクトリを作る
# mkdir /usr/local/mongodb # mkdir -p /data/mongo # ln -sfT /data/mongo /usr/local/mongodb/data
9. limits のnofileを多めに変更
https://docs.mongodb.org/manual/reference/ulimit/
後は普通にMongoDBを構築してください。
リンク先の設定がそのまま使えるはずです。