Upload
vumien
View
220
Download
5
Embed Size (px)
Citation preview
MongoDB Durability from Client Side: WriteConcerns and
ReadPreferences
Stéphane CombaudonSeptember 22nd, 2015
www.percona.com
Agenda
● MongoDB Replica Sets
● Read Preferences
● Write Concerns
www.percona.com
Main features of MongoDB replication
● Replication is asynchronous● All writes go to the primary
● Acknowledgement from secondaries is configurable (write concern)
● Secondaries can accept reads (read preference)
● A new primary is automatically elected if the current primary fails
● An arbiter with no data can be used
www.percona.com
A simple replica set
Primary
Secondary
Heartbeat
Writes
SecondaryReplication
www.percona.com
Election process
● Based on heartbeats● Exchanged every 2 second● If the primary does not reply after 10 seconds, the
other members assume it's unreachable
● Election then starts to get a new primary
● A priority can be given to any member to influence the result of the election
www.percona.com
Agenda
● MongoDB Replica Sets
● Read Preferences
● Write Concerns
www.percona.com
Read-Write Splitting
● A replica set is useful for HA purposes
● Can it be used to scale writes?● No, all writes must go to the primary
● Can it be used to scale reads?● Yes, secondaries have a copy of the data● Keep in mind replication is asynchronous
www.percona.com
Implementing read-write splitting
● For any supported programming language● The MongoDB driver is replica-set aware● Read-write splitting is just a matter of configuration
– Ridiculously easy compared to the MySQL world!
www.percona.com
Basic Read Preferences (1)
● PRIMARY: Only read from the primary
● Default setting● Provides strict consistency
● SECONDARY: Read from any secondary
● Raises an error if no secondary is available
www.percona.com
Basic Read Preferences (2)
● PRIMARY_PREFERRED: Read from the primary, if not available read from a secondary
● SECONDARY_PREFERRED: Read from any secondary, if none is available read from the primary
● NEAREST: Read from the nearest node (regarding network latency)
www.percona.com
rs.slaveOk()
● By default, reads on secondaries are not allowed
● Before using a read preference that is not PRIMARY, you have to run● rs.slaveOk()
www.percona.com
Custom tags
● Tags can be added to a replica setcfg = rs.conf()
cfg.members[0].tags = {'location': 'AMS', 'role': 'regular'}
cfg.members[1].tags = {'location': 'AMS', 'role': 'reporting'}
cfg.members[2].tags = {'location': 'PAR', 'role': 'regular'}
rs.reconfig(cfg)
www.percona.com
Read preference and custom tag
● As long as the read preference is not PRIMARY● You can specify custom tag(s) to better target which
server(s) will get the reads● Useful to spread load depending on
– Geographical location– Hardware capabilities– …
www.percona.com
Using custom tags
● Example in PHP$uri = "mongodb://localhost:30001, localhost:30002, localhost:30003/?replicaSet=RS";
$uri .= "&readPreference=secondary";
$uri .= "&readPreferenceTags=location:AMS";
$uri .= "&readPreferenceTags=role:regular";
$uri .= "&readPreferenceTags=";
www.percona.com
Using custom tags
● Example in PHP$uri = "mongodb://localhost:30001, localhost:30002, localhost:30003/?replicaSet=RS";
$uri .= "&readPreference=secondary";
$uri .= "&readPreferenceTags=location:AMS";
$uri .= "&readPreferenceTags=role:regular";
$uri .= "&readPreferenceTags=";
Read from secondaries only ...
www.percona.com
Using custom tags
● Example in PHP$uri = "mongodb://localhost:30001, localhost:30002, localhost:30003/?replicaSet=RS";
$uri .= "&readPreference=secondary";
$uri .= "&readPreferenceTags=location:AMS";
$uri .= "&readPreferenceTags=role:regular";
$uri .= "&readPreferenceTags=";
Read from secondaries only ...
… located in AMS
www.percona.com
Using custom tags
● Example in PHP$uri = "mongodb://localhost:30001, localhost:30002, localhost:30003/?replicaSet=RS";
$uri .= "&readPreference=secondary";
$uri .= "&readPreferenceTags=location:AMS";
$uri .= "&readPreferenceTags=role:regular";
$uri .= "&readPreferenceTags=";
Read from secondaries only ...
… located in AMS
… if none available, use any 'regular' secondary
www.percona.com
Using custom tags
● Example in PHP$uri = "mongodb://localhost:30001, localhost:30002, localhost:30003/?replicaSet=RS";
$uri .= "&readPreference=secondary";
$uri .= "&readPreferenceTags=location:AMS";
$uri .= "&readPreferenceTags=role:regular";
$uri .= "&readPreferenceTags=";
Read from secondaries only ...
… located in AMS
… if none available, use any 'regular' secondary
… if none available, use any secondary
www.percona.com
Member Selection
● Client driver● Builds a list of candidate nodes by looking at their
type (primary/secondary)● Excludes members where tags don't match● Finds the nearest member (ping distance)● Builds a list of nodes with an acceptable latency
(default is 15ms)● Randomly selects a node from the list
www.percona.com
Agenda
● MongoDB Replica Sets
● Read Preferences
● Write Concerns
www.percona.com
Durability of writes
● On a standalone instance● Journaling governs durability
● On a replica set● You can ask for more durability guarantees● You can wait until some/all replicas have executed
a write● This is done by specifying a write concern
www.percona.com
Basic write concerns - 1
● w: 0
● No acknowledgement
● w: 1
● Write is ok if primary acks the write● Default setting
● w: N
● Write is ok if executed by N members
www.percona.com
Basic write concerns - 2
● w: all
● Write is ok if all members ack the write
● w: majority
● Write is ok if the majority of the voting nodes have executed the writes
● With 3 nodes, it means the primary and one secondary
www.percona.com
Specifying a write concern - 1
● Setting the default write concerncfg = rs.conf()
cfg.settings = {}
cfg.settings.getLastErrorDefaults = { w: "majority", wtimeout: 5000 }
rs.reconfig(cfg)
www.percona.com
Specifying a write concern - 2
● Using a specific write concern for a specific write
db.people.insert(
{name: 'John'},
{writeConcern: {w: all, wtimeout: 5000}})
www.percona.com
Custom tags
● You can use replica set tags to make sure specific nodes will ack writes
● For instance, make sure both AMS and PAR datacenters get a write
cfg=rs.conf()
cfg.settings = {getLastErrorModes:
{AllDCs: {“AMS”: 1, “PAR”: 1}}}
db.people.insert({name: 'John'},
{writeConcern: {w: “AllDCs”}})
www.percona.com
Q&A
Thanks for attending!
Feel free to drop me a line at: