Showing posts with label MongoDB. Show all posts
Showing posts with label MongoDB. Show all posts

Tuesday, February 19, 2013

mongoDB design tips(3)


1. UTF-8 support.
a.MongoDB regex queries support UTF-8 in the regex string.
b.Currently, sort() on a string uses strcmp: sort order will be reasonable but not fully international correct.
Future versions of MongoDB may support full UTF-8 sort ordering.

2.don’t support Sequence Numbers, but you can use following method(careful using on sharding):
  function counter(name) {
var ret = db.counters.findAndModify({query:{_id:name}, update:{$inc : {next:1}}, "new":true,
upsert:true});
// ret == { "_id" : "users", "next" : 1 }
return ret.next;
}
db.users.insert({_id:counter("users"), name:"Sarah C."}) // _id : 1
db.users.insert({_id:counter("users"), name:"Bob D."}) // _id : 2
//repeat
3. Collections number limitation.
By default MongoDB has a limit of approximately 24,000 namespaces per database. Each namespace is 628 bytes, the .ns file is 16MB by default. If more collections are required, run mongod with the --nssize parameter specified. This will make the <database>.ns file larger and support more collections. Note that --nssize sets the size used for newly created .ns files -- if you have an existing database and wish to resize, after running the db with --nssize, run the db.repairDatabase() command from the shell to adjust the size.
Maximum .ns file size is 2GB.
Be aware that there is a certain minimum overhead per collection -- a few KB. Further, any index will require at least 8KB of data space as the b-tree page size is 8KB. Certain operations can get slow if there are a lot of collections and the meta data gets paged out.

4.Keys Too Large To Index
Index entries have a limitation on their maximum size (the sum of the values), currently 1024 bytes (prior to v2.0 the maximum size was 819bytes). Documents whose fields have values (key size in index terminology) greater than this size cannot be indexed.

5.Index limitation:
     Object has a Index(a,b,c)
a. The sort column must be the last column used in the index.
  Good:
find(a=1).sort(a)
find(a=1).sort(b)
find(a=1, b=2).sort(c)
Bad:
find(a=1).sort(c)
even though c is the last column used in the index, a is that last column used, so you can only sort on a or b.
b. The range query must also be the last column in an index. This is an axiom of 1 above.
   Good:
  find(a=1,b>2)
        find(a>1 and a<10)
        find(a>1 and a<10).sort(a)
Bad:
  find(a>1, b=2)
c. Only use a range query or sort on one column.
     Good:
find(a=1,b=2).sort(c)
find(a=1,b>2)
find(a=1,b>2 and b<4)
find(a=1,b>2).sort(b)
Bad:
find(a>1,b>2)
find(a=1,b>2).sort(c)
d. Conserve indexes by re-ordering columns used on equality (non-range) queries.
   Imagine you have the following two queries:
find(a=1,b=1,d=1)
find(a=1,b=1,c=1,d=1)
A single index defined on a, b, c, and d can be used for both queries.
If, however, you need to sort on the final value, you might need two indexes

e. MongoDB's $ne or $nin operator's aren't efficient with indexes.
When excluding just a few documents, it's better to retrieve extra rows from MongoDB and do the exclusion on the client side.

6.Pay attention to the read/write ratio of your application.
This is important because, whenever you add an index, you add overhead to all insert, update, and delete operations on the given collection. If your application is read-heavy, as are most web applications, the additional indexes are usually a good thing. But if your application is write-heavy, then be careful when creating new indexes, since each additional index with impose a small write-performance penalty.
In general, don't be cavalier about adding indexes. Indexes should be added to complement your queries. Always have a good reason for adding a new index, and make sure you've benchmarked alternative strategies.

7. Key names limitation
     a. The '$' character must not be the first character in the key name.
b. The '.' character must not appear anywhere in the key name.

8. Schema design Summary of Best Practices
a."First class" objects, that are at top level, typically have their own collection.
b. Line item detail objects typically are embedded.
c. Objects which follow an object modelling "contains" relationship should generally be embedded.
d. Many to many relationships are generally done by linking.
e. Collections with only a few objects may safely exist as separate collections, as the whole collection is quickly cached in application server memory.
f. Embedded objects are a bit harder to link to than "top level" objects in collections.
g. It is more difficult to get a system-level view for embedded objects. When needed an operation of this sort is performed by using MongoDB's map/reduce facility.
h. If the amount of data to embed is huge (many megabytes), you may reach the limit on size of a single object.
I. If performance is an issue, embed.
When you Write the java program for mongo ,please notice it as following.

9.   use requestStart and requestDone.
In turns the read operation may not see the data just written since replication is asynchronous. If you want to ensure complete consistency in a "session" (maybe an http request), you would want the driver to use the same socket, which you can achieve by using a "consistent request". Call requestStart() before your operations and requestDone() to release the connection back to the pool.
example codes:
DB db...;
db.requestStart();
db.requestEnsureConnection();
code....
db.requestDone();
10.   WriteConcern option for single write operation
Since by default a connection is given back to the pool after each request, you may wonder how calling getLastError() works after a write. You
should actually use a write concern like WriteConcern.SAFE instead of calling getLastError() manually. The driver will then call getLastError()
before putting the connection back in the pool.
WriteConcern.NONE : No exceptions thrown.
WriteConcern.NORMAL : Exceptions are only thrown when the primary node is unreachable for a read, or the full replica set is unreachable.
WriteConcern.SAFE : Same as the above, but exceptions thrown when there is a server error on writes or reads. Calls getLastError().
WriteConcern.REPLICAS_SAFE : Tries to write to two separate nodes. Same as the above, but will throw an exception if two writes are not possible.
WriteConcern.FSYNC_SAFE : Same as WriteConcern.SAFE, but also waits for write to be written to disk.
example codes:
DBCollection coll...;
coll.insert(..., WriteConcern.SAFE);
// is equivalent to
DB db...;
DBCollection coll...;
db.requestStart();
coll.insert(...);
DBObject err = db.getLastError();
db.requestDone();
11.   Saving Objects Using DBObject
The Java driver provides a DBObject interface to save custom objects to the database.
Example codes:
public class Tweet implements DBObject {
/* ... */
}
Then you can:
Tweet myTweet = new Tweet();
myTweet.put("user", userId);
myTweet.put("message", msg);
myTweet.put("date", new Date());
collection.insert(myTweet);
     When a document is retrieved from the database, it is automatically converted to a DBObject. To convert it to an instance of your class, use
DBCollection.setObjectClass():
   collection.setObjectClass(Tweet.class);
Tweet myTweet = (Tweet)collection.findOne();
     If for some reason you wanted to change the message you can simply take that tweet and save it back after updating the field.
        Tweet myTweet = (Tweet)collection.findOne();
myTweet.put("message", newMsg);
collection.save(myTweet);
12.   How to insert embedded document.
BasicDBObject doc = new BasicDBObject();
doc.put("name", "MongoDB");
doc.put("type", "database");
doc.put("count", 1);
BasicDBObject info = new BasicDBObject();
info.put("x", 203);
info.put("y", 102);
doc.put("info", info);
coll.insert(doc);
13.   How to insert array?
{
"x" :
   [
    1,
    2,
    {"foo" : "bar"},
    4
    ]
}
ArrayList x = new ArrayList();
x.add(1);
x.add(2);
x.add(new BasicDBObject("foo", "bar"));
x.add(4);
BasicDBObject doc = new BasicDBObject("x", x);
14.   Adding Multiple Documents
{
"i" : value
}
and we can do this fairly efficiently in a loop
        for (int i=0; i < 100; i++) {
coll.insert(new BasicDBObject().append("i", i));
}

15.   Regular Expressions
Pattern john = Pattern.compile("joh?n", CASE_INSENSITIVE);
BasicDBObject query = new BasicDBObject("name", john);
// finds all people with "name" matching /joh?n/i
DBCursor cursor = collection.find(query);

mongoDB design tips(2)


1.    Optimizing Object IDs(using mongodb ObjectId() method, BSON ObjectId's begin with a timestamp)
The _id field in a MongoDB document is very important and is always indexed for normal collections. This page lists some recommendations.
Note that it is common to use the BSON ObjectID datatype for _id's, but the values of an _id field can be of any type.Use the collections 'natural primary key' in the _id field._id's can be any type, so if your objects have a natural unique identifier, consider using that in _id to both save space and avoid an additional index.When possible, use _id values that are roughly in ascending order. If the _id's are in a somewhat well defined order, on inserts the entire b-tree for the _id index need not be loaded. BSON ObjectIds have this property. Store Binary GUIDs as BinData, rather than as hex encoded strings
BSON includes a binary data datatype for storing byte arrays. Using this will make the id values, and their respective keys in the _id index, twice as small.
Note that unlike the BSON Object ID type (see above), most UUIDs do not have a rough ascending order, which creates additional caching needs for their index.

2.    Optimizing Storage.
a.    Using the _id Field Explicitly
Mongo automatically adds an object ID to each document and sets it to a unique value. Additionally this field in indexed. For tiny objects this takes up significant space.
The best way to optimize for this is to use _id explicitly. Take one of your fields which is unique for the collection and store its values in _id. By doing so, you have explicitly provided IDs. This will effectively eliminate the creation of a separate _id field. If your previously separate field was
indexed, this eliminates an extra index too.

b.    Using Small Field Names
Consider a record
{ last_name : "Smith", best_score: 3.9 }
The strings "last_name" and "best_score" will be stored in each object's BSON. Using shorter strings would save space:
{ lname : "Smith", score : 3.9 }
Field names are not stored in indexes as indexes have a predefined structure. Thus, shortening field names will not help the size of indexes. In
general it is not necessary to use short field names.

3.    Querying and nulls
> db.foo.insert( { x : 1, y : 1 } )
> db.foo.insert( { x : 2, y : "string" } )
> db.foo.insert( { x : 3, y : null } )
> db.foo.insert( { x : 4 } )
// Query #1
> db.foo.find( { "y" : null } )
{ "_id" : ObjectId("4dc1975312c677fc83b5629f"), "x" : 3, "y" : null }
{ "_id" : ObjectId("4dc1975a12c677fc83b562a0"), "x" : 4 }
// Query #2
> db.foo.find( { "y" : { $type : 10 } } )
{ "_id" : ObjectId("4dc1975312c677fc83b5629f"), "x" : 3, "y" : null }
// Query #3
> db.foo.find( { "y" : { $exists : false } } )
{ "_id" : ObjectId("4dc1975a12c677fc83b562a0"), "x" : 4 }
To summarize the three queries:
documents where y has the value null or where y does not exist
documents where y has the value null
documents where y does not exist

4.    Field Negation
// get all posts about 'tennis' but without the comments field
db.posts.find( { tags : 'tennis' }, { comments : 0 } );

5.    Covered Indexes
Mongod will automatically use covered index when it can. But be sure that:
a. you provide list of fields to return, so that it can determine that it can be covered by index
b. you must explicitly exclude the _id field by using {_id: 0} (unless the index includes that)
c. as soon as you insert one array value for one of the index keys, the index will immediately become a multikey index and this disables covered index functionality
    d. use Explain to determine if the covered index is used: the indexOnly field should be true

6.    Retrieving a Subrange of Array Elements
You can use the $slice operator to retrieve a subrange of elements in an array.
  db.posts.find({}, {comments:{$slice: 5}}) // first 5 comments
  db.posts.find({}, {comments:{$slice: -5}}) // last 5 comments
  db.posts.find({}, {comments:{$slice: [20, 10]}}) // skip 20, limit 10
  db.posts.find({}, {comments:{$slice: [-20, 10]}}) // 20 from end, limit 10
Filtering with $slice does not affect other fields inclusion/exclusion. It only applies within the array being sliced.
     db.posts.find({}, {_id:1, comments:{$slice: 5}}) // first 5 comments, and the _id field only


7.    Sharding scales reads better than replication
Replication doesn't scale writes at all, but it can add some scalability as different servers can service queries. Use sharding to scale out. Sharding
scales queries just as well as writes, and tends to make better use of the cluster's total ram than replication would.

8.    When in doubt, query the primary only
Consider the diagram below as an example.



A client in the primary data center could use slaveOk for reads, querying from both Svr1 and Svr2. However there are several things to consider in this situation:
Are eventually consistent reads ok when you hit Svr2?
Do you expect to be able to continue to run in Data Center 1 if one of the (Svr1/Svr2) pair is down? If so, and you need both for query load normally, won't you be overcapacity if one box goes down? That is, there is not n+1 capacity in Data Center 1. Likewise if two are needed in DC1, you probably need 2 for DR also. One could counter that one server has sufficient and that using two is just "a little faster" in terms of latency; however, it is then very hard to notice if one server truly has enough capacity to handle the entire load.
    Do you have real time alerts if replication is lagging. Imagine a bad ethernet cable on Svr2 and it is 2 hours behind realtime on its data. You probably do not want to be querying it then.

One argument for using slaveOk would be graceful degradation in failure scenarios. During replica set failover, 20+ seconds could pass before a new primary is elected. With slaveOk you can read during that period. In addition, if your system were badly broken (two servers down) the third would be readable, but not be primary as a majority is needed to elect a primary. One best practice is to run querying primaries only but have built into your app a "read only mode" you can enable in an emergency (such as a disaster) so that reads are still possible; in that mode slaveOk would be used.

Good uses of slaveOk
slaveOk does have its uses.
    Secondaries are great for doing dumps and backups and running reports without slowing down your front end app / production system.
    Secondaries in remote data centers are useful for low latency local queries

9.    BSON type.
db.things.find( { a : { $type : 2 } } ); // matches if a is a string
db.things.find( { a : { $type : 16 } } ); // matches if a is an int

10.  Regular Expressions
i - Case insensitive. Letters in the pattern match both upper and lower case letters.
m - Multiline. By default, Mongo treats the subject string as consisting of a single line of characters (even if it actually contains newlines).
The "start of line" metacharacter (^) matches only at the start of the string, while the "end of line" metacharacter ($) matches only at the
end of the string, or before a terminating newline.When m it is set, the "start of line" and "end of line" constructs match immediately following or immediately before internal newlines in the
subject string, respectively, as well as at the very start and end. If there are no newlines in a subject string, or no occurrences of ^ or $ in
a pattern, setting m has no effect.
x - Extended. If set, whitespace data characters in the pattern are totally ignored except when escaped or inside a character class.
Whitespace does not include the VT character (code 11). In addition, characters between an unescaped # outside a character class and
the next newline, inclusive, are also ignored.
This option makes it possible to include comments inside complicated patterns. Note, however, that this applies only to data characters.
Whitespace characters may never appear within special character sequences in a pattern, for example within the sequence (?( which
introduces a conditional subpattern.
s - Dot all. New in 1.9.0. Allows the dot (.) to

11.  Mongo Meta query operators
Only return the index key:
     db.foo.find()._addSpecial("$returnKey" , true )

Show disk location of results:
     db.foo.find()._addSpecial("$showDiskLoc" , true)

Force query to use the given index:
     db.foo.find()._addSpecial("$hint", {_id : 1})

12.  Matching with $elemMatch
// Document 1
{ "foo" : [
{
"shape" : "square",
"color" : "purple",
"thick" : false
},
{
"shape" : "circle",
"color" : "red",
"thick" : true
}
] }

// Document 2
{ "foo" : [
{
"shape" : "square",
"color" : "red",
"thick" : true
},
{
"shape" : "circle",
"color" : "purple",
"thick" : false
}
You want to query for a purple square, and so you write the following:
  db.foo.find({"foo.shape": "square", "foo.color": "purple"})
  or
  db.foo.find({foo: {"shape": "square", "color": "purple"} } )
      The problem with this query is that it will match the second in addition to matching the first document. In other words, the standard query syntax
won't restrict itself to a single document within the foo array. As mentioned above, subobjects have to match exactly.
To match an entire document within the foo array, you need to use $elemMatch. To properly query for a purple square, you'd use $elemMatch like
so:
db.foo.find({foo: {"$elemMatch": {shape: "square", color: "purple"}}})
The query will return the first document, which contains the purple square you're looking for.

13.  Atomic Operations
MongoDB supports atomic operations on single documents. MongoDB does not support traditional locking and complex transactions for a
number of reasons:
First, in sharded environments, distributed locks could be expensive and slow. Mongo DB's goal is to be lightweight and fast.
We dislike the concept of deadlocks. We want the system to be simple and predictable without these sort of surprises.
We want Mongo DB to work well for realtime problems. If an operation may execute which locks large amounts of data, it might stop
some small light queries for an extended period of time. (We don't claim Mongo DB is perfect yet in regards to being "real-time", but we
certainly think locking would make it even harder.)
The Mongo DB update command supports several modifiers, all of which atomically update an element in a document. They include:
$set - set a particular value
$unset - delete a particular field (v1.3+)
$inc - increment a particular value by a certain amount
$push - append a value to an array
$pushAll - append several values to an array
$pull - remove a value(s) from an existing array
$pullAll - remove several value(s) from an existing array
$bit - bitwise operations
These modifiers are convenient ways to perform certain operations atomically.
Another strategy for atomic updates is "Update if Current".
This is what an OS person would call Compare and Swap. For this we
1.Fetch the object.
2.Modify the object locally.
3.Send an update request that says "update the object to this new value if it still matches its old value".
Should the operation fail, we might then want to try again from step 1.

14.  The ABA Nuance
However, what if since our read, object had been modified?
We would then overwrite that change and lose it!
There are several ways to avoid this problem ; it's mainly just a matter of being aware of the nuance.
a. Use the entire object in the update's query expression, instead of just the _id and qty field.
b. Use $set to set the field we care about. If other fields have changed, they won't be affected.
c. Put a version variable in the object, and increment it on each update.
d. When possible, use a $ operator instead of an update-if-current sequence of operations.
15.  Operations Lock Type

16.  How many times is data written to disk when replication and journaling are both on?
In v1.8, for an insert, four times. The object is written to the main collection, and also the oplog collection (so that is twice). Both of those writes
are journaled as a single mini-transaction in the journal file (the files in /data/db/journal). Thus 4 times total.
There is an open item in to reduce this by having the journal be compressed. This will reduce from 4x to probably ~2.5x.
The above applies to collection data and inserts which is the worst case scenario. Index updates are written to the index and the journal, but not
the oplog, so they should be 2X today not 4X. Likewise updates with things like $set, $addToSet, $inc, etc. are compactly logged all around so
those are generally small.

17.  Prealloc Files
mongod will create prealloc files in the journal directory under some circumstances to minimize journal write latency. On some filesystems,
appending to a file and making it larger can be slower than writing to a file of a predefined size. mongod checks this at startup and if it finds this to
be the case will use preallocated journal files. If found to be helpful, a small pool of prealloc files will be created in the journal directory before
startup begins. This is a one time initiation and does not occur with future invocations. Approximately 3GB of files will be preallocated (and truly
prewritten, not sparse allocated) - thus in this situation, expect roughly a 3 minute delay on the first startup to preallocate these files.
If you don't want to wait three minutes on startup, you can preallocate the files using another instance of mongod and then move them to your
normal dbpath before starting with journaling.

mongoDB design tips(1)


1.    Linux File Systems

MongoDB uses large files for storing data, and preallocates these. These filesystems seem to work well:
ext4 ( kernel version >= 2.6.23 )
xfs ( kernel version >= 2.6.25 )
In addition to the file systems above you might also want to (explicitly) disable file/directory modification times by using these mount options:
noatime (also enables nodiratime)
We have found ext3 to be very slow in allocating files (or removing them) as well as access within large files is also poor.

2.    What Hardware?
MongoDB tends to run well on virtually all hardware. In fact it was designed specifically with commodity hardware in mind (to facilitate cloud
computing); that said it works well on very large servers too. That said if you are about to buy hardware here are a few suggestions:
1.Fast CPU clock speed is helpful.
2.Many cores helps but does not provide a high level of marginal return, so don't spend money on them. (This is both a consequence of the
design of the program and also that memory bandwidth can be a limiter; there isn't necessarily a lot of computation happening inside a
database).
3.NUMA is not very helpful as memory access is not very localized in a database. Thus non-NUMA is recommended; or configure NUMA
as detailed elsewhere in this document.
4.RAM is good.
5.SSD is good. We have had good results and have seen good price/performance with SATA SSDs; the (typically) more upscale PCI SSDs
work fine too.
6.Commodity (SATA) spinning drives are often a good option as the speed increase for random I/O for more expensive drives is not that
dramatic (only on the order of 2x) – spending that money on SSDs or RAM may be more effective.
3.    PCI vs. SATA
SSD is available both as PCI cards and SATA drives. PCI is oriented towards the high end of products on the market.
Some SATA SSD drives now support 6Gbps sata transfer rates, yet at the time of this writing many controllers shipped with servers are 3Gbps.
For random IO oriented applications this is likely sufficient, but worth considering regardless.
4.    RAM vs. SSD
Even though SSDs are fast, RAM is still faster. Thus for the highest performance possible, having enough RAM to contain the working set of data
from the database is optimal. However, it is common to have a request rate that is easily met by the speed of random IO's with SSDs, and SSD
cost per byte is lower than RAM (and persistent too).
A system with less RAM and SSDs will likely outperform a system with more RAM and spinning disks. For example a system with SSD drives and
64GB RAM will often outperform a system with 128GB RAM and spinning disks. (Results will vary by use case of course.)
One helpful characteristic of SSDs is they can facilitate fast "preheat" of RAM on a hardware restart. On a restart a system's RAM file system
cache must be repopulated. On a box with 64GB RAM or more, this can take a considerable amount of time – for example six minutes at
100MB/sec, and much longer when the requests are random IO to spinning disks.

5.    FlashCache
FlashCache is a write back block cache for Linux. It was created by Facebook. Installation is a bit of work as you have to build and install a kernel
module. Sep2011: If you use this please report results in the mongo forum as it's new and everyone will be curious how well it works.

6.    OS scheduler
One user reports good results with the noop IO scheduler under certain configurations of their system. As always caution is recommended on
nonstandard configurations as such configurations never get as much testing...

7.    Virtualization
Generally MongoDB works very well in virtualized environments, with the exception of OpenVZ.


8.    Replication
Two forms of replication are available, Replica Sets and Master-Slave. Use Replica Sets – replica sets are a functional superset of master/slave and are handled by much newer, more robust code.




9.    Replica Set Design Concepts

majority of the set is not up or reachable, no member will be elected primary.
There is no way to tell (from the set's point of view) the difference between a network partition and nodes going down, so members left in a
minority will not attempt to become master (to prevent a set from ending up with masters on either side of a partition).
This means that, if there is no majority on either side of a network partition, the set will be read only (thus, we suggest an odd number of servers:
e.g., two servers in one data center and one in another). The upshot of this strategy is that data is consistent: there are no multi-master conflicts
to resolve.
There are several important concepts concerning data integrity with replica sets that you should be aware of:
1. A write is (cluster-wide) committed once it has replicated to a majority of members of the set.
For important writes, the client should request acknowledgement of this with a getLastError({w:...}) call. (If you do not call getLastError,
the servers do exactly the same thing; the getlasterror call is simply to get confirmation that committing is finished.)
For important writes, use the getLastError to ensure cluster-wide commits of critical writes.
2. Queries in MongoDB and replica sets have "READ UNCOMMITTED" semantics.
Writes which are committed at the primary of the set may be visible before the cluster-wide commit completes.
The read uncommitted semantics (an option on many databases) are more relaxed and make theoretically achievable performance and
availability higher (for example we never have an object locked in the server where the locking is dependent on network performance).
3. On a failover, if there are writes which have not replicated from the primary, the writes are rolled back. Thus we use getlasterror as in #1
above when we need to confirm a cluster-wide commit.
The data is backed up to files in the rollback directory, although the assumption is that in most cases this data is never recovered as that would
require operator intervention. However, it is not "lost," it can be manually applied at any time with mongorestore.
Rationale
Merging back old operations later, after another node has accepted writes, is a hard problem. One then has multi-master replication, with potential
for conflicting writes. Typically that is handled in other products by manual version reconciliation code by developers. We think that is too much
work : we want MongoDB usage to be less developer work, not more. Multi-master also can make atomic operation semantics problematic.
It is possible (as mentioned above) to manually recover these events, via manual DBA effort, but we believe in large system with many, many
nodes that such efforts become impractical.
Comments
Some drivers support 'safe' write modes for critical writes. For example via setWriteConcern in the Java driver.
Additionally, defaults for { w : ... } parameter to getLastError can be set in the replica set's configuration.
Note a call to getLastError will cause the client to have to wait for a response from the server. This can slow the client's throughput on writes if
large numbers are made because of the client/server network turnaround times. Thus for "non-critical" writes it often makes sense to make no
getLastError check at all, or only a single check after many writes.

10.  Replica Set Commands

11.  Forcing a Member to be Primary
In v2.0+,For example, if we had members A, B, and C and A is the current primary and we want B to be primary, we could give B a higher priority like so:
> config = rs.conf()
{
"_id" : "foo",
"version" : 1,
"members" : [
{
"_id" : 0,
"host" : "A",
},
{
"_id" : 1,
"host" : "B",
},
{
"_id" : 2,
"host" : "C",
}
]
}
> config.version++
> // the default priority is 1
> config.members[1].priority = 2
> rs.reconfig(config)
Assuming B is synced to within 10 seconds of A, A will step down, B (and C) will catch up to where A is, and B will be elected primary.
If B is far behind A, A will not step down until B is within 10 seconds of its optime. This minimizes the amount of time there will be no primary on
failover. If you do not care about how long the set is primary-less, you can force A to step down by running:
db.adminCommand({replSetStepDown:1000000, force:1})


12.  Changing Config Servers

Best Practices
A.Use three config servers.
B.Give them logical (DNS) names. Do not refer to them (on the mongos ocmmand line) by IP address.
C.The DNS name should be logical (e.g. "mycluster_config2") not a name that is VM-specific.
Use a short DNS TTL (20 seconds or example).
D.Act slowly when replacing a config server – your system should be fine with one down. Better to not have an operational typo and to let
one be down for a while. If one is down, take some time and read this page, consider opening a support ticket, etc., before taking action.
The metadata for the cluster is very important.
E.When replacing a config server, make sure the old process/machine is truly down before starting up the new one. There may be legacy
sockets open to the old config server process otherwise, and that would be bad.

13.  Simple Initial Sharding Architecture
Goal
Two datacenters (East=primary, West=backup/DR)
Data Tier (MongoDB)
3 shards
3 nodes per shard
9 hosts total
Application Tier
4 application servers
Machines Locations
e1-e6 are in 1 datacenter (East)
     w1-w3 are in another datacenter (West)
Datacenter Roles
We'll use datacenter East as the primary, and data center West as disaster recovery.


14.  Licensing

Database:
Free Software Foundation's GNU AGPL v3.0.
Commercial licenses are also available from 10gen, including free evaluation licenses.
Drivers:
 mongodb.org supported drivers: Apache License v2.0.
   Third parties have created drivers too; licenses will vary there.