中年engineerの独り言 - crumbjp

LinuxとApacheの憂鬱

AWS上にハイパフォーマンスMongoDBを構築する方法

AWSインスタンスの選定

AWSインスタンスタイプ一覧

以下のインスタンスボリュームが付随しているプロダクトラインが候補になる。
個人的にはi2.xxx が好みである。

r3.xxx
メモリ最適化インスタンス
i2.xxx
SSD容量最適化インスタンス

ただし、インスタンスボリュームはスナップショットが取れず、揮発性なので取り回しが悪い。
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">パーティションファイルシステム設定関連:

手順

1. 普通に AWS console から作る場合


OS領域はマグネットで十分。インスタンスストアを全部追加すること。

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 に読み替えてください。

4. ファイルシステムXFSを作る

`mkfs.xfs` が無ければ `apt-get install xfsprogs`

# mkfs.xfs -K /dev/xvdb1
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を構築してください。
リンク先の設定がそのまま使えるはずです。