Configure Replica Set Tag Sets

Tag sets let you customize write concern and read preferences for a replica set. MongoDB stores tag sets in the replica set configuration object, which is the document returned by rs.conf(), in the members[n].tags embedded document.

This section introduces the configuration of tag sets. For an overview on tag sets and their use, see w: <tag set> and Tag Sets.

Differences Between Read Preferences and Write Concerns

Custom read preferences and write concerns evaluate tags sets in different ways:

  • Read preferences consider the value of a tag when selecting a member to read from.
  • Write concerns do not use the value of a tag to select a member except to consider whether or not the value is unique.

For example, a tag set for a read operation may resemble the following document:

{ "disk": "ssd", "use": "reporting" }

To fulfill such a read operation, a member would need to have both of these tags. Any of the following tag sets would satisfy this requirement:

{ "disk": "ssd", "use": "reporting" }
{ "disk": "ssd", "use": "reporting", "rack": "a" }
{ "disk": "ssd", "use": "reporting", "rack": "d" }
{ "disk": "ssd", "use": "reporting", "mem": "r"}

The following tag sets would not be able to fulfill this query:

{ "disk": "ssd" }
{ "use": "reporting" }
{ "disk": "ssd", "use": "production" }
{ "disk": "ssd", "use": "production", "rack": "k" }
{ "disk": "spinning", "use": "reporting", "mem": "32" }

Add Tag Sets to a Replica Set

Given the following replica set configuration:

{
    "_id" : "rs0",
    "version" : 1,
    "members" : [
             {
                     "_id" : 0,
                     "host" : "mongodb0.example.net:27017"
             },
             {
                     "_id" : 1,
                     "host" : "mongodb1.example.net:27017"
             },
             {
                     "_id" : 2,
                     "host" : "mongodb2.example.net:27017"
             }
     ]
}

You could add tag sets to the members of this replica set with the following command sequence in the mongo shell:

conf = rs.conf()
conf.members[0].tags = { "dc": "east", "use": "production"  }
conf.members[1].tags = { "dc": "east", "use": "reporting"  }
conf.members[2].tags = { "use": "production"  }
rs.reconfig(conf)

After this operation the output of rs.conf() would resemble the following:

{
    "_id" : "rs0",
    "version" : 2,
    "members" : [
             {
                     "_id" : 0,
                     "host" : "mongodb0.example.net:27017",
                     "tags" : {
                             "dc": "east",
                             "use": "production"
                     }
             },
             {
                     "_id" : 1,
                     "host" : "mongodb1.example.net:27017",
                     "tags" : {
                             "dc": "east",
                             "use": "reporting"
                     }
             },
             {
                     "_id" : 2,
                     "host" : "mongodb2.example.net:27017",
                     "tags" : {
                             "use": "production"
                     }
             }
     ]
}

Important

In tag sets, all tag values must be strings.

Custom Multi-Datacenter Write Concerns

Given a five member replica set with members in two data centers:

  1. a facility VA tagged dc_va
  2. a facility GTO tagged dc_gto

Create a custom write concern to require confirmation from two data centers using replica set tags, using the following sequence of operations in the mongo shell:

  1. Create a replica set configuration JavaScript object conf:

    conf = rs.conf()
    
  2. Add tags to the replica set members reflecting their locations:

    conf.members[0].tags = { "dc_va": "rack1"}
    conf.members[1].tags = { "dc_va": "rack2"}
    conf.members[2].tags = { "dc_gto": "rack1"}
    conf.members[3].tags = { "dc_gto": "rack2"}
    conf.members[4].tags = { "dc_va": "rack1"}
    rs.reconfig(conf)
    
  3. Create a custom settings.getLastErrorModes setting to ensure that the write operation will propagate to at least one member of each facility:

    conf.settings = { getLastErrorModes: { MultipleDC : { "dc_va": 1, "dc_gto": 1 } } }
    
  4. Reconfigure the replica set using the modified conf configuration object:

    rs.reconfig(conf)
    

To ensure that a write operation propagates to at least one member of the set in both data centers, use the MultipleDC write concern mode as follows:

db.users.insert( { id: "xyz", status: "A" }, { writeConcern: { w: "MultipleDC" } } )

Alternatively, if you want to ensure that each write operation propagates to at least 2 racks in each facility, reconfigure the replica set as follows in the mongo shell:

  1. Create a replica set configuration object conf:

    conf = rs.conf()
    
  2. Redefine the settings.getLastErrorModes value to require two different values of both dc_va and dc_gto:

    conf.settings = { getLastErrorModes: { MultipleDC : { "dc_va": 2, "dc_gto": 2}}
    
  3. Reconfigure the replica set using the modified conf configuration object:

    rs.reconfig(conf)
    

Now, the following write operation will only return after the write operation propagates to at least two different racks in the each facility:

Changed in version 2.6: A new protocol for write operations integrates write concerns with the write operations. Previous versions used the getLastError command to specify the write concerns.

db.users.insert( { id: "xyz", status: "A" }, { writeConcern: { w: "MultipleDC" } } )

Configure Tag Sets for Functional Segregation of Read and Write Operations

Given a replica set with tag sets that reflect:

  • data center facility,
  • physical rack location of instance, and
  • storage system (i.e. disk) type.

Where each member of the set has a tag set that resembles one of the following: [1]

{"dc_va": "rack1", disk:"ssd", ssd: "installed" }
{"dc_va": "rack2", disk:"raid"}
{"dc_gto": "rack1", disk:"ssd", ssd: "installed" }
{"dc_gto": "rack2", disk:"raid"}
{"dc_va": "rack1", disk:"ssd", ssd: "installed" }

To target a read operation to a member of the replica set with a disk type of ssd, you could use the following tag set:

{ disk: "ssd" }

However, to create comparable write concern modes, you would specify a different set of settings.getLastErrorModes configuration. Consider the following sequence of operations in the mongo shell:

  1. Create a replica set configuration object conf:

    conf = rs.conf()
    
  2. Redefine the settings.getLastErrorModes value to configure two write concern modes:

    conf.settings = {
                     "getLastErrorModes" : {
                             "ssd" : {
                                        "ssd" : 1
                             },
                             "MultipleDC" : {
                                     "dc_va" : 1,
                                    "dc_gto" : 1
                             }
                     }
                   }
    
  3. Reconfigure the replica set using the modified conf configuration object:

    rs.reconfig(conf)
    

Now you can specify the MultipleDC write concern mode, as in the following, to ensure that a write operation propagates to each data center.

Changed in version 2.6: A new protocol for write operations integrates write concerns with the write operations. Previous versions used the getLastError command to specify the write concerns.

db.users.insert( { id: "xyz", status: "A" }, { writeConcern: { w: "MultipleDC" } } )

Additionally, you can specify the ssd write concern mode to ensure that a write operation propagates to at least one instance with an SSD.

[1]Since read preferences and write concerns use the value of fields in tag sets differently, larger deployments may have some redundancy.