Tải bản đầy đủ - 0 (trang)
Inspecting an Instance’s Status with rs.status()

Inspecting an Instance’s Status with rs.status()

Tải bản đầy đủ - 0trang


The myState field shown in the preceding example has the values shown in Table 11–10. These

values indicate the status of any member you run the rs.status() command against.

Table 11–10. Values for the myState Field




Member is starting up and is in phase 1.


Member is operating as a primary (master) server.


Member is operating as a secondary server.


Member is recovering; the sysadmin has restarted the member server in recovery

mode after a possible crash or other data issue.


Member has encountered a Fatal Error; the errMsg field in the members array for this

server should show more details about the problem.


Member is starting up and has reached phase 2.


Member is in an unknown state; this could indicate a misconfigured replica set,

where some servers are not reachable by all other members.


Member is operating as an arbiter.


Member is down or otherwise unreachable. The lastheartbeat timestamp in the

member array associated with this server should provide the date/time that the

server was last seen alive.

In the preceding example, the rs.status() command is run against the primary server member. The

information returned for this command shows that the primary server is operating with a myState value

of 1; in other words, the “Member is operating as a primary (master).”

Forcing a New Election with rs.stepDown()

You can use the rs.stepDown() command to force a primary server to stand down; the command also

forces the election of a new primary server. This command is useful in the following situations:

You would like to take the server hosting the primary instance offline, whether to

investigate the server or to implement hardware upgrades or maintenance.

You would like to run a diagnostic process against the data structures.

You would like to simulate the effect of a primary failure and force your cluster to

fail over, enabling you to test how your application responds to such an event.

The following example shows the output returned if you run the rs.stepDown() command against

the testset replica set:




Download from Wow! eBook

> rs.stepDown()

{ "ok" : 1 }

> rs.status()


"set" : "testset",

"date" : "Sat Jul 31 2010 12:57:14 GMT+0800 (PHT)",

"myState" : 2,

"members" : [


"name" : "[hostname]:27021",

"self" : true,

"errmsg" : ""



"name" : "[hostname]:27023",

"health" : 1,

"uptime" : 2446,

"lastHeartbeat" : "Sat Jul 31 2010 12:57:13 GMT+0800 (PHT)",

"errmsg" : "initial sync done"



"name" : "[hostname]:27022",

"health" : 1,

"uptime" : 2450,

"lastHeartbeat" : "Sat Jul 31 2010 12:57:13 GMT+0800 (PHT)",

"errmsg" : ""



"ok" : 1


In the preceding example, you run the rs.stepDown() command against the primary server. The

output of the rs.status() command shows that the server now has a myState value of 2: “Member is

operating as secondary.”

Determining If a Member is the Primary Server

The db.isMaster() command isn’t strictly a replica set command. Nevertheless, this command is

extremely useful because it allows an application to test whether it is connected to a master/primary




"ismaster" : false,

"secondary" : true,

"msg" : "",

"hosts" : [




"passives" : [






"primary" : "[hostname]",

"ok" : 1


If you run isMaster() against your testset replica set cluster at this point, it shows that the server

you have run it against is not a master/primary server (“ismaster” == false). If the server instance you

run this command against is a member of a replica set, the command will also return a map of the

known server instances in the set, including the roles of the individual servers in that set.

Configuring the Options for Replica Set Members

The replica set functionality ships with a number of options you can use to control the behavior of a

replica set’s members. When you run the rs.initiate(replSetcfg) or rs.add(membercfg) options, you

have to supply a configuration structure that describes the characteristics of a replica set’s members:


_id : ,

members: [


_id : ,

host : ,

[, priority: ]

[, arbiterOnly : true]

[, votes : ]


, ...


settings: {

[heartbeatSleep : ]

[, heartbeatTimeout : ]

[, heartbeatConnRetries : ]

[, getLastErrorDefaults: ]



For rs.initiate(), you should supply the full configuration structure, as shown in the preceding

example. The topmost level of the configuration structure itself includes three levels: _id, members, and

settings. The _id is the name of the replica set, as supplied with the --replSet command-line option

when you create the replica set members. The members array consists of a set of structures that describe

each member of the set; this is the member structure that you supply to the rs.add() command when

adding an individual server to the set. Finally, the settings array contains options that apply to the

entire replica set.

Organization of the Members Structure

The members structure contains all the entries required to configure each of the member instances of the

replica set; you can see all of these entries listed in Table 11–11.




Table 11–11. Configuring Member Server Properties




(Mandatory) Integer: This element specifies the ordinal position of the

member structure in the member array. Possible values for this element

include integers greater than or equal to 0. This value enables you to address

specific member structures, so you can perform add, remove, and overwrite



(Mandatory) String: This element specifies the name of the server in the

form host:port; note that the host portion cannot be localhost or


(Optional) Float: The element represents the weight assigned to the server

when elections for a new primary server are conducted. If the primary server

becomes unavailable, then a secondary server will be promoted based on

this value. Any secondary server with a non-zero value is considered to be

active and eligible to become a primary server. Thus, setting this value to

zero forces the secondary to become passive. If multiple secondary servers

share equal priority, then a vote will be taken, and an arbiter (if configured)

may be called upon to resolve any deadlocks. The default value for this

element is 1.0, unless you specify otherwise.


(Optional) Boolean: This member operates as an arbiter for electing new

primary servers. It is not involved in any other function of the replica set,

and it does not need to have been started with a --replSet command-line

option. Any running mongod process in your system can perform this task.

The default value of this element is false.


(Optional) Integer: This element specifies the number of votes that this

instance can cast to elect other instances as a primary server; the default

value of this element is 1.

Exploring the Options Available in the Settings Structure

Table 11–12 lists the replica set properties available in the Settings structure. These settings are applied

globally to the entire replica set; you use these properties to configure how replica set members

communicate with each other.




Table 11–12. Inter-server Communication Properties for the Settings Structure




(Optional) Integer: This element specifies how often the members of

the replica set should announce themselves to each other, and its

value is expressed in milliseconds. If not specified, this element has a

default value of 2000 (2 seconds).


(Optional) Integer: This element specifies the amount of time that the

members of a replica set should wait after not hearing from a specific

member before assuming it is unavailable. This value is expressed in

milliseconds; if not specified, this element has a default value of 10000

(10 seconds).


(Optional) Integer: The element specifies the number of attempts a

member should make to reach another member before assuming it is

down. If not specified, this element has a default value of 3.

Determining the Status of Replica Sets

Replica sets are only becoming available as a stable implementation in the very latest version of

MongoDB (1.6.x) at the time of writing.

10gen (the company that produces MongoDB) is very proactive in rolling out enhancements, so it is

a good idea to peruse the online documentation to see what has changed since this book’s publication.

For up-to-the-minute information on replica sets, visit this page on the MongoDB site:


You should keep in mind the fact that, from version 1.6.x onwards, replica sets will become the

preferred mechanism for setting up replicated clusters of machines, and the simpler “Replica Pairs” will

become deprecated.

Connecting to a Replica Set from Your Application

Connecting to a replica set from PHP is similar to connecting to a single MongoDB instance. The only

difference is that it can provide either a single replica set instance address or a list of replica set

members; the connection library will work out which server is the primary server and direct queries to

that machine, even if the primary server is not one of the members that you provide. The following

example shows how to connect to a replica set from a PHP application:

$m = new Mongo("mongodb://localhost:27021,

localhost:27022", array("replicaSet" => true));






Viewing Replica Set Status with the Web Interface

MongoDB maintains a web-based console for viewing the status of your system. For our previous

example, you can access this console by opening the URL http://localhost:28021 with your web

browser. The port number of the web interface is set by default to port n+1000, where n is the port

number of your instance. So, assuming your primary instance is on port 27021, as in this chapter’s

example, its web interface can be found on port 28021. If you open this interface in your web browser,

you will see a link to the status of the replica set at the top of the page (see Figure 11–9).

Figure 11–9. Viewing the status of the replica set in a browser

Clicking the Replica set status link will take you to the Replica Set dashboard shown in Figure


Figure 11–10. The replica set dashboard in the MongoDB web interface





MongoDB provides a rich set of tools for implementing a wide range of clustering and replication

topologies. In this chapter, you learned about many of these tools, including some of the reasons and

motivations for using them. You also learned how to set up a number of different replication topologies,

from the simplest replication configuration all the way through to the latest, most advanced replica set

capability introduced in the most recent version of MongoDB. Additionally, you learned how to inspect

the status of replication systems using both the command-line tools and the built-in web interface.

Please take the time required to evaluate each of the topologies described in this chapter to make

sure you choose the one best suited to your particular needs before attempting to use any of them in a

production environment. It is incredibly easy to use MongoDB to create test beds on a single machine;

therefore, you are strongly encouraged to experiment with each method to make sure that you fully

understand the benefits and limitations of each approach, including how it will perform with your

particular data and application.




C H A P T E R 12



Whether you’re building the next Facebook or just a simple database application, you will probably need

to scale your app up at some point if it’s successful. If you don’t want to be continually replacing your

hardware, then you will want to use a technique that allows you to add capacity incrementally to your

system, as you need it. Sharding is a technique that allows you to spread your data across multiple

machines, yet does so in a way that mimics an app hitting a single database.

Ideally suited for the new generation of cloud-based computing platforms, sharding as

implemented by MongoDB is perfect for dynamic, load-sensitive automatic scaling, where you ramp up

your capacity as you need it and turn it down when you don’t.

This chapter will walk you through implementing sharding in MongoDB.

Exploring the Need for Sharding

When the World Wide Web was just getting under way, the number of sites, users, and the amount of

information available online was low. The Web consisted of a few thousand sites and a population of

only tens or perhaps hundreds of thousands of users predominantly centered on the academic and

research communities. In those early days, data tended to be simple: hand-maintained HTML

documents connected together by hyperlinks. The original design objective of the protocols that make

up the Web was to provide a means of creating navigable references to documents stored on different

servers around the Internet.

Even current big brand names such as Yahoo had only a minuscule presence on the Web compared

to its offerings today. The Yahoo directory that comprised the original product around which the

company was formed was little more than a network of hand-edited links to popular sites. These links

were maintained by a small but enthusiastic band of people called the surfers. Each page in the Yahoo

directory was a simple HTML document stored in a tree of filesystem directories and maintained using a

simple text editor.

But as the size of the net started to explode—and the number of sites and visitors started its nearvertical climb upwards—the sheer volume of resources available forced the early Web pioneers to move

away from simple documents to more complex dynamic page generation from separate data stores.

Search engines started to spider the Web and pull together databases of links that today number in

the hundreds of billions of links and tens of billions of stored pages.

These developments prompted the movement to datasets managed and maintained by evolving

content management systems that were stored mainly in databases for easier access.

At the same time, new kinds of services evolved that stored more than just documents and link sets.

For example, audio, video, events, and all kinds of other data started to make its way into these huge

datastores. This is often described as the “industrialization of data”—and in many ways it shares

parallels with the evolution of the industrial revolution centered on manufacturing during the 19th


Eventually, every successful company on the Web faces the problem of how to access the data

stored in these mammoth databases. They find that there are only so many queries per second that can




be handled with a single database server, and network interfaces and disk drives can only transfer so

many megabytes per second to and from the web servers. Companies that provide web-based services

can quickly find themselves exceeding the performance of a single server, network, or drive array. In

such cases, they are compelled to divide and distribute their massive collections of data. The usual

solution is to partition these mammoth chunks of data into smaller pieces that can be managed more

reliably and quickly. At the same time, these companies need to maintain the ability to perform

operations across the entire breadth of the data held in their large clusters of machines.

Replication, which you learned about in some detail in Chapter 11, can be an effective tool for

overcoming some of these scaling issues, enabling you to create multiple copies of your data in multiple

servers. This enables you to spread out your server load across more machines.

Before long, however, you run headlong into another problem, where the size of the individual tables

or collections that make up your data set grow so large that they exceed the capacity of a single database

system to manage them effectively. For example, Flickr announced that on October 12th 2009 it had

received its 4 billionth photo, and the site is now well on its way to crossing the 10 billion photos mark.

Attempting to store the details of 10 billion photos in one table is not feasible, so Flickr looked at

ways of distributing that set of records across a large number of database servers. The solution adopted

by Flickr serves as one of the better-documented (and publicized) implementations of sharding in the

real world.

Partitioning Horizontal and Vertical Data

Data partitioning is the mechanism of splitting data across multiple independent datastores. Those

datastores can be co-resident (on the same system) or remote (on separate systems). The motivation for

co-resident partitioning is to reduce the size of individual indices and reduce the amount of I/O that is

needed to update records. The motivation for remote partitioning is to increase the bandwidth of access

to data, by having more network interfaces and disc data I/O channels available.

Partitioning Data Vertically

In the traditional view of databases, data is stored in rows and columns. Vertical partitioning consists of

breaking up a record on column boundaries and storing the parts in separate tables or collections. It can

be argued that a relational database design that uses joined tables with a one-to-one relationship is a

form of co-resident vertical data partitioning.

MongoDB, however, does not lend itself to this form of partitioning because the structure of its

records (documents) does not fit the nice and tidy row and column model. Therefore, there are few

opportunities to cleanly separate a row based on its column boundaries. MongoDB also promotes the

use of embedded documents, and it does not directly support the ability to join associated collections


Partitioning Data Horizontally

Horizontal partitioning is where all the action is when using MongoDB, and sharding is the common

term for a popular form of horizontal partitioning. Sharding allows you to split a collection across

multiple servers to improve performance in a collection that has a large number of documents in it.

A simple example of sharding occurs when a collection of user records is divided across a set of

servers, so that all the records for people with last names that begin with the letters A–G are on one

server, H–M are on another, and so on. The rule that splits the data is known as the sharding key

function, or the data hashing function.

In simple terms, sharding allows you to treat the cloud of shards as through it were a single

collection, and an application does not need to be aware that the data is distributed across multiple




machines. Traditional sharding implementations require the application to be actively involved in

determining which server a particular document is stored on, so it can route its requests properly.

Traditionally, there is a library bound to the application, and this library is responsible for storing and

querying data in sharded data sets.

MongoDB is virtually unique in its support for auto-sharding, where the database server manages

the splitting of the data and the routing of requests to the required shard server. If a query requires data

from multiple shards, then MongoDB will manage the process of merging the data obtained from each

shard back into a single cursor.

This feature, more than any other, is what earns MongoDB its stripes as a cloud or web-oriented


Analyzing a Simple Sharding Scenario

Let’s assume you want to implement a simple sharding solution for a fictitious Gaelic social network.

Figure 12–1 shows a simplified representation of how this application could be sharded.

Figure 12–1. Simple sharding of a User collection

There are a number of problems with this simplified view of our application. Let’s look at the most

obvious ones.

First, if your Gaelic network is targeted at the Irish and Scottish communities around the world, then

the database will have a large number of names that start with Mac and Mc (e.g., MacDonald, McDougal,

and so on) for the Scottish population and O’ (e.g., O’Reilly, O’Conner, and so on) for the Irish

population. Thus, using the simple sharding key function based on the first letter of the last name will



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Inspecting an Instance’s Status with rs.status()

Tải bản đầy đủ ngay(0 tr)