PhpRiot
News Archive
PhpRiot Newsletter
Your Email Address:

More information

Read Preferences wth the MongoDB PHP driver

Note: This article was originally published at Planet PHP on 18 December 2012.
Planet PHP

Read Preferences wth the MongoDB PHP driver

London, UK Tuesday, December 18th 2012, 09:41 GMT

Read Preferences are a new Replica Set and Sharding feature implemented by most MongoDB drivers that are supported by 10gen. This functionality requires MongoDB 2.2. In short, Read Preferences allow you to configure from which nodes you prefer the driver reads data from. In a Replica Set environment it is the driver that does the selection of the preferred node, and in a Sharded environment it is the mongos process that routes queries according to the defined Read Preferences.

There are a few different Read Preference types. There is primary (the default) which will make sure the driver (or mongos) only reads from primary nodes. This is the default and guarantees consistent reads. The other types can all possibly returned outdated documents as replication is asynchronous in MongoDB. Other types include primaryPreferred, which reads from a primary, unless no primary is available; secondary, which runs queries on secondaries only; secondaryPreferred, which reads from secondaries first, and if none are available, from the primary node; and the last one is nearest which does not prefer a specific type of node (primary or secondary) but solely selects one of the "nearest" nodes - within 15ms of the closest node.

The PHP driver checks ping times to nodes in a Replica Set about every 5 seconds and keeps this information with the connection manager, about which I wrote in an earlier article.

As an example, let us assume that we have a Replica Set with four nodes and that the driver has established the following ping times:

  • Primary node a: 2ms

  • Secondary node b: 23ms

  • Secondary node c: 1ms

  • Secondary node d: 7ms

  • Secondary node e: 3ms

The manager searches the manager for all connections and returns all connections for which a connection matches the Read Preference criteria. For primary or secondary it only includes nodes with that property, for the other three Read Preference types it will return all the connections. The set that is returned for secondaryPreferred is [ a, b, c, d, e ]. The manager then sorts this list according to the Read Preference and the ping time. As we are more interested in secondaries with secondaryPreferred, the sorted list of nodes becomes { c, e, d, b, a }. Node c is first because it has the lowest ping time (1ms). In the next step, all nodes that are more than 15ms slower than the fastest node are eliminated. In our example, we are now left with { c, e, d, a }. In the last step, we select a node from this set. With a Read Preference of secondaryPreferred we eliminate the last node from the list if there is more than one node in the list, and the last node in the list is a primary. The final list to pick a node from is now { c, e, a }. From this remaining list, a random node is picked.

With the PHP driver, you can choose a Read Preference in a few different ways. The simplest way is probably directly in the connection string:

new MongoClient('mongodb://a,d/?replicaSet=demoset&readPreference=secondaryPreferred');

It is also possible to set the Read Preference on a connection, database or collection object. When a read preference is set, it is inherited by every database or connection object that is created afterwards:

setReadPreference(Mongo::RP_SECONDARY_PREFERRED); $d = $m-demoDb; /* The Read Preference for $d is 'secondaryPreferred' */ $d-setReadPreference(Mongo::RP_PRIMARY_PREFERRED); /* The Read Preference for $d has been changed to 'primaryPreferred' */ $c = $d-myCollection; /* The Read Preference for $c is 'primaryPreferred' */ $c = $m-demoDb-myCollection; /* The Read Preference for $c is 'secondaryPreferred' */ $d-setReadPreference(Mongo::RP_NEAREST); /* The Read Preference for $c is now 'nearest' */ ?

In future versions of the

Truncated by Planet PHP, read more at the original (another 4825 bytes)