diff --git a/source/administration/operational-segregation.txt b/source/administration/operational-segregation.txt index 7ef6293637d..308dfdf6e8d 100644 --- a/source/administration/operational-segregation.txt +++ b/source/administration/operational-segregation.txt @@ -2,8 +2,6 @@ Location and Operational Segregation in MongoDB Operations and Deployments ========================================================================== -.. rename this file /administration/operational-segregation.txt - .. default-domain:: mongodb Operational Overview @@ -33,7 +31,7 @@ Specifically, with MongoDB, you can: - ensure that specific members of a replica set respond to queries. - ensure that specific ranges of your :term:`shard key` balance onto and - reside on specific :term:`shards`. + reside on specific :term:`shard`. - combine the above features in a single distributed deployment, on a per-operation (for read and write operations) and collection (for @@ -65,19 +63,21 @@ documentation in the MongoDB Manual: Before adding operational segregation features to your application and MongoDB deployment, become familiar with all documentation of :doc:`replication ` and :doc:`sharding `, - particularly :doc:`/core/replication` and :doc:`/core/sharding`. + particularly :doc:`/core/replication` and :doc:`/core/sharded-clusters`. + +.. TODO uncomment this section when we can write content for it: -Examples of Operational Segregation ------------------------------------ + Examples of Operational Segregation + ----------------------------------- -Increase Data Locality in Geographically Distributed Cluster -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Increase Data Locality in Geographically Distributed Cluster + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Functional Segregation for Reporting and Backups -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Functional Segregation for Reporting and Backups + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Increase Read Locality for Distributed Applications -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Increase Read Locality for Distributed Applications + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Ensure Geographical Redundancy for Write Operations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Ensure Geographical Redundancy for Write Operations + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/source/administration/tag-aware-sharding.txt b/source/administration/tag-aware-sharding.txt index f4773fbe9d9..05579dc9275 100644 --- a/source/administration/tag-aware-sharding.txt +++ b/source/administration/tag-aware-sharding.txt @@ -22,29 +22,149 @@ cluster. This capability enables the following deployment patterns: This document describes the behavior, operation, and use of tag aware sharding in MongoDB deployments. +.. note:: + + Shard key tags are entirely distinct from :ref:`replica set member + tags `. + Behavior and Operations ----------------------- -- tags are cluster metadata. (implications.) Shell helpers to set the - metadata. The balancer does the rest. +Tags in a shareded cluster are pieces of metadata that dictate the +policy and behavior of the cluster balancer :term:`balancer`. Using +tags, you may associate individual shards in a cluster with one or +more strings, or tags. Then, you can assign this tag string to a range +of :term:`shard key` values for a sharded collection. When migrating a +chunk, the balancer will select a destination shard based on the +configured tag ranges. + +To migrate chunks in a tagged environment, the balancer selects a +target shard with a tag range that has an *upper* bound that *greater +than* the migrating chunk's *lower* bound. If a shard with a matching +tagged range exists, the balancer will migrate the chunk to that +shard. + +.. note:: The balancer may migrate chunks to tagged shards that + contain values that exceed the upper bound of the selected tag + range. + +.. example:: -- tags are arbitrary. tags are independent of replica-set member - tags. + Given a sharded collection with two configured tag ranges, such + that: -- tags only dictate balancing policy, and depending on chunk splits, - and current distribution of data it may take time for the cluster to - achieve desired distribution + - :term:`Shard key` values between ``100`` and ``200`` have tags to + direct corresponding chunks on shards tagged ``NYC``. -- (more?) + - Shard Key values between ``200`` and ``300`` have tags to direct + corresponding chunks on shards tagged ``SFO``. + + In this cluster, the balancer will migrate a chunk with shard key + values ranging between ``150`` and ``220`` to a shard tagged + ``NYC``, since ``150`` is closer to ``200`` than ``300``. + +After configuring sharding tags, the cluster may take some time to +reach the proper distribution of data, depending on the division of +chunks (i.e. splits) and the current distribution of data in the +cluster. Once configured, the balancer will respect tag ranges during +future :ref:`balancing rounds `. Administer Shard Tags --------------------- +Associate tags with a particular shard using the +:method:`sh.addShardTag()` method when connected to a +:program:`mongos` instance. A single shard may have multiple tags, and +multiple shards may also have the same tag. + +.. example:: + + The following example adds the tag ``NYC`` to two shards, and the tags + ``SFO`` and ``NRT`` to a third shard: + + .. code-block:: javascript + + sh.addShardTag("shard0000", "NYC") + sh.addShardTag("shard0001", "NYC") + sh.addShardTag("shard0002", "SFO") + sh.addShardTag("shard0002", "NRT") + +You may remove tags from a particular shard using the +:method:`sh.removeShardTag()` method when connected to a +:program:`mongos` instance, as in the following example, which removes +the ``NRT`` tag from a shard: + +.. code-block:: javascript + + sh.removeShardTag("shard0002", "NRT") + Tag a Shard Key Range ~~~~~~~~~~~~~~~~~~~~~ +To assign a range of shard key values to a tag, use the +:method:`sh.addTagRange()` method when connected to a +:program:`mongos` instance. Any given shard key range may only have +*one* assigned tag. However, you may assign the same tag to multiple +shard key rage. + +.. example:: + + Given a collection named ``users`` in the ``records`` database, + sharded by the ``zipcode`` field. The following operations assign: + + - two ranges of zip codes in Manhattan and Brooklyn the ``NYC`` tag + + - one range of zip codes in San Francisco the ``SFO`` tag + + .. code-block:: javascript + + sh.addTagRange("records.users", { zipcode: "10001" }, { zipcode: "10281" }, "NYC") + sh.addTagRange("records.users", { zipcode: "11201" }, { zipcode: "11240" }, "NYC") + sh.addTagRange("records.users", { zipcode: "94102" }, { zipcode: "94135" }, "SFO") + Remove a Tag From a Shard Key Range ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The :program:`mongod` does not provide a helper for removing a tag +rage. You may delete tag assignment from a shard key range by removing +the corresponding document from the :data:`~config.tags` collection of +the ``config`` database. + +Each document in the :data:`~config.tags` holds the :term:`namespace` +of the sharded collection and a minimum shard key value. + +.. example:: + + The following example removes the ``NYC`` tag assignment for the + range of zip codes within Manhattan: + + .. code-block:: javascript + + use config + db.tags.remove({ _id: { ns: "records.users", min: { zipcode: "10001" }}, tag: "NYC" }) + View Existing Shard Tags ~~~~~~~~~~~~~~~~~~~~~~~~ + +The output from :method:`sh.status()` lists tags associated with a +shard, if any, for each shard. A shard's tags exist in the shard's +document in the :data:`~config.shards` collection of the ``config`` +database. To return all shards with a specific tag use a sequence of +operations that resemble the following, which will return only those +shards tagged with ``NYC``: + +.. code-block:: javascript + + use config + db.shards.find({ tags: "NYC" }) + +You can find tag ranges for all :term:`namespaces ` in the +:data:`~config.tags` collection of the ``config`` database. The output +of :method:`sh.status()` displays all tag ranges. To return all shard +key ranges tagged with ``NYC`` issue the following sequence of +commands: + +.. code-block:: javascript + + use config + db.shards.find({ tags: "NYC" }) diff --git a/source/applications/replication.txt b/source/applications/replication.txt index 3e3c7c6b7f5..20e58e3cb4a 100644 --- a/source/applications/replication.txt +++ b/source/applications/replication.txt @@ -67,8 +67,8 @@ use the ``wtimeout`` argument. The following example sets the timeout to db.runCommand( { getlasterror: 1, w: 2, wtimeout:5000 } ) -Custom Write Propagation -~~~~~~~~~~~~~~~~~~~~~~~~ +Modify Default Write Propagation Operation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can configure your own "default" :dbcommand:`getLastError` behavior for a replica set. Use the @@ -99,6 +99,123 @@ have *no* other arguments. .. seealso:: :ref:`write-operations-write-concern` and :ref:`connections-write-concern` +Custom Write Propagation Modes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can use replica set tags to create custom write concerns using the +:data:`~local.system.replset.settings.getLastErrorDefaults` and +:data:`~local.system.replset.settings.getLastErrorModes` replica set +settings. + +.. note:: + + Custom write concern modes specify the field name and a number of + *distinct* values for that field. By contrast, read preferences use + the value of fields in the tag document to direct read operations. + + In some cases, you may be able to use the same tags for read + preferences and write concerns; however, you may need to create + additional tags for write concerns depending on the requirements of + your application. + +Single Tag Write Concerns +````````````````````````` + +Consider a five member replica set, where each member has one of the +following tag sets: + +.. code-block:: javascript + + { "use": "reporting" } + { "use": "backup" } + { "use": "application" } + { "use": "application" } + { "use": "application" } + +You could create a custom write concern mode that will ensure that +applicable write operations will not return until members with two +different values of the ``use`` tag have acknowledged the write +operation. Create the mode with the following sequence of operations +in the :program:`mongo` shell: + +.. code-block:: javascript + + cfg = rs.conf() + cfg.settings = { getLastErrorModes: { multiUse: { "use": 2 } } } + rs.reconfig(cfg) + +.. these examples need to be better so that they avoid overwriting + getLastErrorModes upon repetition (i.e. they don't $push documents + to getLastErrorModes.) + +To use this mode pass the string ``multiUse`` to the ``w`` option of +:dbcommand:`getLastError` as follows: + +.. code-block:: javascript + + db.runCommand( { getlasterror: 1, w: multiUse } ) + +Specific Custom Write Concerns +`````````````````````````````` + +If you have a three member replica with the following tag sets: + +.. code-block:: javascript + + { "disk": "ssd" } + { "disk": "san" } + { "disk": "spinning" } + +You cannot specify a custom +:data:`~local.system.replset.settings.getLastErrorModes` value to +ensure that the write propagates to the ``san`` before +returning. However, you may implement this write concern policy by +creating the following additional tags, so that the set resembles the +following: + +.. code-block:: javascript + + { "disk": "ssd" } + { "disk": "san", "disk.san": "san" } + { "disk": "spinning" } + +Then, create a custom +:data:`~local.system.replset.settings.getLastErrorModes` value, as +follows: + +.. code-block:: javascript + + cfg = rs.conf() + cfg.settings = { getLastErrorModes: { san: { "disk.san": 1 } } } + rs.reconfig(cfg) + +.. these examples need to be better so that they avoid overwriting + getLastErrorModes upon repetition (i.e. they don't $push documents + to getLastErrorModes.) + +To use this mode pass the string ``san`` to the ``w`` option of +:dbcommand:`getLastError` as follows: + +.. code-block:: javascript + + db.runCommand( { getlasterror: 1, w: san } ) + +This operation will not return until a replica set member with the tag +``disk.san`` returns. + +You may set a custom write concern mode as the default write concern +mode using :data:`~local.system.replset.settings.getLastErrorDefaults` +replica set as in the following setting: + +.. code-block:: javascript + + cfg = rs.conf() + cfg.settings.getLastErrorDefaults = { ssd:1 } + rs.reconfig(cfg) + +.. seealso:: :ref:`replica-set-configuration-tag-sets` for further + information about replica set reconfiguration and tag sets. + .. index:: read preference .. index:: slaveOk @@ -341,26 +458,25 @@ Tag Sets ~~~~~~~~ Tag sets allow you to specify custom :ref:`read preferences -` +` and :ref:`write concerns ` so that your application can target -operations to specific members, based on custom parameters. - -.. important:: - - 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 utilize the value of a tag to select a - member except to consider whether or not the value is unique. - -Custom Read Preferences -``````````````````````` +operations to specific members, based on custom parameters. + +.. note:: + + Consider the following properties of read preferences: -A tag set for a read operation may resemble the following: + - 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 ignore the value of a tag to when selecting a + member *except* to consider whether or not the value is unique. + +A tag set for a read operation may resemble the following document: .. code-block:: javascript @@ -419,78 +535,6 @@ For more information on how read preference :ref:`modes ` interact with tag sets, see the documentation for each read preference mode. -Custom Write Concerns -````````````````````` - -Replica set tags can be used to create custom write concerns through -a combination of the tags and the :data:`~local.system.replset.settings.getLastErrorDefaults` -replica set setting. - -You may be able to utilize the same tags you have created for read -preferences, however you may also need to create additional tags to -fully utilize custom write concerns. - -For example, previously you may have tagged a member with the tags -:samp:`disk` and :samp:`use`: - -.. code-block:: javascript - - { "disk": "ssd", "use": "reporting" } - -In order to direct write operations to the member tagged with :samp:`disk:{ssd}` -you must add an additional tag: - -.. code-block:: javascript - - { "disk.ssd": "ssd"} - -You would then use this tag to create a custom getLastErrorMode: - -.. code-block:: javascript - - > var cfg = rs.conf() - > cfg.settings = { getLastErrorModes: { ssd: {"disk.ssd":1}} } - > rs.reconfig(cfg) - -This creates a custom getLastError mode of :samp:`ssd`, requiring -at least one member tagged :samp:`ssd` to confirm the write operation. - -If, however, you wanted multiple members tagged :samp:`ssd` -to confirm the write operation, you need to tag each member with -a different value for the :samp:`disk.ssd` tag. -For example: - -.. code-block:: javascript - - > cfg.members[2].tags = {"disk.ssd": "APPLE SSD SM512E"} - > cfg.members[3].tags = {"disk.ssd": "APPLE SSD SM512E"} - > cfg.members[4].tags = {"disk.ssd": "INTEL SSD S3700"} - -And your custom getLastErrorMode would be: - -.. code-block:: javascript - - > cfg.settings = { getLastErrorModes: { ssd: {"disk.ssd":2}} } - -This getLastErrorMode directs MongoDB to confirm writes to two replica -members tagged with unique values for the :samp:`disk.ssd` tag. -In this example either :samp:`member[{2}]` or :samp:`member[{3}]` would -satisfy one requirement, and :samp:`member[{4}]` would satisfy -the requirement for a second member. - -The custom write concern can be specified as you would specify a write -concern or it may be added as a default write concern using the -the :data:`~local.system.replset.settings.getLastErrorDefaults` -replica set setting: - -.. code-block:: javascript - - > cf.settings.getLastErrorDefaults = {ssd:1} - -.. seealso:: :ref:`replica-set-configuration-tag-sets` for further - information about replica set reconfiguration and tag sets. - - .. index:: read preference; behavior .. _replica-set-read-preference-behavior: diff --git a/source/core/replication.txt b/source/core/replication.txt index 8b9d161879d..51161fc4a8f 100644 --- a/source/core/replication.txt +++ b/source/core/replication.txt @@ -496,11 +496,13 @@ your replica set: - Consider keeping one or two members of the set in an off-site data center, but make sure to configure the :ref:`priority ` to prevent it from becoming primary. - -- Create custom write concerns with - :ref:`replica set tags ` to ensure - data is written to specific members of the replica set or to facilitate - data center awareness. + +- Create custom write concerns with :ref:`replica set tags + ` to ensure that applications + can control the threshold for a successful write operation. Use + these write concerns to ensure that operations propagate to specific + data centers or to machines of different functions before returning + successfully. For more information regarding replica set configuration and deployments see :doc:`/administration/replica-set-architectures`. diff --git a/source/reference/config-database.txt b/source/reference/config-database.txt index 55768ea4de9..eb0a0dc022a 100644 --- a/source/reference/config-database.txt +++ b/source/reference/config-database.txt @@ -271,6 +271,30 @@ Collections { "_id" : "shard0000", "host" : "shard1/localhost:30000" } + If the shard has :ref:`tags ` assigned, this + document has a ``tags`` field, that holds an array of the tags, as + in the following example: + + .. code-block:: javascript + + { "_id" : "shard0001", "host" : "localhost:30001", "tags": [ "NYC" ] } + +.. data:: config.tags + + The :data:`~config.tags` collection holds documents for each tagged + shard key range in the cluster. The documents in the + :data:`~config.tags` collection resemble the following: + + .. code-block:: javascript + + { + "_id" : { "ns" : "records.users", "min" : { "zipcode" : "10001" } }, + "ns" : "records.users", + "min" : { "zipcode" : "10001" }, + "max" : { "zipcode" : "10281" }, + "tag" : "NYC" + } + .. data:: config.version The :data:`~config.version` collection holds the current metadata version number. This diff --git a/source/reference/replica-configuration.txt b/source/reference/replica-configuration.txt index 53c80299f47..8680f40193c 100644 --- a/source/reference/replica-configuration.txt +++ b/source/reference/replica-configuration.txt @@ -408,218 +408,257 @@ full documentation of the behavior of :ref:`tags sets for write concern .. important:: - Custom read preferences and write concerns evaluate tags sets in + 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 utilize the value of a tag to select a member except to consider whether or not the value is unique. Configure tag sets by adding fields and values to the document stored -in the :data:`~local.system.replset.members[n].tags`. Consider the following example: - -.. example:: +in the :data:`~local.system.replset.members[n].tags`. Consider the +following examples: - Given the following replica set configuration: - - .. code-block:: javascript +Configure Tag Sets +~~~~~~~~~~~~~~~~~~ - { - "_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" - } - ] - } +Given the following replica set configuration: - You could add the tag sets, to the members of this replica set, - with the following command sequence in the :program:`mongo` shell: +.. code-block:: javascript - .. code-block:: javascript + { + "_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" + } + ] + } - 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) +You could add the tag sets, to the members of this replica set, +with the following command sequence in the :program:`mongo` shell: - After this operation the output of :method:`rs.conf()`, would - resemble the following: +.. code-block:: javascript - .. code-block:: javascript + 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) - { - "_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" - } - } - ] - } +After this operation the output of :method:`rs.conf()`, would +resemble the following: +.. code-block:: javascript -.. example:: + { + "_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" + } + } + ] + } + + +Configure Tag Sets for Custom Multi-Data Center Write Concern Mode +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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 :program:`mongo` shell: + +#. Create the replica set configuration object ``conf``: - Create a custom write concern to require confirmation from two - data centers using replica set tags. - - You have a five member replica set consisting of members in a data - center in Vienna, VA which we will tag "dc.va" and members in a data - center in Toronto, Ontario which we will tag "dc.gto". - - First add tags to the replica set members reflecting their locations: - .. code-block:: javascript - + conf = rs.conf() - - conf.members[0].tags = { "dc.va": "true"} - conf.members[1].tags = { "dc.va": "true"} - conf.members[2].tags = { "dc.gto": "true"} - conf.members[3].tags = { "dc.gto": "true"} - conf.members[4].tags = { "dc.va": "true"} - rs.reconfig(conf) - - Then you must create a custom getLastErrorMode: - - .. code-block:: javascript - - conf.settings = { getLastErrorModes: { MultipleDC : { "dc.va": 1, "dc.gto": 1}} - rs.reconfig(conf) - - -.. example:: - Create a custom write concern to require confirmation from two members in - distinct racks in two data centers using replica set tags. You have - five members in two data centers as in the previous example. - - You may look at the previous example and expect to write: - - .. code-block:: - - conf.settings = { getLastErrorModes: { MultipleDC : { "dc.va": 2, "dc.gto": 2}} - rs.reconfig(conf) +#. Add tags to the replica set members reflecting their locations: - But you will receive: - .. code-block:: javascript - - { - "errmsg" : "exception: mode { dc.va: 2.0, dc.gto: 2.0 } requires 2 tagged with dc.va, but only 1 with this tag were found", - "code" : 14831, - "ok" : 0 - } - - You must use unique values for the tags if you require more than one - tagged member to be selected by a custom write concern. - This is an important difference from the use of replica set tags for - read preferences. - - You can still reuse the configuration from the previous example with - a minor change: - - .. code-block:: javascript - - conf = rs.conf() - + 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) - - Then you change the custom getLastErrorMode: - + +#. Create a custom + :data:`~local.system.replset.settings.getLastErrorModes` setting to + ensure that the write operation will propagate to at least one member + of each facility: + .. code-block:: javascript - - conf.settings = { getLastErrorModes: { MultipleDC : { "dc.va": 2, "dc.gto": 2}} - rs.reconfig(conf) - - MongoDB will now ensure that writes go to two of the three systems tagged :samp:`dc.va` - and both systems tagged :samp:`dc.gto`. - - -.. example:: - Create tags to confirm that reads are directed to members with solid - state drives, and that writes are confirmed by members with SSD drives. - - You have a five member replica set with three members configured with - solid state drives. - - Since read preferences and write concerns utilize tags in different - ways you will need to create multiple tags: - + conf.settings = { getLastErrorModes: { MultipleDC : { "dc.va": 1, "dc.gto": 1}} + +#. Reconfigure the replica set using the new ``conf`` configuration + object: + + .. code-block:: javascript + + rs.reconfig(conf) + +To ensure that a write operation propagators to at least one member of +the set in both facilities, then use the ``MultipleDC`` write concern +mode, as follows: + +.. code-block:: javascript + + db.runCommand( { getLastErrror: 1, 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 :program:`mongo` shell: + +#. Create the replica set configuration object ``conf``: + .. code-block:: javascript - + conf = rs.conf() - conf.members[0].tags = {"dc.va": "rack1", disk:"ssd", ssd:"true"} - conf.members[1].tags = {"dc.va": "rack2", disk:"raid"} - conf.members[2].tags = {"dc.gto": "rack1", disk:"ssd", ssd:"true"} - conf.members[3].tags = {"dc.gto": "rack2", disk:"raid"} - conf.members[4].tags = {"dc.va": "rack1", disk:"ssd", ssd:"true"} + +#. Redefine the + :data:`~local.system.replset.settings.getLastErrorModes` valuie to + require two different values of both ``dc.va`` and ``dc.gto``: + + .. code-block:: javascript + + conf.settings = { getLastErrorModes: { MultipleDC : { "dc.va": 2, "dc.gto": 2}} + +#. Reconfigure the replica set using the new ``conf`` configuration + object: + + .. code-block:: javascript + rs.reconfig(conf) - - You would specify the :samp:`ssd` read preference: - + +Now, the following write concern operation will only return after the +write operation propagates to at least two different racks in the +each facility: + +.. code-block:: javascript + + db.runCommand( { getLastErrror: 1, 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: [#read-and-write-tags]_ + +.. code-block:: javascript + + {"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 an +disk type of ``ssd``, you could use the following tag set: + +.. code-block:: javascript + + { disk: "ssd" } + +However, to create comparable write concern modes, you would specify a +different set of +:data:`~local.system.replset.settings.getLastErrorModes` +configuration. Consider the the following sequence of operations in +the :program:`mongo` shell: + +#. Create the replica set configuration object ``conf``: + .. code-block:: javascript - { "disk": "ssd"} - - However you will need to create a custom getLastErrorMode to specify - :samp:`ssd` as a write preference: - + conf = rs.conf() + +#. Redefine the + :data:`~local.system.replset.settings.getLastErrorModes` value to + configure two write concern modes: + .. code-block:: javascript - - conf=rs.conf() + conf.settings = { - "getLastErrorModes" : { - "ssd" : { - "ssd" : 1 - }, - "MultipleDC" : { - "dc.va" : 1, - "dc.gto" : 1 - } - } - } + "getLastErrorModes" : { + "ssd" : { + "ssd" : 1 + }, + "MultipleDC" : { + "dc.va" : 1, + "dc.gto" : 1 + } + } + } + +#. Reconfigure the replica set using the new ``conf`` configuration + object: + + .. code-block:: javascript + rs.reconfig(conf) - - You would then specify :samp:`ssd` as your custom write concern. - \ No newline at end of file + +Now, you can specify the ``MultipleDC`` write concern mode, as in the +following operation, to ensure that a write operation propagates to +each data center. + +.. code-block:: javascript + + db.runCommand( { getLastErrror: 1, w: "MultipleDC" } ) + +Additionally, you can specify the ``ssd`` write concern mode, as in +the following operation, to ensure that a write operation propagates +to at least one instance with an SSD. + +.. [#read-and-write-tags] Since read preferences and write concerns + use the value of fields in tag sets differently, for larger + deployments will have some redundancy.