parent
70fd4d25fd
commit
c5ffa7e432
@ -0,0 +1,298 @@ |
||||
##Deploying a sharded production ready MongoDB cluster with Ansible |
||||
------------------------------------------------------------------------------ |
||||
|
||||
- Requires Ansible 1.2 |
||||
- Expects CentOS/RHEL 6 hosts |
||||
|
||||
###A Primer into the MongoDB NoSQL database. |
||||
--------------------------------------------- |
||||
|
||||
![Alt text](/images/nosql_primer.png "Primer NoSQL") |
||||
|
||||
The above diagram shows how the MongoDB nosql differs from the traditional |
||||
relational database model. In RDBMS the data of a user is stored in table and |
||||
the records of users are stored in rows/columns, While in mongodb the 'table' |
||||
is replaced by 'collection' and the individual 'records' are called |
||||
'documents'. One thing also to be noticed is that the data is stored as |
||||
key/value pairs in BJSON format. |
||||
|
||||
Another thing to be noticed is that nosql has a looser consistency model, as an |
||||
example the second document in the users collection has an additonal field of |
||||
'last name'. Due to this flexibility the nosql database model can give us: |
||||
|
||||
Better Horizontal scaling capability. |
||||
|
||||
Also mongodb has inbuilt support for |
||||
|
||||
Data Replication & HA |
||||
|
||||
Which makes it good choice for users who have very large data to handle and |
||||
less requirement for ACID. |
||||
|
||||
|
||||
### MongoDB's Data replication . |
||||
------------------------------------ |
||||
|
||||
![Alt text](/images/replica_set.png "Replica Set") |
||||
|
||||
|
||||
Data backup is achieved in Mongodb via Replica sets. As the figure above show's |
||||
a single replication set consists of a replication master (active) and several |
||||
other replications slaves (passive). All the database operations like |
||||
Add/Delete/Update happens on the replication master and the master replicates |
||||
the data to the slave nodes. mongod is the process which is resposible for all |
||||
the database activities as well as replication processes. The minimum |
||||
recommended number of slave servers are 3. |
||||
|
||||
|
||||
### MongoDB's Sharding (Horizontal Scaling) . |
||||
------------------------------------------------ |
||||
|
||||
![Alt text](/images/sharding.png "Sharding") |
||||
|
||||
Sharding allows to achieve a very high performing database, by partioning the |
||||
data into seperate chunks and allocating diffent ranges of chunks to diffrent |
||||
shard servers. The figure above shows a collection which has 90 documents which |
||||
has been sharded across the three shard server, The first shard getting ranges |
||||
from 1- 29 etc... . When a client wants to access a certian document it |
||||
contacts the query router (mongos process), which inturn would contact the |
||||
'configuration node' (lightweight mongod process) which keeps a record of which |
||||
ranges of chunks are distributed across which shards. |
||||
|
||||
Please do note that every shard server should be backed by a replica set, so |
||||
that when data is written/queried copies of the data are available. So in a |
||||
three shard deployment we would require 3 replica sets and primaries of each |
||||
would act as the sharding server. |
||||
|
||||
Here's a basic steps of how sharding works. |
||||
|
||||
1) A new database is created, and collections are added. |
||||
|
||||
2) New documents get updated as an when clients update, all the new documents |
||||
goes into a single shard. |
||||
|
||||
3) when the size of collection in a shard exceeds the 'chunk_size' the |
||||
collection is split and balanced across shards. |
||||
|
||||
|
||||
###Deploy MongoDB cluster via Ansible. |
||||
-------------------------------------------- |
||||
|
||||
### Deploy the Cluster. |
||||
---------------------------- |
||||
|
||||
![Alt text](/images/site.png "Site") |
||||
|
||||
The above diagram illustrates the deployment model for mongodb cluster via |
||||
Ansible, This deployment models focuses on deploying a three shard servers, |
||||
each having a replica set, the backup replica servers are other two shard |
||||
primaries. The configuration server are co-located with the shard's. The mongos |
||||
servers are best deployed on seperate servers. These are the minimum recomended |
||||
configuration for a production grade mongodb deployment. Please note that the |
||||
playbooks are capable of deploying N node cluster not necesarily three. Also |
||||
all the processes are secured using keyfiles. |
||||
|
||||
###Pre-Requisite's |
||||
|
||||
Edit the group_vars/all file to reflect the below variables. |
||||
|
||||
1) iface: 'eth1' # the interface to be used for all communication. |
||||
|
||||
2) Set a unique mongod_port variable in the inventory file for each MongoDB |
||||
server. |
||||
|
||||
3) The default directory for storing data is /data, please do change it if |
||||
requried, also make sure it has sufficient space 10G recommended. |
||||
|
||||
###Once the pre-requisite's have been done, we can procced with the site deployment. The following example deploys a three node MongoDB Cluster |
||||
|
||||
The inventory file looks as follows: |
||||
|
||||
#The site wide list of mongodb servers |
||||
[mongo_servers] |
||||
mongo1 mongod_port=2700 |
||||
mongo2 mongod_port=2701 |
||||
mongo3 mongod_port=2702 |
||||
|
||||
#The list of servers where replication should happen, including the master server. |
||||
[replication_servers] |
||||
mongo1 |
||||
mongo2 |
||||
mongo3 |
||||
|
||||
#The list of mongodb configuration servers, make sure it is 1 or 3 |
||||
[mongoc_servers] |
||||
mongo1 |
||||
mongo2 |
||||
mongo3 |
||||
|
||||
#The list of servers where mongos servers would run. |
||||
[mongosservers] |
||||
mongos1 |
||||
mongos2 |
||||
|
||||
Build the site with the following command: |
||||
|
||||
ansible-playbook -i hosts site.yml |
||||
|
||||
|
||||
###Verifying the deployed MongoDB Cluster |
||||
--------------------------------------------- |
||||
|
||||
Once completed we can check replication set availibitly by connecting to |
||||
individual primary replication set nodes, 'mongo --host 192.168.1.1 --port 2700' |
||||
and issue the command to query the status of replication set, we should get a |
||||
similar output. |
||||
|
||||
|
||||
web2:PRIMARY> rs.status() |
||||
{ |
||||
"set" : "web2", |
||||
"date" : ISODate("2013-03-19T10:26:35Z"), |
||||
"myState" : 1, |
||||
"members" : [ |
||||
{ |
||||
"_id" : 0, |
||||
"name" : "web2:2013", |
||||
"health" : 1, |
||||
"state" : 1, |
||||
"stateStr" : "PRIMARY", |
||||
"uptime" : 102, |
||||
"optime" : Timestamp(1363688755000, 1), |
||||
"optimeDate" : ISODate("2013-03-19T10:25:55Z"), |
||||
"self" : true |
||||
}, |
||||
{ |
||||
"_id" : 1, |
||||
"name" : "web3:2013", |
||||
"health" : 1, |
||||
"state" : 2, |
||||
"stateStr" : "SECONDARY", |
||||
"uptime" : 40, |
||||
"optime" : Timestamp(1363688755000, 1), |
||||
"optimeDate" : ISODate("2013-03-19T10:25:55Z"), |
||||
"lastHeartbeat" : ISODate("2013-03-19T10:26:33Z"), |
||||
"pingMs" : 1 |
||||
} |
||||
], |
||||
"ok" : 1 |
||||
} |
||||
|
||||
|
||||
we can check the status of the Shards as follows: connect to the mongos service |
||||
'mongo localhost:8888/admin -u admin -p 123456' and issue the following command to get |
||||
the status of the Shards. |
||||
|
||||
|
||||
|
||||
mongos> sh.status() |
||||
--- Sharding Status --- |
||||
sharding version: { "_id" : 1, "version" : 3 } |
||||
shards: |
||||
{ "_id" : "web2", "host" : "web2/web2:2013,web3:2013" } |
||||
{ "_id" : "web3", "host" : "web3/web2:2014,web3:2014" } |
||||
databases: |
||||
{ "_id" : "admin", "partitioned" : false, "primary" : "config" } |
||||
|
||||
|
||||
###We can also make sure the Sharding works by creating a database,collection and populate it with documents and check if the chunks of the collection are balanced equally across nodes. The below diagram illustrates the verification step. |
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------- |
||||
|
||||
![Alt text](/images/check.png "check") |
||||
|
||||
The above mentioned steps can be tested with an automated playbook. |
||||
|
||||
Issue the following command to run the test. In variable passed make sure the |
||||
servername is one of any mongos server. |
||||
|
||||
ansible-playbook -i hosts playbooks/testsharding.yml -e servername=mongos |
||||
|
||||
|
||||
Once the playbook completes, we check if the shadring has succeded by logging |
||||
on to any mongos server and issuing the following command. The output display |
||||
the number of chunks spread across the shards. |
||||
|
||||
mongos> sh.status() |
||||
--- Sharding Status --- |
||||
sharding version: { "_id" : 1, "version" : 3 } |
||||
shards: |
||||
{ "_id" : "bensible", "host" : "bensible/bensible:20103,web2:20103,web3:20103" } |
||||
{ "_id" : "web2", "host" : "web2/bensible:20105,web2:20105,web3:20105" } |
||||
{ "_id" : "web3", "host" : "web3/bensible:20102,web2:20102,web3:20102" } |
||||
databases: |
||||
{ "_id" : "admin", "partitioned" : false, "primary" : "config" } |
||||
{ "_id" : "test", "partitioned" : true, "primary" : "web3" } |
||||
|
||||
test.test_collection chunks: |
||||
|
||||
bensible 7 |
||||
web2 6 |
||||
web3 7 |
||||
|
||||
|
||||
|
||||
|
||||
### Scaling the Cluster |
||||
--------------------------------------- |
||||
|
||||
![Alt text](/images/scale.png "scale") |
||||
|
||||
To add a new node to the configured MongoDb Cluster, setup the inventory file as follows: |
||||
|
||||
#The site wide list of mongodb servers |
||||
[mongoservers] |
||||
mongo1 mongod_port=2700 |
||||
mongo2 mongod_port=2701 |
||||
mongo3 mongod_port=2702 |
||||
mongo4 mongod_port=2703 |
||||
|
||||
#The list of servers where replication should happen, make sure the new node is listed here. |
||||
[replicationservers] |
||||
mongo4 |
||||
mongo3 |
||||
mongo1 |
||||
mongo2 |
||||
|
||||
#The list of mongodb configuration servers, make sure it is 1 or 3 |
||||
[mongocservers] |
||||
mongo1 |
||||
mongo2 |
||||
mongo3 |
||||
|
||||
#The list of servers where mongos servers would run. |
||||
[mongosservers] |
||||
mongos1 |
||||
mongos2 |
||||
|
||||
Make sure you have the new node added in the replicationservers section and |
||||
execute the following command: |
||||
|
||||
ansible-playbook -i hosts site.yml |
||||
|
||||
###Verification. |
||||
----------------------------- |
||||
|
||||
The verification of the newly added node can be as easy checking the sharding |
||||
status and see the chunks being rebalanced to the newly added node. |
||||
|
||||
$/usr/bin/mongo localhost:8888/admin -u admin -p 123456 |
||||
mongos> sh.status() |
||||
--- Sharding Status --- |
||||
sharding version: { "_id" : 1, "version" : 3 } |
||||
shards: |
||||
{ "_id" : "bensible", "host" : "bensible/bensible:20103,web2:20103,web3:20103" } |
||||
{ "_id" : "web2", "host" : "web2/bensible:20105,web2:20105,web3:20105" } |
||||
{ "_id" : "web3", "host" : "web3/bensible:20102,web2:20102,web3:20102" } |
||||
{ "_id" : "web4", "host" : "web4/bensible:20101,web3:20101,web4:20101" } |
||||
databases: |
||||
{ "_id" : "admin", "partitioned" : false, "primary" : "config" } |
||||
{ "_id" : "test", "partitioned" : true, "primary" : "bensible" } |
||||
|
||||
test.test_collection chunks: |
||||
|
||||
web4 3 |
||||
web3 6 |
||||
web2 6 |
||||
bensible 5 |
||||
|
||||
|
@ -0,0 +1,25 @@ |
||||
# The global variable file mongodb installation |
||||
|
||||
# The chunksize for shards in MB |
||||
mongos_chunk_size: 1 |
||||
|
||||
# The port in which mongos server should listen on |
||||
mongos_port: 8888 |
||||
|
||||
# The port for mongo config server |
||||
mongoc_port: 7777 |
||||
|
||||
# The directory prefix where the database files would be stored |
||||
mongodb_datadir_prefix: /data/ |
||||
|
||||
# The interface where the mongodb process should listen on. |
||||
# Defaults to the first interface. Change this to: |
||||
# |
||||
# iface: eth1 |
||||
# |
||||
# ...to override. |
||||
# |
||||
iface: '{{ ansible_default_ipv4.interface }}' |
||||
|
||||
# The password for admin user |
||||
mongo_admin_pass: 123456 |
@ -0,0 +1,29 @@ |
||||
#The site wide list of mongodb servers |
||||
|
||||
# the mongo servers need a mongod_port variable set, and they must not conflict. |
||||
[mongo_servers] |
||||
hadoop1 mongod_port=2700 |
||||
hadoop2 mongod_port=2701 |
||||
hadoop3 mongod_port=2702 |
||||
hadoop4 mongod_port=2703 |
||||
|
||||
#The list of servers where replication should happen, by default include all servers |
||||
[replication_servers] |
||||
hadoop1 |
||||
hadoop2 |
||||
hadoop3 |
||||
hadoop4 |
||||
|
||||
#The list of mongodb configuration servers, make sure it is 1 or 3 |
||||
[mongoc_servers] |
||||
hadoop1 |
||||
hadoop2 |
||||
hadoop3 |
||||
|
||||
|
||||
#The list of servers where mongos servers would run. |
||||
[mongos_servers] |
||||
hadoop1 |
||||
hadoop2 |
||||
|
||||
|
After Width: | Height: | Size: 180 KiB |
After Width: | Height: | Size: 181 KiB |
After Width: | Height: | Size: 142 KiB |
After Width: | Height: | Size: 427 KiB |
After Width: | Height: | Size: 238 KiB |
After Width: | Height: | Size: 416 KiB |
@ -0,0 +1,13 @@ |
||||
--- |
||||
#This playbook is used to add a new node the mongodb cluster |
||||
|
||||
- hosts: all |
||||
tasks: |
||||
- include: roles/common/tasks/main.yml |
||||
handlers: |
||||
- include: roles/common/handlers/main.yml |
||||
|
||||
- hosts: ${servername} |
||||
tasks: |
||||
- include: roles/mongod/tasks/main.yml |
||||
- include: roles/mongod/tasks/addshard.yml |
@ -0,0 +1,17 @@ |
||||
--- |
||||
# The playbook creates a new database test and populates data in the database to test the sharding. |
||||
|
||||
- hosts: $servername |
||||
user: root |
||||
tasks: |
||||
- name: Create a new database and user |
||||
mongodb_user: login_user=admin login_password=${mongo_admin_pass} login_port=${mongos_port} database=test user=admin password=${mongo_admin_pass} state=present |
||||
|
||||
- name: Pause for the user to get created and replicated |
||||
pause: minutes=3 |
||||
|
||||
- name: Execute the collection creation script |
||||
command: /usr/bin/mongo localhost:${mongos_port}/test -u admin -p ${mongo_admin_pass} /tmp/testsharding.js |
||||
|
||||
- name: Enable sharding on the database and collection |
||||
command: /usr/bin/mongo localhost:${mongos_port}/admin -u admin -p ${mongo_admin_pass} /tmp/enablesharding.js |
@ -0,0 +1,6 @@ |
||||
[10gen] |
||||
name=10gen Repository |
||||
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64 |
||||
gpgcheck=0 |
||||
enabled=1 |
||||
|
@ -0,0 +1,29 @@ |
||||
-----BEGIN PGP PUBLIC KEY BLOCK----- |
||||
Version: GnuPG v1.4.5 (GNU/Linux) |
||||
|
||||
mQINBEvSKUIBEADLGnUj24ZVKW7liFN/JA5CgtzlNnKs7sBg7fVbNWryiE3URbn1 |
||||
JXvrdwHtkKyY96/ifZ1Ld3lE2gOF61bGZ2CWwJNee76Sp9Z+isP8RQXbG5jwj/4B |
||||
M9HK7phktqFVJ8VbY2jfTjcfxRvGM8YBwXF8hx0CDZURAjvf1xRSQJ7iAo58qcHn |
||||
XtxOAvQmAbR9z6Q/h/D+Y/PhoIJp1OV4VNHCbCs9M7HUVBpgC53PDcTUQuwcgeY6 |
||||
pQgo9eT1eLNSZVrJ5Bctivl1UcD6P6CIGkkeT2gNhqindRPngUXGXW7Qzoefe+fV |
||||
QqJSm7Tq2q9oqVZ46J964waCRItRySpuW5dxZO34WM6wsw2BP2MlACbH4l3luqtp |
||||
Xo3Bvfnk+HAFH3HcMuwdaulxv7zYKXCfNoSfgrpEfo2Ex4Im/I3WdtwME/Gbnwdq |
||||
3VJzgAxLVFhczDHwNkjmIdPAlNJ9/ixRjip4dgZtW8VcBCrNoL+LhDrIfjvnLdRu |
||||
vBHy9P3sCF7FZycaHlMWP6RiLtHnEMGcbZ8QpQHi2dReU1wyr9QgguGU+jqSXYar |
||||
1yEcsdRGasppNIZ8+Qawbm/a4doT10TEtPArhSoHlwbvqTDYjtfV92lC/2iwgO6g |
||||
YgG9XrO4V8dV39Ffm7oLFfvTbg5mv4Q/E6AWo/gkjmtxkculbyAvjFtYAQARAQAB |
||||
tCFFUEVMICg2KSA8ZXBlbEBmZWRvcmFwcm9qZWN0Lm9yZz6JAjYEEwECACAFAkvS |
||||
KUICGw8GCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRA7Sd8qBgi4lR/GD/wLGPv9 |
||||
qO39eyb9NlrwfKdUEo1tHxKdrhNz+XYrO4yVDTBZRPSuvL2yaoeSIhQOKhNPfEgT |
||||
9mdsbsgcfmoHxmGVcn+lbheWsSvcgrXuz0gLt8TGGKGGROAoLXpuUsb1HNtKEOwP |
||||
Q4z1uQ2nOz5hLRyDOV0I2LwYV8BjGIjBKUMFEUxFTsL7XOZkrAg/WbTH2PW3hrfS |
||||
WtcRA7EYonI3B80d39ffws7SmyKbS5PmZjqOPuTvV2F0tMhKIhncBwoojWZPExft |
||||
HpKhzKVh8fdDO/3P1y1Fk3Cin8UbCO9MWMFNR27fVzCANlEPljsHA+3Ez4F7uboF |
||||
p0OOEov4Yyi4BEbgqZnthTG4ub9nyiupIZ3ckPHr3nVcDUGcL6lQD/nkmNVIeLYP |
||||
x1uHPOSlWfuojAYgzRH6LL7Idg4FHHBA0to7FW8dQXFIOyNiJFAOT2j8P5+tVdq8 |
||||
wB0PDSH8yRpn4HdJ9RYquau4OkjluxOWf0uRaS//SUcCZh+1/KBEOmcvBHYRZA5J |
||||
l/nakCgxGb2paQOzqqpOcHKvlyLuzO5uybMXaipLExTGJXBlXrbbASfXa/yGYSAG |
||||
iVrGz9CE6676dMlm8F+s3XXE13QZrXmjloc6jwOljnfAkjTGXjiB7OULESed96MR |
||||
XtfLk0W5Ab9pd7tKDR6QHI7rgHXfCopRnZ2VVQ== |
||||
=V/6I |
||||
-----END PGP PUBLIC KEY BLOCK----- |
@ -0,0 +1,26 @@ |
||||
[epel] |
||||
name=Extra Packages for Enterprise Linux 6 - $basearch |
||||
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch |
||||
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch |
||||
failovermethod=priority |
||||
enabled=1 |
||||
gpgcheck=1 |
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 |
||||
|
||||
[epel-debuginfo] |
||||
name=Extra Packages for Enterprise Linux 6 - $basearch - Debug |
||||
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug |
||||
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch |
||||
failovermethod=priority |
||||
enabled=0 |
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 |
||||
gpgcheck=1 |
||||
|
||||
[epel-source] |
||||
name=Extra Packages for Enterprise Linux 6 - $basearch - Source |
||||
#baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS |
||||
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch |
||||
failovermethod=priority |
||||
enabled=0 |
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 |
||||
gpgcheck=1 |
@ -0,0 +1,5 @@ |
||||
--- |
||||
# Handler for mongod |
||||
|
||||
- name: restart iptables |
||||
service: name=iptables state=restarted |
@ -0,0 +1,35 @@ |
||||
--- |
||||
# This Playbook runs all the common plays in the deployment |
||||
|
||||
- name: Create the hosts file for all machines |
||||
template: src=hosts.j2 dest=/etc/hosts |
||||
|
||||
- name: Create the repository for 10Gen |
||||
copy: src=10gen.repo.j2 dest=/etc/yum.repos.d/10gen.repo |
||||
|
||||
- name: Create the EPEL Repository. |
||||
copy: src=epel.repo.j2 dest=/etc/yum.repos.d/epel.repo |
||||
|
||||
- name: Create the GPG key for EPEL |
||||
copy: src=RPM-GPG-KEY-EPEL-6 dest=/etc/pki/rpm-gpg |
||||
|
||||
- name: Create the mongod user |
||||
user: name=mongod comment="MongoD" |
||||
|
||||
- name: Create the data directory for the namenode metadata |
||||
file: path={{ mongodb_datadir_prefix }} owner=mongod group=mongod state=directory |
||||
|
||||
- name: Install the mongodb package |
||||
yum: name={{ item }} state=installed |
||||
with_items: |
||||
- mongo-10gen |
||||
- mongo-10gen-server |
||||
- bc |
||||
- python-pip |
||||
|
||||
- name: Install the latest pymongo package |
||||
pip: name=pymongo state=latest use_mirrors=no |
||||
|
||||
- name: Create the iptables file |
||||
template: src=iptables.j2 dest=/etc/sysconfig/iptables |
||||
notify: restart iptables |
@ -0,0 +1,4 @@ |
||||
127.0.0.1 localhost |
||||
{% for host in groups['all'] %} |
||||
{{ hostvars[host]['ansible_' + iface].ipv4.address }} {{ host }} |
||||
{% endfor %} |
@ -0,0 +1,27 @@ |
||||
# Firewall configuration written by system-config-firewall |
||||
# Manual customization of this file is not recommended. |
||||
*filter |
||||
:INPUT ACCEPT [0:0] |
||||
:FORWARD ACCEPT [0:0] |
||||
:OUTPUT ACCEPT [0:0] |
||||
{% if 'mongoc_servers' in group_names %} |
||||
-A INPUT -p tcp --dport 7777 -j ACCEPT |
||||
{% endif %} |
||||
{% if 'mongos_servers' in group_names %} |
||||
-A INPUT -p tcp --dport 8888 -j ACCEPT |
||||
{% endif %} |
||||
{% if 'mongo_servers' in group_names %} |
||||
{% for host in groups['mongo_servers'] %} |
||||
-A INPUT -p tcp --dport {{ hostvars[host]['mongod_port'] }} -j ACCEPT |
||||
{% endfor %} |
||||
{% endif %} |
||||
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT |
||||
-A INPUT -p icmp -j ACCEPT |
||||
-A INPUT -i lo -j ACCEPT |
||||
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT |
||||
-A INPUT -j REJECT --reject-with icmp-host-prohibited |
||||
-A FORWARD -j REJECT --reject-with icmp-host-prohibited |
||||
COMMIT |
||||
|
||||
|
||||
|
@ -0,0 +1,3 @@ |
||||
qGO6OYb64Uth9p9Tm8s9kqarydmAg1AUdgVz+ecjinaLZ1SlWxXMY1ug8AO7C/Vu |
||||
D8kA3+rE37Gv1GuZyPYi87NSfDhKXo4nJWxI00BxTBppmv2PTzbi7xLCx1+8A1uQ |
||||
4XU0HA |
@ -0,0 +1,26 @@ |
||||
--- |
||||
# This playbook deploys the mongodb configurationdb servers |
||||
|
||||
- name: Create data directory for mongoc configuration server |
||||
file: path={{ mongodb_datadir_prefix }}/configdb state=directory owner=mongod group=mongod |
||||
|
||||
- name: Create the mongo configuration server startup file |
||||
template: src=mongoc.j2 dest=/etc/init.d/mongoc mode=0655 |
||||
|
||||
|
||||
- name: Create the mongo configuration server file |
||||
template: src=mongoc.conf.j2 dest=/etc/mongoc.conf |
||||
|
||||
|
||||
- name: Copy the keyfile for authentication |
||||
copy: src=roles/mongod/files/secret dest={{ mongodb_datadir_prefix }}/secret owner=mongod group=mongod mode=0400 |
||||
|
||||
- name: Start the mongo configuration server service |
||||
command: creates=/var/lock/subsys/mongoc /etc/init.d/mongoc start |
||||
|
||||
- name: pause |
||||
pause: seconds=20 |
||||
|
||||
- name: add the admin user |
||||
mongodb_user: database=admin name=admin password={{ mongo_admin_pass }} login_port={{ mongoc_port }} state=present |
||||
ignore_errors: yes |
@ -0,0 +1 @@ |
||||
db.addUser('admin','{{ mongo_admin_pass }}') |
@ -0,0 +1,17 @@ |
||||
|
||||
#where to log |
||||
logpath=/var/log/mongo/mongod-config.log |
||||
|
||||
logappend=true |
||||
|
||||
# fork and run in background |
||||
fork = true |
||||
|
||||
port = {{ mongoc_port }} |
||||
|
||||
dbpath={{ mongodb_datadir_prefix }}configdb |
||||
keyFile={{ mongodb_datadir_prefix }}secret |
||||
# location of pidfile |
||||
pidfilepath = /var/run/mongoc.pid |
||||
|
||||
configsvr=true |
@ -0,0 +1,94 @@ |
||||
#!/bin/bash |
||||
|
||||
# mongod - Startup script for mongod |
||||
|
||||
# chkconfig: 35 85 15 |
||||
# description: Mongo is a scalable, document-oriented database. |
||||
# processname: mongod |
||||
# config: /etc/mongod.conf |
||||
# pidfile: /var/run/mongo/mongod.pid |
||||
|
||||
. /etc/rc.d/init.d/functions |
||||
|
||||
# things from mongod.conf get there by mongod reading it |
||||
export LC_ALL="C" |
||||
|
||||
# NOTE: if you change any OPTIONS here, you get what you pay for: |
||||
# this script assumes all options are in the config file. |
||||
CONFIGFILE="/etc/mongoc.conf" |
||||
OPTIONS=" -f $CONFIGFILE" |
||||
SYSCONFIG="/etc/sysconfig/mongod" |
||||
|
||||
# FIXME: 1.9.x has a --shutdown flag that parses the config file and |
||||
# shuts down the correct running pid, but that's unavailable in 1.8 |
||||
# for now. This can go away when this script stops supporting 1.8. |
||||
DBPATH=`awk -F= '/^dbpath=/{print $2}' "$CONFIGFILE"` |
||||
PIDFILE=`awk -F= '/^dbpath\s=\s/{print $2}' "$CONFIGFILE"` |
||||
mongod=${MONGOD-/usr/bin/mongod} |
||||
|
||||
MONGO_USER=mongod |
||||
MONGO_GROUP=mongod |
||||
|
||||
if [ -f "$SYSCONFIG" ]; then |
||||
. "$SYSCONFIG" |
||||
fi |
||||
|
||||
# Handle NUMA access to CPUs (SERVER-3574) |
||||
# This verifies the existence of numactl as well as testing that the command works |
||||
NUMACTL_ARGS="--interleave=all" |
||||
if which numactl >/dev/null 2>/dev/null && numactl $NUMACTL_ARGS ls / >/dev/null 2>/dev/null |
||||
then |
||||
NUMACTL="numactl $NUMACTL_ARGS" |
||||
else |
||||
NUMACTL="" |
||||
fi |
||||
|
||||
start() |
||||
{ |
||||
echo -n $"Starting mongod: " |
||||
daemon --user "$MONGO_USER" $NUMACTL $mongod $OPTIONS |
||||
RETVAL=$? |
||||
echo |
||||
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/mongoc |
||||
} |
||||
|
||||
stop() |
||||
{ |
||||
echo -n $"Stopping mongod: " |
||||
killproc -p "$PIDFILE" -d 300 /usr/bin/mongod |
||||
RETVAL=$? |
||||
echo |
||||
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/mongoc |
||||
} |
||||
|
||||
restart () { |
||||
stop |
||||
start |
||||
} |
||||
|
||||
ulimit -n 12000 |
||||
RETVAL=0 |
||||
|
||||
case "$1" in |
||||
start) |
||||
start |
||||
;; |
||||
stop) |
||||
stop |
||||
;; |
||||
restart|reload|force-reload) |
||||
restart |
||||
;; |
||||
condrestart) |
||||
[ -f /var/lock/subsys/mongod ] && restart || : |
||||
;; |
||||
status) |
||||
status $mongod |
||||
RETVAL=$? |
||||
;; |
||||
*) |
||||
echo "Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}" |
||||
RETVAL=1 |
||||
esac |
||||
|
||||
exit $RETVAL |
@ -0,0 +1,3 @@ |
||||
qGO6OYb64Uth9p9Tm8s9kqarydmAg1AUdgVz+ecjinaLZ1SlWxXMY1ug8AO7C/Vu |
||||
D8kA3+rE37Gv1GuZyPYi87NSfDhKXo4nJWxI00BxTBppmv2PTzbi7xLCx1+8A1uQ |
||||
4XU0HA |
@ -0,0 +1,37 @@ |
||||
--- |
||||
# This role deploys the mongod processes and sets up the replication set. |
||||
|
||||
- name: create data directory for mongodb |
||||
file: path={{ mongodb_datadir_prefix }}/mongo-{{ inventory_hostname }} state=directory owner=mongod group=mongod |
||||
delegate_to: '{{ item }}' |
||||
with_items: groups.replication_servers |
||||
|
||||
|
||||
- name: Create the mongodb startup file |
||||
template: src=mongod.j2 dest=/etc/init.d/mongod-{{ inventory_hostname }} mode=0655 |
||||
delegate_to: '{{ item }}' |
||||
with_items: groups.replication_servers |
||||
|
||||
|
||||
- name: Create the mongodb configuration file |
||||
template: src=mongod.conf.j2 dest=/etc/mongod-${inventory_hostname}.conf |
||||
delegate_to: '{{ item }}' |
||||
with_items: groups.replication_servers |
||||
|
||||
- name: Copy the keyfile for authentication |
||||
copy: src=secret dest={{ mongodb_datadir_prefix }}/secret owner=mongod group=mongod mode=0400 |
||||
|
||||
|
||||
- name: Start the mongodb service |
||||
command: creates=/var/lock/subsys/mongod-${inventory_hostname} /etc/init.d/mongod-${inventory_hostname} start |
||||
delegate_to: '{{ item }}' |
||||
with_items: groups.replication_servers |
||||
|
||||
- name: Create the file to initialize the mongod replica set |
||||
template: src=repset_init.j2 dest=/tmp/repset_init.js |
||||
|
||||
- name: Pause for a while |
||||
pause: seconds=20 |
||||
|
||||
- name: Initialize the replication set |
||||
shell: /usr/bin/mongo --port "{{ mongod_port }}" /tmp/repset_init.js |
@ -0,0 +1,15 @@ |
||||
--- |
||||
#This Playbooks adds shards to the mongos servers once everythig is added |
||||
|
||||
|
||||
- name: Create the file to initialize the mongod Shard |
||||
template: src=shard_init.j2 dest=/tmp/shard_init_{{ inventory_hostname }}.js |
||||
delegate_to: '{{ item }}' |
||||
with_items: groups.mongos_servers |
||||
|
||||
- name: Add the shard to the mongos |
||||
shell: /usr/bin/mongo localhost:{{ mongos_port }}/admin -u admin -p {{ mongo_admin_pass }} /tmp/shard_init_{{ inventory_hostname }}.js |
||||
delegate_to: '{{ item }}' |
||||
with_items: groups.mongos_servers |
||||
|
||||
|
@ -0,0 +1,25 @@ |
||||
# mongo.conf |
||||
smallfiles=true |
||||
|
||||
#where to log |
||||
logpath=/var/log/mongo/mongod-{{ inventory_hostname }}.log |
||||
|
||||
logappend=true |
||||
|
||||
# fork and run in background |
||||
fork = true |
||||
|
||||
port = {{ mongod_port }} |
||||
|
||||
dbpath={{ mongodb_datadir_prefix }}mongo-{{ inventory_hostname }} |
||||
keyFile={{ mongodb_datadir_prefix }}/secret |
||||
|
||||
# location of pidfile |
||||
pidfilepath = /var/run/mongod.pid |
||||
|
||||
|
||||
# Ping interval for Mongo monitoring server. |
||||
#mms-interval = <seconds> |
||||
|
||||
# Replication Options |
||||
replSet={{ inventory_hostname }} |
@ -0,0 +1,94 @@ |
||||
#!/bin/bash |
||||
|
||||
# mongod - Startup script for mongod |
||||
|
||||
# chkconfig: 35 85 15 |
||||
# description: Mongo is a scalable, document-oriented database. |
||||
# processname: mongod |
||||
# config: /etc/mongod.conf |
||||
# pidfile: /var/run/mongo/mongod.pid |
||||
|
||||
. /etc/rc.d/init.d/functions |
||||
|
||||
# things from mongod.conf get there by mongod reading it |
||||
export LC_ALL="C" |
||||
|
||||
# NOTE: if you change any OPTIONS here, you get what you pay for: |
||||
# this script assumes all options are in the config file. |
||||
CONFIGFILE="/etc/mongod-{{ inventory_hostname }}.conf" |
||||
OPTIONS=" -f $CONFIGFILE" |
||||
SYSCONFIG="/etc/sysconfig/mongod" |
||||
|
||||
# FIXME: 1.9.x has a --shutdown flag that parses the config file and |
||||
# shuts down the correct running pid, but that's unavailable in 1.8 |
||||
# for now. This can go away when this script stops supporting 1.8. |
||||
DBPATH=`awk -F= '/^dbpath=/{print $2}' "$CONFIGFILE"` |
||||
PIDFILE=`awk -F= '/^dbpath\s=\s/{print $2}' "$CONFIGFILE"` |
||||
mongod=${MONGOD-/usr/bin/mongod} |
||||
|
||||
MONGO_USER=mongod |
||||
MONGO_GROUP=mongod |
||||
|
||||
if [ -f "$SYSCONFIG" ]; then |
||||
. "$SYSCONFIG" |
||||
fi |
||||
|
||||
# Handle NUMA access to CPUs (SERVER-3574) |
||||
# This verifies the existence of numactl as well as testing that the command works |
||||
NUMACTL_ARGS="--interleave=all" |
||||
if which numactl >/dev/null 2>/dev/null && numactl $NUMACTL_ARGS ls / >/dev/null 2>/dev/null |
||||
then |
||||
NUMACTL="numactl $NUMACTL_ARGS" |
||||
else |
||||
NUMACTL="" |
||||
fi |
||||
|
||||
start() |
||||
{ |
||||
echo -n $"Starting mongod: " |
||||
daemon --user "$MONGO_USER" $NUMACTL $mongod $OPTIONS |
||||
RETVAL=$? |
||||
echo |
||||
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/mongod-{{ inventory_hostname }} |
||||
} |
||||
|
||||
stop() |
||||
{ |
||||
echo -n $"Stopping mongod: " |
||||
killproc -p "$PIDFILE" -d 300 /usr/bin/mongod |
||||
RETVAL=$? |
||||
echo |
||||
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/mongod-{{ inventory_hostname }} |
||||
} |
||||
|
||||
restart () { |
||||
stop |
||||
start |
||||
} |
||||
|
||||
ulimit -n 12000 |
||||
RETVAL=0 |
||||
|
||||
case "$1" in |
||||
start) |
||||
start |
||||
;; |
||||
stop) |
||||
stop |
||||
;; |
||||
restart|reload|force-reload) |
||||
restart |
||||
;; |
||||
condrestart) |
||||
[ -f /var/lock/subsys/mongod ] && restart || : |
||||
;; |
||||
status) |
||||
status $mongod |
||||
RETVAL=$? |
||||
;; |
||||
*) |
||||
echo "Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}" |
||||
RETVAL=1 |
||||
esac |
||||
|
||||
exit $RETVAL |
@ -0,0 +1,7 @@ |
||||
rs.initiate() |
||||
sleep(13000) |
||||
{% for host in groups['replication_servers'] %} |
||||
rs.add("{{ host }}:{{ mongod_port }}") |
||||
sleep(8000) |
||||
{% endfor %} |
||||
printjson(rs.status()) |
@ -0,0 +1,2 @@ |
||||
sh.addShard("{{ inventory_hostname}}/{{ inventory_hostname }}:{{ mongod_port }}") |
||||
printjson(rs.status()) |
@ -0,0 +1,3 @@ |
||||
qGO6OYb64Uth9p9Tm8s9kqarydmAg1AUdgVz+ecjinaLZ1SlWxXMY1ug8AO7C/Vu |
||||
D8kA3+rE37Gv1GuZyPYi87NSfDhKXo4nJWxI00BxTBppmv2PTzbi7xLCx1+8A1uQ |
||||
4XU0HA |
@ -0,0 +1,23 @@ |
||||
--- |
||||
#This Playbook configures the mongos service of mongodb |
||||
|
||||
- name: Create the mongos startup file |
||||
template: src=mongos.j2 dest=/etc/init.d/mongos mode=0655 |
||||
|
||||
|
||||
- name: Create the mongos configuration file |
||||
template: src=mongos.conf.j2 dest=/etc/mongos.conf |
||||
|
||||
- name: Copy the keyfile for authentication |
||||
copy: src=roles/mongod/files/secret dest={{ mongodb_datadir_prefix }}/secret owner=mongod group=mongod mode=0400 |
||||
|
||||
- name: Start the mongos service |
||||
command: creates=/var/lock/subsys/mongos /etc/init.d/mongos start |
||||
- name: pause |
||||
pause: seconds=20 |
||||
|
||||
- name: copy the file for shard test |
||||
template: src=testsharding.j2 dest=/tmp/testsharding.js |
||||
|
||||
- name: copy the file enable sharding |
||||
template: src=enablesharding.j2 dest=/tmp/enablesharding.js |
@ -0,0 +1,3 @@ |
||||
db.runCommand( { enableSharding : "test" } ) |
||||
db.runCommand( { shardCollection : "test.test_collection", key : {"number":1} }) |
||||
|
@ -0,0 +1,23 @@ |
||||
#where to log |
||||
logpath=/var/log/mongo/mongos.log |
||||
|
||||
logappend=true |
||||
|
||||
# fork and run in background |
||||
fork = true |
||||
|
||||
port = {{ mongos_port }} |
||||
{% set hosts = '' %} |
||||
{% for host in groups['mongoc_servers'] %} |
||||
{% if loop.last %} |
||||
{% set hosts = hosts + host + ':' ~ mongoc_port %} |
||||
configdb = {{ hosts }} |
||||
{% else %} |
||||
{% set hosts = hosts + host + ':' ~ mongoc_port + ',' %} |
||||
{% endif %} |
||||
{% endfor %} |
||||
|
||||
# location of pidfile |
||||
pidfilepath = /var/run/mongodb/mongos.pid |
||||
keyFile={{ mongodb_datadir_prefix }}/secret |
||||
chunkSize={{ mongos_chunk_size }} |
@ -0,0 +1,95 @@ |
||||
#!/bin/bash |
||||
|
||||
# mongod - Startup script for mongod |
||||
|
||||
# chkconfig: 35 85 15 |
||||
# description: Mongo is a scalable, document-oriented database. |
||||
# processname: mongod |
||||
# config: /etc/mongod.conf |
||||
# pidfile: /var/run/mongo/mongod.pid |
||||
|
||||
. /etc/rc.d/init.d/functions |
||||
|
||||
# things from mongod.conf get there by mongod reading it |
||||
export LC_ALL="C" |
||||
|
||||
# NOTE: if you change any OPTIONS here, you get what you pay for: |
||||
# this script assumes all options are in the config file. |
||||
CONFIGFILE="/etc/mongos.conf" |
||||
OPTIONS=" -f $CONFIGFILE" |
||||
SYSCONFIG="/etc/sysconfig/mongod" |
||||
|
||||
# FIXME: 1.9.x has a --shutdown flag that parses the config file and |
||||
# shuts down the correct running pid, but that's unavailable in 1.8 |
||||
# for now. This can go away when this script stops supporting 1.8. |
||||
DBPATH=`awk -F= '/^dbpath=/{print $2}' "$CONFIGFILE"` |
||||
PIDFILE=`awk -F= '/^dbpath\s=\s/{print $2}' "$CONFIGFILE"` |
||||
mongod=${MONGOD-/usr/bin/mongos} |
||||
|
||||
MONGO_USER=mongod |
||||
MONGO_GROUP=mongod |
||||
|
||||
if [ -f "$SYSCONFIG" ]; then |
||||
. "$SYSCONFIG" |
||||
fi |
||||
|
||||
# Handle NUMA access to CPUs (SERVER-3574) |
||||
# This verifies the existence of numactl as well as testing that the command works |
||||
NUMACTL_ARGS="--interleave=all" |
||||
if which numactl >/dev/null 2>/dev/null && numactl $NUMACTL_ARGS ls / >/dev/null 2>/dev/null |
||||
then |
||||
NUMACTL="numactl $NUMACTL_ARGS" |
||||
else |
||||
NUMACTL="" |
||||
fi |
||||
|
||||
start() |
||||
{ |
||||
echo -n $"Starting mongod: " |
||||
daemon --user "$MONGO_USER" $NUMACTL $mongod $OPTIONS |
||||
RETVAL=$? |
||||
echo |
||||
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/mongos |
||||
} |
||||
|
||||
stop() |
||||
{ |
||||
echo -n $"Stopping mongod: " |
||||
killproc -p "$PIDFILE" -d 300 /usr/bin/mongos |
||||
RETVAL=$? |
||||
echo |
||||
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/mongos |
||||
} |
||||
|
||||
restart () { |
||||
stop |
||||
start |
||||
} |
||||
|
||||
ulimit -n 12000 |
||||
RETVAL=0 |
||||
|
||||
case "$1" in |
||||
start) |
||||
start |
||||
;; |
||||
stop) |
||||
stop |
||||
;; |
||||
restart|reload|force-reload) |
||||
restart |
||||
;; |
||||
condrestart) |
||||
[ -f /var/lock/subsys/mongod ] && restart || : |
||||
;; |
||||
status) |
||||
status $mongod |
||||
RETVAL=$? |
||||
;; |
||||
*) |
||||
echo "Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}" |
||||
RETVAL=1 |
||||
esac |
||||
|
||||
exit $RETVAL |
||||
|
@ -0,0 +1,12 @@ |
||||
people = ["Marc", "Bill", "George", "Eliot", "Matt", "Trey", "Tracy", "Greg", "Steve", "Kristina", "Katie", "Jeff"]; |
||||
|
||||
for(var i=0; i<100000; i++){ |
||||
name = people[Math.floor(Math.random()*people.length)]; |
||||
user_id = i; |
||||
boolean = [true, false][Math.floor(Math.random()*2)]; |
||||
added_at = new Date(); |
||||
number = Math.floor(Math.random()*10001); |
||||
db.test_collection.save({"name":name, "user_id":user_id, "boolean": boolean, "added_at":added_at, "number":number }); |
||||
} |
||||
db.test_collection.ensureIndex({number:1}) |
||||
|
@ -0,0 +1,22 @@ |
||||
--- |
||||
# This Playbook would deploy the whole mongodb cluster with replication and sharding. |
||||
|
||||
- hosts: all |
||||
roles: |
||||
- role: common |
||||
|
||||
- hosts: mongo_servers |
||||
roles: |
||||
- role: mongod |
||||
|
||||
- hosts: mongoc_servers |
||||
roles: |
||||
- role: mongoc |
||||
|
||||
- hosts: mongos_servers |
||||
roles: |
||||
- role: mongos |
||||
|
||||
- hosts: mongo_servers |
||||
tasks: |
||||
- include: roles/mongod/tasks/shards.yml |
Reference in new issue