Spring data mongodb secondary node reads

Reading from secondary mongodb is one of the simplest way to scale number of reads from the application. By default, all the reads and writes goes to primary. Although mongodb docs caution against going ahead with this option, there are certain scenarios where it's useful,

  • Data is mostly static and changes if at all, rarely
  • Reporting systems, where lagging data is fine
  • High number of reads, relatively low writes
The risk is that the data read from secondary might not be latest, so we have to be careful in choosing which queries are to be sent to secondary.  It's best to consider setting SecondaryPreferred with maxStaleness for the driver to determine, whether to send to secondary or fallback to primary. We can achieve this behaviour by making use of Read Preference

Spring Data MongoDB

Spring provides two API to set Read Preference. One is via MongoTemplate and the other is through Query flags(slave ok).

Option 1: MongTemplate:

This approach is slightly tedious but suits better if you have lots of collections and you can't decide on single read preference per collection. Need to disable spring boot mongo auto configuration and have to create two MongoTemplate, one with Primary read preference and the other with SecondaryPreferred read preference. Then autowire specific mongoTemplate with respect to the required read preference for querying. Multiple MongoTemplate per app complicates app config as well as test config. It make us to write lots of config by hand instead of relying on spring boot auto configuration.

Option 2: Query Flags:


This approach is easiest as we need to set SLAVE_OK flag per query basis. Query API exposes slaveOk() method to set this flag. Otherwise, can use @Meta annotation to set this flag as well. In effect, spring instructs mongo driver to set SlaveOK.Allow in OP_QUERY.


Mongo Java Driver:

Mongo Java driver has an API to set read preference at both Db and collection level. This is useful, if the read preference can be fixed for the whole db or collection. I have been using collection level read preference in my projects since my spring data mongo 1.10 didn't support option 2 yet. Once the spring app context is configured, we can autowire the mongoTemplate and set the read preference on interested collections.

Comments

Popular posts from this blog

Spring mongodb connection pool limit

Spark streaming with kafka and HDFS