MongoDB on AWS
david@davidmturner.com
david@davidmturner.com
David Turner
I look after the internet
125
david@davidmturner.comdavid@davidmturner.com124
david@davidmturner.com123 david@davidmturner.com
david@davidmturner.com122 david@davidmturner.com
david@davidmturner.com121 david@davidmturner.com
david@davidmturner.com120
david@davidmturner.com119 david@davidmturner.com
david@davidmturner.com118 david@davidmturner.com
david@davidmturner.com117
M102: MongoDB for DBAs
david@davidmturner.com
100%
116
david@davidmturner.com115
M101P: MongoDB for Programmers
david@davidmturner.com
Less than 100%
114
david@davidmturner.comdavid@davidmturner.com113
david@davidmturner.com
What is MongoDB?
112
david@davidmturner.comdavid@davidmturner.com111
david@davidmturner.com110 david@davidmturner.com
david@davidmturner.com
Prebaked AMI
109
MongoDB with 1000 or 4000 PIOPS
david@davidmturner.comdavid@davidmturner.com108
david@davidmturner.com
Up and running in minutes
107
david@davidmturner.com
Not ready for
production
106
david@davidmturner.com105 david@davidmturner.com
david@davidmturner.com104
david@davidmturner.com103
david@davidmturner.com
Approach
1. configure AWS objects
2. instantiate instances using AWS CLI tools
3. scripted install with user data bash script
4. initialise the replica set
102
david@davidmturner.com
Configure VPC
101
david@davidmturner.com
Subnets
100
david@davidmturner.com
$ aws ec2 create-subnet
--vpc-id vpc-xxxxxxxx
--cidr-block 10.0.1.0/24
--availability-zone eu-west-1a
99
david@davidmturner.com98
$ aws ec2 create-subnet
--vpc-id vpc-xxxxxxxx
--cidr-block 10.0.2.0/24
--availability-zone eu-west-1b
david@davidmturner.com
Route Table
97
david@davidmturner.com
Assuming you have a
NAT instance already
96
david@davidmturner.com
$ aws ec2 create-route-table
--vpc-id vpc-xxxxxxxx
95
david@davidmturner.com
$ aws ec2 create-route
--route-table-id rtb-xxxxxxxx
--destination-cidr-block 0.0.0.0/0
--instance-id i-xxxxxxxx
94
david@davidmturner.com
$ aws ec2 associate-route-table
--route-table-id rtb-xxxxxxxx
--subnet-id subnet-xxxxxxx1
93
david@davidmturner.com92
$ aws ec2 associate-route-table
--route-table-id rtb-xxxxxxxx
--subnet-id subnet-xxxxxxx2
david@davidmturner.com
Security Group
91
david@davidmturner.com
$ aws ec2 create-security-group
--group-name MongoDB
--description MongoDB
--vpc-id vpc-xxxxxxxx
90
david@davidmturner.com
Ingress
89
david@davidmturner.com
$ aws ec2 authorize-security-group-ingress
--group-id sg-xxxxxxxx
--protocol tcp --port 27017
--source-group sg-xxxxxxxx
88
david@davidmturner.com
$ aws ec2 authorize-security-group-ingress
--group-id sg-xxxxxxxx
--protocol tcp --port 27017
--source-group sg-yyyyyyyy
87
david@davidmturner.com
$ aws ec2 authorize-security-group-ingress
--group-id sg-xxxxxxxx
--protocol tcp --port 22
--source-group sg-zzzzzzzz
86
david@davidmturner.com
Egress
85
david@davidmturner.com
$ aws ec2 authorize-security-group-egress
--group-id sg-xxxxxxxx
--protocol tcp --port 27017
--source-group sg-xxxxxxxx
84
david@davidmturner.com
$ aws ec2 authorize-security-group-egress
--group-id sg-xxxxxxxx
--protocol tcp --port 80
--cidr 0.0.0.0/0
83
david@davidmturner.com82
$ aws ec2 authorize-security-group-egress
--group-id sg-xxxxxxxx
--protocol tcp --port 443
--cidr 0.0.0.0/0
david@davidmturner.com81
$ aws ec2 authorize-security-group-egress
--group-id sg-xxxxxxxx
--protocol udp --port 123
--cidr 0.0.0.0/0
david@davidmturner.com
Network ACLs
80
david@davidmturner.com
Lazy. Default ALLOW.
79
david@davidmturner.com78 david@davidmturner.com
david@davidmturner.com
Placement Groups
77
david@davidmturner.com
$ aws ec2 create-placement-group MongoDB-a
76
david@davidmturner.com75
$ aws ec2 create-placement-group MongoDB-b
david@davidmturner.com
IAM
74
david@davidmturner.com
TrustPolicy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
73
david@davidmturner.com
MongoDBPolicy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["ec2:DescribeVolumes", “ec2:DescribeTags”,
"ec2:DescribeInstances", "ec2:DescribeInstanceAttribute"],
"Resource": ["*"],
"Effect": "Allow"
}, {
"Action": ["ec2:DeleteSnapshot", “ec2:CreateSnapshot",
"ec2:DescribeSnapshots"],
"Resource": ["*"],
"Effect": "Allow"
}, {
"Action": ["ec2:CreateTags"],
"Resource": ["*"],
"Effect": "Allow"
}
]
}
72
david@davidmturner.com
Role
71
david@davidmturner.com
$ aws iam create-role
--role-name MongoDB
--assume-role-policy-document
file://TrustPolicy.json
70
david@davidmturner.com
$ aws iam put-role-policy
--role-name MongoDB
--policy-name MongoDB-Policy
--policy-document
file://MongoDBPolicy.json
69
david@davidmturner.com
Instance Profile
68
david@davidmturner.com
$ aws iam create-instance-profile
--instance-profile-name MongoDB
67
david@davidmturner.com
$ aws iam add-role-to-instance-profile
--instance-profile-name MongoDB
--role-name MongoDB
66
david@davidmturner.com
fire up instances with
a bash userdata script
65
david@davidmturner.com
$ data=$(cat ./user-data.sh)
64
david@davidmturner.com
# volume sizes in GB
data_size=500
log_size=15
journal_size=25
63
david@davidmturner.com
$ aws ec2 run-instances
--region ‘eu-west-1’ …
62
david@davidmturner.com
… --security-group-ids sg-xxxxxxxx …
61
david@davidmturner.com
… --key-name TopSecretKeyPair …
60
david@davidmturner.com
… --iam-instance-profile
‘{“Arn”:"arn:aws:iam::
012345678901:instance-profile/
MongoDB_Instance_Profile"}' …
59
david@davidmturner.com
… --instance-type r3.large …
(2 vCPU, 15.25GB RAM)
58
david@davidmturner.com
… --block-device-mapping ‘[{
"DeviceName": "/dev/xvdf", “Ebs”:
{"VolumeSize":'$data_size',
"VolumeType": "io1", "Iops": 1000}},
{“DeviceName": "/dev/xvdg", "Ebs":
{“VolumeSize":'$data_size',
“VolumeType”: "io1", "Iops": 1000}},
{"DeviceName": "/dev/xvdh", “Ebs":
{“VolumeSize":'$journal_size',
"VolumeType": "io1", "Iops": 250}},
{“DeviceName": "/dev/xvdi", "Ebs":
{“VolumeSize":'$log_size',
"VolumeType": "io1", "Iops": 150}}]’ …
57
(data)
(journal)
(log)
david@davidmturner.com
… --placement AvailabilityZone=eu-west-1a,GroupName=MongoDB …
56
david@davidmturner.com
… --disable-api-termination …
55
david@davidmturner.com
… --image-id ami-a10897d6 …
Amazon Linux AMI 2015.03 (HVM), SSD Volume Type
Root device type: ebs Virtualization type: hvm
54
david@davidmturner.com
… --subnet-id subnet-xxxxxxxx …
53
david@davidmturner.com
… —user-data “$data” …
52
david@davidmturner.com
… —count 2
51
(then same again for AZ eu-west-1b)
david@davidmturner.com
yum -y update
50
david@davidmturner.com
mdadm --verbose --create
--name=mongo /dev/md0
--level=0 --chunk=256
--raid-devices=2 /dev/xvdf /dev/xvdg
mdadm --detail --scan | tee -a /etc/mdadm.conf
49
david@davidmturner.com
mkdir /mnt/data /mnt/journal /mnt/log
mkfs.ext4 /dev/md0
mkfs.ext4 /dev/xvdh
mkfs.ext4 /dev/xvdi
48
david@davidmturner.com
uuid=`blkid -o value -s UUID /dev/md0`
echo "UUID=$uuid /mnt/data ext4
defaults,auto,noatime,noexec 0 0
/dev/xvdh /mnt/journal ext4
defaults,auto,noatime,noexec 0 0
/dev/xvdi /mnt/log ext4
defaults,auto,noatime,noexec 0 0" >>
/etc/fstab
mount -a
47
david@davidmturner.com
ln -s /mnt/journal /mnt/data/journal
46
david@davidmturner.com
echo "[MongoDB]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/
repo/redhat/os/x86_64
gpgcheck=0
enabled=1" >> /etc/yum.repos.d/mongodb.repo
45
david@davidmturner.com
yum install -y
mongodb-org-2.6.1
mongodb-org-server-2.6.1
--exclude mongodb-org,
mongodb-org-server
service mongod stop
44
david@davidmturner.com
yum install -y sysstat gcc python27
python27-pip python27-devel
pip-2.7 install pymongo boto
43
david@davidmturner.com
chown mongod:mongod /mnt/data
chown mongod:mongod /mnt/journal
chown mongod:mongod /mnt/log
42
david@davidmturner.com
echo "dbpath=/mnt/data
logpath=/mnt/log/mongodb.log
logappend=true
fork=true
replSet = AWSUserGroup
" > /etc/mongod.conf
41
david@davidmturner.com
echo "mongod soft nofile 64000
mongod hard nofile 64000
mongod soft nproc 32000
mongod hard nproc 32000"
> /etc/security/limits.d/90-mongo.conf
40
david@davidmturner.com
echo 'ACTION=="add", KERNEL=="md*", ATTR{bdi/
read_ahead_kb}="16"' >> /etc/udev/rules.d/85-ebs.rules
echo 'ACTION=="add", KERNEL=="xvdf", ATTR{bdi/
read_ahead_kb}="16"' >> /etc/udev/rules.d/85-ebs.rules
echo 'ACTION=="add", KERNEL=="xvdg", ATTR{bdi/
read_ahead_kb}="16"' >> /etc/udev/rules.d/85-ebs.rules
echo 'ACTION=="add", KERNEL=="xvdh", ATTR{bdi/
read_ahead_kb}="16"' >> /etc/udev/rules.d/85-ebs.rules
echo 'ACTION=="add", KERNEL=="xvdi", ATTR{bdi/
read_ahead_kb}="16"' >> /etc/udev/rules.d/85-ebs.rules
39
david@davidmturner.com
echo "/mnt/log/mongodb.log {
daily
rotate 30
compress
dateext
missingok
notifempty
sharedscripts
prerotate
grep query /mnt/log/mongodb.log | logger -t mongodb -p warn
endscript
postrotate
/bin/kill -SIGUSR1 $(/bin/cat /mnt/data/mongod.lock)
rm -f /mnt/log/mongodb.log.[0-9][0-9][0-9][0-9]-*
endscript
}
" > /etc/logrotate.d/mongod
38
david@davidmturner.com
echo "net.ipv4.tcp_keepalive_time = 120"
> /etc/sysctl.d/01-mongod.conf
37
david@davidmturner.com
chkconfig mongod on
36
david@davidmturner.com
reboot
35
david@davidmturner.com
Route53
34
david@davidmturner.com
Skipping it for time…
33
david@davidmturner.com32
david@davidmturner.com
Configure MongoDB
31
david@davidmturner.com
rs.initiate()
30
david@davidmturner.com
rs.add(“x.x.x.x”)
29
david@davidmturner.com
rs.add(“y.y.y.y”)
28
david@davidmturner.com
rs.status()
27
david@davidmturner.com
Backups
26
david@davidmturner.com25
david@davidmturner.com
Hidden Member
24
david@davidmturner.com
EBS Snapshots
23
david@davidmturner.com
Hourly cronjob
22
david@davidmturner.com
Python Script
• Lock the database
• Lock the filesystem
• EBS Snapshot
• Unlock filesystem
• Unlock database
• Trim snapshots
21
david@davidmturner.com
if __name__ == "__main__":
conn = boto.ec2.connect_to_region(REGION)
client.admin.command("fsync", lock=True)
p = subprocess.Popen(
'/usr/bin/sudo /sbin/fsfreeze -f /mnt/data', shell=True)
p.wait()
create_snapshots(conn, get_volume_ids(conn))
p = subprocess.Popen(
'/usr/bin/sudo /sbin/fsfreeze -u /mnt/data', shell=True)
p.wait()
client.admin[‘$cmd'].sys.unlock.find_one()
conn.trim_snapshots(hourly_backups=3, daily_backups=7,
weekly_backups=4, monthly_backups=True)
20
david@davidmturner.com
Development
instances
19
david@davidmturner.com
… --block-device-mapping ‘[
{ "DeviceName": "/dev/xvdf", "Ebs":
{"SnapshotId": “snap-xxxxxxxx”,
"VolumeSize":'$data_size',
"VolumeType": “gp2"}
},{"DeviceName": "/dev/xvdg", "Ebs":
{"SnapshotId": “snap-xxxxxxxx",
"VolumeSize":'$data_size',
"VolumeType": “gp2"}
} …
18
david@davidmturner.com
Development instance
in less than 15 min
17
david@davidmturner.com
Haven’t Shown…
16
david@davidmturner.com
EBS Encryption and KMS
15
david@davidmturner.com
Multi-region
14
david@davidmturner.com
Sharded configuration
13
david@davidmturner.com
Log management
12
david@davidmturner.com
Monitoring
11
david@davidmturner.com10 david@davidmturner.com
david@davidmturner.com9 david@davidmturner.com
david@davidmturner.comdavid@davidmturner.com8
david@davidmturner.com7
david@davidmturner.com6 david@davidmturner.com
Would like to meet...
david@davidmturner.com5 david@davidmturner.com
david@davidmturner.comdavid@davidmturner.com4
david@davidmturner.com3
david@davidmturner.com2
david@davidmturner.comdavid@davidmturner.com1
david@davidmturner.com
david@davidmturner.com
Images
4: http://i.ytimg.com/vi/-xcecNrpChQ/maxresdefault.jpg
15: http://elginsweeper.com/portals/0/Images/Application_Photos/Runway.gif
17: http://arabhardware.net/wp-content/uploads/2014/12/ram-04.jpg
18: http://www.public-domain-image.com/full-image/objects-public-domain-images-pictures/an-old-west-style-
padlock-in-old-town-san-diego.jpg-free-stock-photo.html
20: http://orbital.comp.nus.edu.sg/wp-content/uploads/2013/02/
STS-133_Discovery_Lift_Off_Launch_Pad_39A_KSC.jpg
23: http://www.layman.org/wp-content/uploads/2013/10/face.jpg
26: http://blog.mongodb.org/post/4982676520/mongodb-on-ec2-best-practices
122: https://dogchow.com/media/28148/how_do_i_stop_my_dog_from_begging_istock_000012144475small.jpg
124: http://www.salus-wellness.com/wp-content/uploads/2010/11/Business.jpg
126: http://www.twinfinite.net/wp-content/uploads/2015/03/Lego.jpg

MongoDB on AWS in 5 min