Buscar

Mostrando entradas con la etiqueta mongoDB_4_DBA_HomeWork. Mostrar todas las entradas
Mostrando entradas con la etiqueta mongoDB_4_DBA_HomeWork. Mostrar todas las entradas

martes, 17 de febrero de 2015

MongoDB for DBA's 6/7. Scalability. Homeworks

Homework 6.1

For this week's homework we will start with a standalone MongoDB database, turn it into a sharded cluster with two shards, and shard one of the collections. We will create a "dev" environment on our local box: no replica sets, and only one config server. In production you would almost always use three config servers and replica sets as part of a sharded cluster. In the final of the course we'll set up a larger cluster with replica sets and three config servers.
Download week6.js from Download Handout link.
Start an initially empty mongod database instance.
Connect to it with the shell and week6.js loaded:
mongo --shell localhost/week6 week6.js
Run homework.init(). It will take some time to run as it inserts quite a few documents. When it is done run
db.trades.stats()
to check the status of the collection. 
At this point we have a single mongod and would like to transform it into a sharded cluster with one shard. (We'll use this node’s existing week6.trades data in the cluster.)
Stop the mongod process. Now, restart the mongod process adding the option --shardsvr. If you started mongod with a --dbpath option, specify that as well.
mongod --shardsvr …

sudo mongod --shardsvr --dbpath /var/lib/mongodb --logpath /var/log/mongodb/mongod00.log --port 27018 --fork --logappend --smallfiles --oplogSize 50

Note that with --shardsvr specified the default port for mongod becomes 27018.
Start a mongo config server:
mongod --configsvr …

sudo mongod --configsvr --dbpath /var/lib/mongodb/configdb --port 27019 --fork --logpath /var/log/mongodb/mongod00.log.cfg0 --logappend

(Note with --configsvr specified the default port for listening becomes 27019 and the default data directory /data/configdb. Wherever your data directory is, it is suggested that you verify that the directory is empty before you begin.)
Start a mongos:
mongos --configdb your_host_name:27019
Connect to mongos with the shell:
mongo --shell localhost/week6 week6.js
Add the first shard ("your_host_name:27018").

sh.addShard("localhost:27018")
{ "shardAdded" : "shard0000", "ok" : 1 }

Verify that the week6.trades data is visible via mongos. Note at this point the week6 database isn't "sharding enabled" but its data is still visible via mongos:
> db.trades.find().pretty()
> db.trades.count()
> db.trades.stats()
Run homework.a() and enter the result below. This method will simply verify that this simple cluster is up and running and return a result key.

Result: 1000001


Homework 6.2

Now enable sharding for the week6 database. (See sh.help() for details.)
sh.enableSharding("week6")
{ "ok" : 1 }
Then shard the trades collection on the compound shard key ticker plus time. Note to shard a collection, you must have an index on the shard key, so you will need to create the index first:
> db.trades.ensureIndex( { ticker:1, time:1 } )
> // can now shard the trades collection on the shard key  { ticker:1, time:1 } 

sh.shardCollection("week6.trades",{ ticker:1, time:1 })

After sharding the collection, look at the chunks which exist:
> use config
> db.chunks.find()
> // or:
> db.chunks.find({}, {min:1,max:1,shard:1,_id:0,ns:1})
Run homework.b() to verify the above and enter the return value below.


Result : 3


Homework 6.3

Let's now add a new shard. Run another mongod as the new shard on a new port number. Use --shardsvr.
sudo mongod --shardsvr --dbpath /var/lib/mongodb/a1 --logpath /var/log/mongodb/mongod01.log --port 27020 --fork --logappend --smallfiles --oplogSize 50 --journal
Then add the shard to the cluster (see sh.help()).
sh.addShard( "localhost:27020")
You can confirm the above worked by running:
homework.check1()



mongos> homework.check1()
db.getSisterDB("config").shards.count() : 
2
There are 2 shards in the cluster as expected

Now wait for the balancer to move data among the two shards more evenly. Periodically run:
> use config
> db.chunks.find( { ns:"week6.trades" }, {min:1,max:1,shard:1,_id:0} ).sort({min:1})
and/or:
db.chunks.aggregate( [
 { $match : { ns : "week6.trades" } } , 
 { $group : { _id : "$shard", n : { $sum : 1 } } }
] )
When done, run homework.c() and enter the result value.That completes this week's homework. However if you want to explore more, something to try would be to try some queries and/or write operations with a single process down to see how the system behaves in such a situation. 

Result: 2

miércoles, 4 de febrero de 2015

MongoDB for DBA's 5/7. Replication Part 2. Homeworks

Homework 5.1

Set up a replica set that includes an arbiter.
To demonstrate that you have done this, what is the text in the "state" field for the arbiter when you run rs.status()?
Status : 7

Homework 5.2


You have a replica set with two members, having decided that a total of two copies of your data is sufficient.
You are concerned about robustness, however.
Which of the following are options that will allow you to ensure that failover can occur if the firstserver goes down?
Check all that apply.


Homework 5.3


At the beginning of the section, "W Timeout and Capacity Planning", Dwight mentioned something that hasn't yet been touched upon in this class: Batch Inserts.
He mentions that you can find information on them in the docs, but he hasn't used them in the shell during this course.
Your job is to look this functionality up in the documentation, and use it for the following problem:
Please insert into the m102 collection, the following 3 documents, using only one shell query (please use double quotes around each key in each document in your answer):
  • { "a" : 1 }
  • { "b" : 2 }
  • { "c" : 3 }
Hints: This is not the same as the Bulk() operations, which were discussed earlier in this course. Also, this does not involve semicolons, so don't put any into the text box. You probably want to test this on your machine, and then copy and paste the insert query in the box below. Do not include the > sign from the beginning of the shell.

Result: db.m102.insert([{"a":1},{"b":2},{"c":3}])

Homework 5.4


You would like to create a replica set that is robust to data center failure.
You only have two data centers available. Which arrangement(s) of servers will allow you to be stay up (as in, still able to elect a primary) in the event of a failure of either data center (but not both at once)? Check all that apply.


Homework 5.5


Consider the following scenario: You have a two member replica set, a primary, and a secondary.
The data center with the primary goes down, and is expected to remain down for the foreseeable future. Your secondary is now the only copy of your data, and it is not accepting writes. You want to reconfigure your replica set config to exclude the primary, and allow your secondary to be elected, but you run into trouble. Find out the optional parameter that you'll need, and input it into the box below for your rs.reconfigure(new_cfg, OPTIONAL PARAMETER).
Hint: You may want to use this documentation page to solve this problem.
Your answer should be of the form { key : value } (including brackets).

Result: { force : true }

viernes, 30 de enero de 2015

MongoDB for DBA's 4/7. Replication. Homeworks

Homework 4.1

In this chapter’s homework we will create a replica set and add some data to it.
1. Unpack replication.js from the Download Handout zip file.
2. We will create a three member replica set. Pick a root working directory to work in. Go to that directory in a console window.
Given we will have three members in the set, and three mongod processes, create three data directories:
mkdir 1
mkdir 2
mkdir 3
3. We will now start a single mongod as a standalone server. Given we will have three mongod processes on our single test server, we will explicitly specify the port numbers (this wouldn’t be necessary if we had three real machines or three virtual machines). We’ll also use the --smallfiles parameter and --oplogSize so the files are small given we have a lot of server processes running on our test PC.
$ # starting as a standalone server for problem 1:
$ mongod --dbpath 1 --port 27001 --smallfiles --oplogSize 50
Note: for all mongod startups in the homework this chapter, you can optionally use --logPath, --logappend, and --fork. Or, since this is just an exercise on a local PC, you could simply have a separate terminal window for all and forgo those settings. Run “mongod --help” for more info on those.
mongod --dbpath 1 --port 27001 --smallfiles --logpath log.1 --logappend --fork --oplogSize 50
mongod --dbpath 2 --port 27002 --smallfiles --logpath log.2 --logappend --fork --oplogSize 50
mongod --dbpath 3 --port 27003 --smallfiles --logpath log.3 --logappend --fork --oplogSize 50

To know pid mongo processes:

ps -Aef | grep mongod

To kill mongod processes

kill pid

4. In a separate terminal window (cmd.exe on Windows), run the mongo shell with the replication.js file:
mongo --port 27001 --shell replication.js
Then run in the shell:
> homework.init()
This will load a small amount of test data into the database.
Now run:
 > homework.a()

and enter the result. This will simply confirm all the above happened ok.

result: 5001


Homework 4.2

Now convert the mongod instance (the one in the problem 4.1 above, which uses “--dbpath 1”) to a single server replica set. To do this, you’ll need to stop the mongod (NOT the mongo shell instance) and restart it with “--replSet” on its command line. Give the set any name you like.
ps -Aef | grep mongod

mongodb   1009     1  0 09:25 ?        00:00:05 /usr/bin/mongod --config /etc/mongod.conf
user  3260  2009  0 09:42 ?        00:00:02 mongod --dbpath 1 --port 27001 --smallfiles --logpath log.1 --logappend --fork --oplogSize 50
user  3272  2009  0 09:43 ?        00:00:01 mongod --dbpath 2 --port 27002 --smallfiles --logpath log.2 --logappend --fork --oplogSize 50
user  3284  2009  0 09:43 ?        00:00:01 mongod --dbpath 3 --port 27003 --smallfiles --logpath log.3 --logappend --fork --oplogSize 50

user  3360  3221  0 09:48 pts/0    00:00:00 grep --color=auto mongod

To kill mongod processes

kill 3260

mongod --replSet abc --dbpath 1 --port 27001 --smallfiles --logpath log.1 --logappend --fork --oplogSize 50
Then go to the mongo shell. Once there, run
> rs.initiate()
> rs.initiate()
{
"info2" : "no configuration explicitly specified -- making one",
"me" : "SERVER:27001",
"info" : "Config now saved locally.  Should come online in about a minute.",
"ok" : 1
}
rs.status()
{
"set" : "abc",
"date" : ISODate("2015-01-30T08:55:02Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "SERVER:27001",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 364,
"optime" : Timestamp(1422607970, 1),
"optimeDate" : ISODate("2015-01-30T08:52:50Z"),
"electionTime" : Timestamp(1422607970, 2),
"electionDate" : ISODate("2015-01-30T08:52:50Z"),
"self" : true
}
],
"ok" : 1
}
abc:PRIMARY> rs.conf()
{
"_id" : "abc",
"version" : 1,
"members" : [
{
"_id" : 0,
"host" : "SERVER:27001"
}
]
}
When you first ran homework.init(), we loaded some data into the mongod. You should see it in the replication database. You can confirm with:
> use replication
> db.foo.find()
Once done with that, run
> homework.b()

in the mongo shell and enter that result below.
result: 5002

Homework 4.3

Now add two more members to the set. Use the 2/ and 3/ directories we created in homework 4.1. Run those two mongod’s on ports 27002 and 27003 respectively (the exact numbers could be different).
Remember to use the same replica set name as you used for the first member.
kill 3272 3484
mongod --replSet abc --dbpath 2 --port 27002 --smallfiles --logpath log.2 --logappend --fork --oplogSize 50
mongod --replSet abc --dbpath 3 --port 27003 --smallfiles --logpath log.3 --logappend --fork --oplogSize 50
You will need to add these two new members to your replica set, which will initially have only one member. In the shell running on the first member, you can see your replica set status with
> rs.status()
Initially it will have just that first member. Connecting to the other members will involve using
rs.add()
. For example,
> rs.add("localhost:27002")
You'll know it's added when you see an
{ "ok" : 1 }
document.
Your machine may or may not be OK with 'localhost'. If it isn't, try using the name in the "members.name" field in the document you get by calling rs.status() (but remember to use the correct port!).
abc:PRIMARY> rs.conf()
{
"_id" : "abc",
"version" : 3,
"members" : [
{
"_id" : 0,
"host" : "SERVER:27001"
},
{
"_id" : 1,
"host" : "SERVER:27002"
},
{
"_id" : 2,
"host" : "SERVER:27003"
}
]
}
Once a secondary has spun up, you can connect to it with a new mongo shell instance.
mongo --port 27002
Use
rs.slaveOk()
to let the shell know you're OK with (potentially) stale data, and run some queries. You can also insert data on your primary and then read it out on your secondary. Once the servers have sync'd with the primary and are caught up, run (on your primary):
> homework.c()
and enter the result below.

result: 5


Homework 4.4

We will now remove the first member (@ port 27001) from the set.
As a first step to doing this we will shut it down. (Given the rest of the set can maintain a majority, we can still do a majority reconfiguration if it is down.)
We could simply terminate its mongod process, but if we use the replSetStepDown command, the failover may be faster. That is a good practice, though not essential. Connect to member 1 (port 27001) in the shell and run:
> rs.stepDown()
Then cleanly terminate the mongod process for member 1.
abc:SECONDARY> rs.status()
{
"set" : "abc",
"date" : ISODate("2015-01-30T09:42:11Z"),
"myState" : 2,
"syncingTo" : "SERVER:27003",
"members" : [
{
"_id" : 0,
"name" : "SERVER:27001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 621,
"optime" : Timestamp(1422610708, 149),
"optimeDate" : ISODate("2015-01-30T09:38:28Z"),
"infoMessage" : "syncing to: SERVER:27003",
"self" : true
},
{
"_id" : 1,
"name" : "SERVER:27002",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 398,
"optime" : Timestamp(1422610708, 149),
"optimeDate" : ISODate("2015-01-30T09:38:28Z"),
"lastHeartbeat" : ISODate("2015-01-30T09:42:10Z"),
"lastHeartbeatRecv" : ISODate("2015-01-30T09:42:11Z"),
"pingMs" : 0,
"lastHeartbeatMessage" : "syncing to: SERVER:27001",
"syncingTo" : "SERVER:27001"
},
{
"_id" : 2,
"name" : "SERVER:27003",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 394,
"optime" : Timestamp(1422610708, 149),
"optimeDate" : ISODate("2015-01-30T09:38:28Z"),
"lastHeartbeat" : ISODate("2015-01-30T09:42:11Z"),
"lastHeartbeatRecv" : ISODate("2015-01-30T09:42:11Z"),
"pingMs" : 0,
"electionTime" : Timestamp(1422610890, 1),
"electionDate" : ISODate("2015-01-30T09:41:30Z")
}
],
"ok" : 1
}
Next, go to the new primary of the set. You will probably need to connect with the mongo shell, which you'll want to run with '--shell replication.js' since we'll be getting the homework solution from there. 
mongo --port 27003 --shell replication.js
Once you are connected, run rs.status() to check that things are as you expect. Then reconfigure to remove member 1.
Tip: You can either use rs.reconfig() with your new configuration that does not contain the first member, or rs.remove(), specifying the host:port of the server you wish to remove as a string for the input.
rs.remove("SERVER:27001")
When done, run
> homework.d()
and enter the result.
Tip: If you ran the shell without replication.js on the command line, restart the shell with it.
 result: 6


Homework 4.5

Note our replica set now has an even number of members, and that is not a best practice. However, to keep the homework from getting too long we’ll leave it at that for now, and instead do one more exercise below involving the oplog.
To get the right answer on this problem, you must perform the homework questions in order. Otherwise, your oplog may look different than we expect.
Go to the secondary in the replica set. The shell should say SECONDARY at the prompt if you've done everything correctly.
mongo --port 27002 --shell replication.js
Switch to the local database and then look at the oplog:
> db.oplog.rs.find()
If you get a blank result, you are not on the right database.
Note: as the local database doesn’t replicate, it will let you query it without entering “rs.slaveOk()” first.
Next look at the stats on the oplog to get a feel for its size:
> db.oplog.rs.stats()
What result does this expression give when evaluated?
db.oplog.rs.find().sort({$natural:1}).limit(1).next().o.msg[0]

 result: R