www.tothenew.com
MongoDB Performance
Tuning
www.tothenew.com
About Me
Puneet Behl
Associate Technical Lead
TO THE NEW Digital
puneet.behl@tothenew.com
GitHub: https://github.com/puneetbehl/
Twitter: @puneetbhl
LinkedIn: https://in.linkedin.com/in/puneetbhl
www.tothenew.com
● Performance Issues
● Tuning Queries
● Tuning Architecture & System configurations
Agenda
www.tothenew.com
● High Disk I/O Utilization
● Queries getting slow as data increases
● Timeout Issues
Performance Issues
www.tothenew.com
● Database Profiler
● Explain
Tuning Queries
www.tothenew.com
Tuning Queries
www.tothenew.com
● Collect fine-grained data about Mongo operations
● Writes all the data in “system.profile” collection
● “system.profile” is a capped collection
● Helps identifying what queries need to be tuned
Database Profiler
www.tothenew.com
● 0 - the profiler is off
● 1 - collects profiling data only for slow operations ( > 100 millis )
● 2 - collects profiling data for all database operations
Database Profiler - Profiling Levels
www.tothenew.com
● Enable for all using
“db.setProfilingLevel(2)”
● Specify the threshold for slow operations
“db.setProfilingLevel(0, 20)”
● Check profiling level
“db.getProfilingLevel()”
Database Profiler - Enable Profiling
www.tothenew.com
“mongod --profile 1 --slows 15”
Database Profiler - Enable Profiling for Entire Instance
www.tothenew.com
● Enable profiling on each mongod instance in a cluster :-P
Database Profiler - Enable Profiling in a Shard Cluster
www.tothenew.com
db.system.profile.find( { millis: { $gt: 100 } } )
Database Profiler - Analyzing Output
www.tothenew.com
db.system.profile.find().sort( { $natural: -1 }
).limit(20)
Database Profiler - Analyzing Output
www.tothenew.com
db.system.profile.find( {“op”: “query” } )
Database Profiler - Analyzing Output
www.tothenew.com
db.system.profile.aggregate({ $group : { _id :"$op",
count:{$sum:1},
"max response time":{$max:"$millis"},
"avg response time":{$avg:"$millis"}
}});
Result:
{
"result" : [
{ "_id" : "command", "count" : 1, "max response time" : 0, "avg response time" : 0 },
{ "_id" : "query", "count" : 12, "max response time" : 571, "avg response time" : 5 },
{ "_id" : "update", "count" : 842, "max response time" : 111, "avg response time" : 40 },
{ "_id" : "insert", "count" : 1633, "max response time" : 2, "avg response time" : 1 }
],
"ok" : 1
}
Database Profiler - Analyzing Output
www.tothenew.com
db.system.profile.aggregate(
{$group : {
_id :"$ns",
count:{$sum:1},
"max response time":{$max:"$millis"},
"avg response time":{$avg:"$millis"} }
},
{$sort: {
"max response time":-1}
}
);
Result on next slide ...
Database Profiler - Analyzing Output
www.tothenew.com
Result:
{
"result" : [
{ "_id" : "game.players","count" : 787, "max response time" : 111, "avg response time" : 0},
{"_id" : "game.games","count" : 1681,"max response time" : 71, "avg response time" : 60}, {"_id"
: "game.events","count" : 841,"max response time" : 1,"avg response time" : 0},
…
],
"ok" : 1
}
Database Profiler - Analyzing Output
www.tothenew.com
See more examples at:
https://docs.mongodb.com/manual/tutorial/manage-the-database-profiler/#exampl
e-profiler-data-queries
Database Profiler - Analyzing Output
www.tothenew.com
● “db.collection.explain()”
● Return information on query plan and execution stats
● Present the query plan as tree of stages
● Pass the query identified in profile to explain
Explain
www.tothenew.com
{
"queryPlanner" : {
"plannerVersion" : <int>,
"namespace" : <string>,
"indexFilterSet" : <boolean>,
"parsedQuery" : {
...
},
Continued on next slide ...
Explain - Sample Output
www.tothenew.com
...
"winningPlan" : {
"stage" : <STAGE1>,
...
"inputStage" : {
"stage" : <STAGE2>,
...
"inputStage" : {
...
}
}
},
"rejectedPlans" : [
<candidate plan 1>,
...
]
}
Explain - Sample Output
www.tothenew.com
db.collection.explain(“executionStats”)
Explain - executionStats
www.tothenew.com
"executionStats" : {
"executionSuccess" : <boolean>,
"nReturned" : <int>,
"executionTimeMillis" : <int>,
"totalKeysExamined" : <int>,
"totalDocsExamined" : <int>,
"executionStages" : {
// on next slide
},
"allPlansExecution" : [
{ <partial executionStats1> },
{ <partial executionStats2> },
...
]
}
Explain - executionStats
www.tothenew.com
"executionStats" : {
...
"executionStages" : {
"stage" : <STAGE1>
"nReturned" : <int>,
"executionTimeMillisEstimate" : <int>,
"works" : <int>,
"advanced" : <int>,
"needTime" : <int>,
"needYield" : <int>,
"isEOF" : <boolean>,
... continued on next slide
Explain - executionStats
www.tothenew.com
"executionStages" : {
...
"inputStage" : {
"stage" : <STAGE2>,
...
"nReturned" : <int>,
"executionTimeMillisEstimate" : <int>,
"keysExamined" : <int>,
"docsExamined" : <int>,
...
"inputStage" : {
...
}
}
},
Explain - executionStats
www.tothenew.com
db.events.find({ "user_id":35991},{"_id":0,"user_id":1}).explain()
{
"cursor" : "BtreeCursor user_id_1", "isMultiKey" : false,
"n" : 2,
"nscannedObjects" : 2,
"nscanned" : 2,
"nscannedObjectsAllPlans" : 2,
"nscannedAllPlans" : 2,
"scanAndOrder" : false,
"indexOnly" : true,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : { "user_id" : [ [ 35991, 35991 ] ] },
}
PS: This example is from v2.x of MongoDB
Examples
www.tothenew.com
Memory, Network and Disks are the system resources important to
MongoDB
Tuning Architecture & System Configurations
www.tothenew.com
● Setting Linux Ulimit
● Deploy these limits by adding a file in “/etc/security/limits.d” (or
appending to “/etc/security/limits.conf” if there is no “limits.d”)
● Following is example file for linux users
“/etc/security/limits.d/mongod.conf”
mongod soft nproc 64000
mongod hard nproc 64000
mongod soft nofile 64000
mongod hard nofile 64000
Tuning Linux for MongoDB
www.tothenew.com
● Setting Swappiness
● Update /etc/sysctl.conf
vm.swappiness = 1 or 10
Tuning Linux for MongoDB
www.tothenew.com
● NUMA (Non-Uniform Memory Access) Architecture
● Disable via on/off switch in in BIOS
● Update via:
numactl --interleave=all mongod <options here>
Tuning Linux for MongoDB
www.tothenew.com
● Update IO Scheduler to “noop” or “deadline”.
echo noop > /sys/block/hda/queue/scheduler
● Check IO Scheduler via:
cat /sys/block/sda/queue/scheduler
Tuning Linux for MongoDB
www.tothenew.com
● Update “Read-Ahead” settings via:
sudo blockdev --getra /dev/sda
● Check current RA value via:
sudo blockdev --getra /dev/sda
Tuning Linux for MongoDB
www.tothenew.com
● File System options
● Recommended to use “ext4” or “XFS”
● Disable access-time updates by adding the flag “noatime” to the
filesystem options field in the file “/etc/fstab” (4th field) for the disk
serving MongoDB data:
/dev/mapper/data-mongodb /var/lib/mongo ext4 defaults,noatime 0 0
Tuning Linux for MongoDB
www.tothenew.com
Thank You! :)
www.tothenew.com
https://docs.mongodb.org
https://www.percona.com/blog/2016/08/12/tuning-linux-for-mongodb/
https://www.mongodb.com/presentations/mongosv-2012/mongodb-performance-tuning
References