Transcript
Page 1: Mythbusting: Understanding How We Measure Performance at MongoDB

VP, Engineering, MongoDB

Andrew Erlichson

#MongoDBDays

Mythbusting: Understanding How We Measure the Performance of MongoDB

Page 2: Mythbusting: Understanding How We Measure Performance at MongoDB

Before we start…

• We are going to look a lot at– C++ kernel code– Java benchmarks– JavaScript tests

• And lots of charts

• And its going to be awesome!

Page 3: Mythbusting: Understanding How We Measure Performance at MongoDB

Goals of Benchmarking

– You have an idea– It must be tested– Others must be able

to reproduce your work.

– Explanations that contribute to knowledge are key.

– Should have practical applications

Academia

Page 4: Mythbusting: Understanding How We Measure Performance at MongoDB

Industry Benchmarketing

• Prove you are faster than the competition

• Emphasize your best attributes

• Repeatable

• Explanations

Page 5: Mythbusting: Understanding How We Measure Performance at MongoDB

Industry Benchmarketing

• Prove you are faster than the competition

• Emphasize your best attributes

• Repeatable*

• Explanations*

*OPTIONAL

Page 6: Mythbusting: Understanding How We Measure Performance at MongoDB

Goals of Internal Benchmarking

• Always be improving

• Understand our bottlenecks

• Main customer is engineering

• Explanations are somewhat important.

Page 7: Mythbusting: Understanding How We Measure Performance at MongoDB

Overview – Internal Benchmarking

• Some common traps

• Performance measurement & diagnosis

• What's next

Page 8: Mythbusting: Understanding How We Measure Performance at MongoDB

Part OneSome Common Traps

Page 9: Mythbusting: Understanding How We Measure Performance at MongoDB

long startTime = System.currentTimeMillis();

for (int roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

BasicDBObject doc = new BasicDBObject();

doc.put("_id",id);

doc.put("k",rand.nextInt(numMaxInserts)+1);

String cVal = "…"

doc.put("c",cVal);

String padVal = "…";

doc.put("pad",padVal);

aDocs[i]=doc;

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

globalInserts.addAndGet(documentsPerInsert);

}

long endTime = System.currentTimeMillis();

#1 Time taken to Insert x Documents

Page 10: Mythbusting: Understanding How We Measure Performance at MongoDB

long startTime = System.currentTimeMillis();

for (int roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

BasicDBObject doc = new BasicDBObject();

doc.put("_id",id);

doc.put("k",rand.nextInt(numMaxInserts)+1);

String cVal = "…"

doc.put("c",cVal);

String padVal = "…";

doc.put("pad",padVal);

aDocs[i]=doc;

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

globalInserts.addAndGet(documentsPerInsert);

}

long endTime = System.currentTimeMillis();

#1 Time taken to Insert x Documents

Page 11: Mythbusting: Understanding How We Measure Performance at MongoDB

long startTime = System.currentTimeMillis();

for (int roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

BasicDBObject doc = new BasicDBObject();

doc.put("_id",id);

doc.put("k",rand.nextInt(numMaxInserts)+1);

String cVal = "…"

doc.put("c",cVal);

String padVal = "…";

doc.put("pad",padVal);

aDocs[i]=doc;

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

globalInserts.addAndGet(documentsPerInsert);

}

long endTime = System.currentTimeMillis();

#1 Time taken to Insert x Documents

Page 12: Mythbusting: Understanding How We Measure Performance at MongoDB

long startTime = System.currentTimeMillis();

for (int roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

BasicDBObject doc = new BasicDBObject();

doc.put("_id",id);

doc.put("k",rand.nextInt(numMaxInserts)+1);

String cVal = "…"

doc.put("c",cVal);

String padVal = "…";

doc.put("pad",padVal);

aDocs[i]=doc;

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

globalInserts.addAndGet(documentsPerInsert);

}

long endTime = System.currentTimeMillis();

#1 Time taken to Insert x Documents

Page 13: Mythbusting: Understanding How We Measure Performance at MongoDB

long startTime = System.currentTimeMillis();

for (int roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

BasicDBObject doc = new BasicDBObject();

doc.put("_id",id);

doc.put("k",rand.nextInt(numMaxInserts)+1);

String cVal = "…"

doc.put("c",cVal);

String padVal = "…";

doc.put("pad",padVal);

aDocs[i]=doc;

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

globalInserts.addAndGet(documentsPerInsert);

}

long endTime = System.currentTimeMillis();

#1 Time taken to Insert x Documents

Page 14: Mythbusting: Understanding How We Measure Performance at MongoDB

long startTime = System.currentTimeMillis();

for (int roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

BasicDBObject doc = new BasicDBObject();

doc.put("_id",id);

doc.put("k",rand.nextInt(numMaxInserts)+1);

String cVal = "…"

doc.put("c",cVal);

String padVal = "…";

doc.put("pad",padVal);

aDocs[i]=doc;

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

globalInserts.addAndGet(documentsPerInsert);

}

long endTime = System.currentTimeMillis();

So that looks ok, right?

Page 15: Mythbusting: Understanding How We Measure Performance at MongoDB

long startTime = System.currentTimeMillis();

for (int roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

BasicDBObject doc = new BasicDBObject();

doc.put("_id",id);

doc.put("k",rand.nextInt(numMaxInserts)+1);

String cVal = "…"

doc.put("c",cVal);

String padVal = "…";

doc.put("pad",padVal);

aDocs[i]=doc;

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

globalInserts.addAndGet(documentsPerInsert);

}

long endTime = System.currentTimeMillis();

What are else you measuring?

Object creation and GC management?

Page 16: Mythbusting: Understanding How We Measure Performance at MongoDB

long startTime = System.currentTimeMillis();

for (int roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

BasicDBObject doc = new BasicDBObject();

doc.put("_id",id);

doc.put("k",rand.nextInt(numMaxInserts)+1);

String cVal = "…"

doc.put("c",cVal);

String padVal = "…";

doc.put("pad",padVal);

aDocs[i]=doc;

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

globalInserts.addAndGet(documentsPerInsert);

}

long endTime = System.currentTimeMillis();

What are else you measuring?

Thread contention on nextInt()?

Object creation and GC management?

Page 17: Mythbusting: Understanding How We Measure Performance at MongoDB

long startTime = System.currentTimeMillis();

for (int roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

BasicDBObject doc = new BasicDBObject();

doc.put("_id",id);

doc.put("k",rand.nextInt(numMaxInserts)+1);

String cVal = "…"

doc.put("c",cVal);

String padVal = "…";

doc.put("pad",padVal);

aDocs[i]=doc;

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

globalInserts.addAndGet(documentsPerInsert);

}

long endTime = System.currentTimeMillis();

What are else you measuring?

Time to synthesize data?

Object creation and GC management?

Thread contention on nextInt()?

Page 18: Mythbusting: Understanding How We Measure Performance at MongoDB

long startTime = System.currentTimeMillis();

for (int roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

BasicDBObject doc = new BasicDBObject();

doc.put("_id",id);

doc.put("k",rand.nextInt(numMaxInserts)+1);

String cVal = "…"

doc.put("c",cVal);

String padVal = "…";

doc.put("pad",padVal);

aDocs[i]=doc;

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

globalInserts.addAndGet(documentsPerInsert);

}

long endTime = System.currentTimeMillis();

What are else you measuring?

Object creation and GC management?

Thread contention on addAndGet()?

Thread contention on nextInt()?

Time to synthesize data?

Page 19: Mythbusting: Understanding How We Measure Performance at MongoDB

long startTime = System.currentTimeMillis();

for (int roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

BasicDBObject doc = new BasicDBObject();

doc.put("_id",id);

doc.put("k",rand.nextInt(numMaxInserts)+1);

String cVal = "…"

doc.put("c",cVal);

String padVal = "…";

doc.put("pad",padVal);

aDocs[i]=doc;

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

globalInserts.addAndGet(documentsPerInsert);

}

long endTime = System.currentTimeMillis();

What are else you measuring?

Object creation and GC management?

Clock resolution?

Thread contention on nextInt()?

Time to synthesize data?

Thread contention on addAndGet()?

Page 20: Mythbusting: Understanding How We Measure Performance at MongoDB

// Pre Create the Object outside the Loop

BasicDBObject[] aDocs = new BasicDBObject[documentsPerInsert];

for (int i=0; i < documentsPerInsert; i++) {

BasicDBObject doc = new BasicDBObject();

String cVal = "…";

doc.put("c",cVal);

String padVal = "…";

doc.put("pad",padVal);

aDocs[i] = doc;

}

Solution: Pre-Create the objects

Pre-create non varying data outside the timing loop

Alternative

• Pre-create the data in a file; load from file

Page 21: Mythbusting: Understanding How We Measure Performance at MongoDB

// Use ThreadLocalRandom generator or an instance of java.util.Random per thread

java.util.concurrent.ThreadLocalRandom rand;

for (long roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

doc = aDocs[i];

doc.put("_id",id);

doc.put("k", nextInt(rand, numMaxInserts)+1);

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

}

// Maintain count outside the loop

globalInserts.addAndGet(documentsPerInsert * roundNum);

Solution: Remove contention

Remove contention nextInt() by making Thread local

Page 22: Mythbusting: Understanding How We Measure Performance at MongoDB

// Use ThreadLocalRandom generator or an instance of java.util.Random per thread

java.util.concurrent.ThreadLocalRandom rand;

for (long roundNum = 0; roundNum < numRounds; roundNum++) {

for (int i = 0; i < documentsPerInsert; i++) {

id++;

doc = aDocs[i];

doc.put("_id",id);

doc.put("k", nextInt(rand, numMaxInserts)+1);

}

coll.insert(aDocs);

numInserts += documentsPerInsert;

}

// Maintain count outside the loop

globalInserts.addAndGet(documentsPerInsert * roundNum);

Solution: Remove contention

Remove contention on addAndGet()

Remove contention nextInt() by making Thread local

Page 23: Mythbusting: Understanding How We Measure Performance at MongoDB

long startTime = System.currentTimeMillis();

long endTime = System.currentTimeMillis();

long startTime = System.nanoTime();

long endTime = System.nanoTime() - startTime;

Solution: Timer resolution

"resolution is at least as good as that of currentTimeMillis()"

"granularity of the value depends on the underlying operating system and may be larger"

Source

• http://docs.oracle.com/javase/7/docs/api/java/lang/System.html

Page 24: Mythbusting: Understanding How We Measure Performance at MongoDB

General Principal #1Know what you are measuring

Page 25: Mythbusting: Understanding How We Measure Performance at MongoDB

BasicDBObject doc = new BasicDBObject();

doc.put("v", str); // str is a 2k string

for (int i=0; i < 1000; i++) {

doc.put("_id",i); coll.insert(doc);

}

BasicDBObject predicate = new BasicDBObject();

long startTime = System.currentTimeMillis();

DBCursor cur = coll.find(predicate);

DBObject foundObj;

while (cur.hasNext()) {

foundObj = cur.next();

}

long endTime = System.currentTimeMillis();

#2 Response time to return all results

Page 26: Mythbusting: Understanding How We Measure Performance at MongoDB

BasicDBObject doc = new BasicDBObject();

doc.put("v", str); // str is a 2k string

for (int i=0; i < 1000; i++) {

doc.put("_id",i); coll.insert(doc);

}

BasicDBObject predicate = new BasicDBObject();

long startTime = System.currentTimeMillis();

DBCursor cur = coll.find(predicate);

DBObject foundObj;

while (cur.hasNext()) {

foundObj = cur.next();

}

long endTime = System.currentTimeMillis();

#2 Response time to return all results

Page 27: Mythbusting: Understanding How We Measure Performance at MongoDB

BasicDBObject doc = new BasicDBObject();

doc.put("v", str); // str is a 2k string

for (int i=0; i < 1000; i++) {

doc.put("_id",i); coll.insert(doc);

}

BasicDBObject predicate = new BasicDBObject();

long startTime = System.currentTimeMillis();

DBCursor cur = coll.find(predicate);

DBObject foundObj;

while (cur.hasNext()) {

foundObj = cur.next();

}

long endTime = System.currentTimeMillis();

#2 Response time to return all results

Page 28: Mythbusting: Understanding How We Measure Performance at MongoDB

BasicDBObject doc = new BasicDBObject();

doc.put("v", str); // str is a 2k string

for (int i=0; i < 1000; i++) {

doc.put("_id",i); coll.insert(doc);

}

BasicDBObject predicate = new BasicDBObject();

long startTime = System.currentTimeMillis();

DBCursor cur = coll.find(predicate);

DBObject foundObj;

while (cur.hasNext()) {

foundObj = cur.next();

}

long endTime = System.currentTimeMillis();

#2 Response time to return all results

Page 29: Mythbusting: Understanding How We Measure Performance at MongoDB

BasicDBObject doc = new BasicDBObject();

doc.put("v", str); // str is a 2k string

for (int i=0; i < 1000; i++) {

doc.put("_id",i); coll.insert(doc);

}

BasicDBObject predicate = new BasicDBObject();

long startTime = System.currentTimeMillis();

DBCursor cur = coll.find(predicate);

DBObject foundObj;

while (cur.hasNext()) {

foundObj = cur.next();

}

long endTime = System.currentTimeMillis();

So that looks ok, right?

Page 30: Mythbusting: Understanding How We Measure Performance at MongoDB

BasicDBObject doc = new BasicDBObject();

doc.put("v", str); // str is a 2k string

for (int i=0; i < 1000; i++) {

doc.put("_id",i); coll.insert(doc);

}

BasicDBObject predicate = new BasicDBObject();

long startTime = System.currentTimeMillis();

DBCursor cur = coll.find(predicate);

DBObject foundObj;

while (cur.hasNext()) {

foundObj = cur.next();

}

long endTime = System.currentTimeMillis();

What else are you measuring?

Each doc is is 4080 bytes on disk with powerOf2Sizes

Page 31: Mythbusting: Understanding How We Measure Performance at MongoDB

BasicDBObject doc = new BasicDBObject();

doc.put("v", str); // str is a 2k string

for (int i=0; i < 1000; i++) {

doc.put("_id",i); coll.insert(doc);

}

BasicDBObject predicate = new BasicDBObject();

long startTime = System.currentTimeMillis();

DBCursor cur = coll.find(predicate);

DBObject foundObj;

while (cur.hasNext()) {

foundObj = cur.next();

}

long endTime = System.currentTimeMillis();

What else are you measuring?

Each doc is is 4080 bytes on disk with powerOf2Sizes

Unrestricted predicate?

Page 32: Mythbusting: Understanding How We Measure Performance at MongoDB

BasicDBObject doc = new BasicDBObject();

doc.put("v", str); // str is a 2k string

for (int i=0; i < 1000; i++) {

doc.put("_id",i); coll.insert(doc);

}

BasicDBObject predicate = new BasicDBObject();

long startTime = System.currentTimeMillis();

DBCursor cur = coll.find(predicate);

DBObject foundObj;

while (cur.hasNext()) {

foundObj = cur.next();

}

long endTime = System.currentTimeMillis();

What else are you measuring?

Each doc is is 4080 bytes on disk with powerOf2Sizes

Measuring• Time to parse &

execute query• Time to retrieve all

documentBut also• Cost of shipping

~4MB data through network stack

Unrestricted predicate?

Page 33: Mythbusting: Understanding How We Measure Performance at MongoDB

BasicDBObject predicate = new BasicDBObject();

predicate.put("_id", new BasicDBObject("$gte", 10).append("$lte", 20));

BasicDBObject projection = new BasicDBObject();

projection.put("_id", 1);

long startTime = System.currentTimeMillis();

DBCursor cur = coll.find(predicate, projection );

DBObject foundObj;

while (cur.hasNext()) {

foundObj = cur.next();

}

long endTime = System.currentTimeMillis();

Solution: Limit the projection

Return fixed range

Page 34: Mythbusting: Understanding How We Measure Performance at MongoDB

BasicDBObject predicate = new BasicDBObject();

predicate.put("_id", new BasicDBObject("$gte", 10).append("$lte", 20));

BasicDBObject projection = new BasicDBObject();

projection.put("_id", 1);

long startTime = System.currentTimeMillis();

DBCursor cur = coll.find(predicate, projection );

DBObject foundObj;

while (cur.hasNext()) {

foundObj = cur.next();

}

long endTime = System.currentTimeMillis();

Solution: Limit the projection

Only project _id

Return fixed range

Page 35: Mythbusting: Understanding How We Measure Performance at MongoDB

BasicDBObject predicate = new BasicDBObject();

predicate.put("_id", new BasicDBObject("$gte", 10).append("$lte", 20));

BasicDBObject projection = new BasicDBObject();

projection.put("_id", 1);

long startTime = System.currentTimeMillis();

DBCursor cur = coll.find(predicate, projection );

DBObject foundObj;

while (cur.hasNext()) {

foundObj = cur.next();

}

long endTime = System.currentTimeMillis();

Solution: Limit the projection

Only project _id

Only 46k transferred through network stack

Return fixed range

Page 36: Mythbusting: Understanding How We Measure Performance at MongoDB

General Principal #2Measure only what you need to measure

Page 37: Mythbusting: Understanding How We Measure Performance at MongoDB

Part TwoPerformance measurement & diagnosis

Page 38: Mythbusting: Understanding How We Measure Performance at MongoDB

Broad categories

• Micro Benchmarks

• Workloads

Page 39: Mythbusting: Understanding How We Measure Performance at MongoDB

Micro benchmarks: mongo-perf

Page 40: Mythbusting: Understanding How We Measure Performance at MongoDB

mongo-perf: goals

• Measure– commands

• Configure– Single mongod, ReplSet size (1 -> n), Sharding– Single vs. Multiple DB– O/S

• Characterize– Throughput (ops/second) by thread count

• Compare

Page 41: Mythbusting: Understanding How We Measure Performance at MongoDB

What do you get?

Better

Thread Count

Ops/

Sec

Page 42: Mythbusting: Understanding How We Measure Performance at MongoDB

What do you get?

Measured improvement

between rc0 and rc2

Better

Page 43: Mythbusting: Understanding How We Measure Performance at MongoDB

tests.push( { name: "Commands.CountsIntIDRange", pre: function( collection ) { collection.drop(); for ( var i = 0; i < 1000; i++ ) { collection.insert( { _id : i } ); } collection.getDB().getLastError(); }, ops: [ { op: "command", ns : "testdb", command : { count : "mycollection", query : { _id : { "$gt" : 10, "$lt" : 100 } } } } ] } );

Benchmark source code

Page 44: Mythbusting: Understanding How We Measure Performance at MongoDB

tests.push( { name: "Commands.CountsIntIDRange", pre: function( collection ) { collection.drop(); for ( var i = 0; i < 1000; i++ ) { collection.insert( { _id : i } ); } collection.getDB().getLastError(); }, ops: [ { op: "command", ns : "testdb", command : { count : "mycollection", query : { _id : { "$gt" : 10, "$lt" : 100 } } } } ] } );

Benchmark source code

Page 45: Mythbusting: Understanding How We Measure Performance at MongoDB

tests.push( { name: "Commands.CountsIntIDRange", pre: function( collection ) { collection.drop(); for ( var i = 0; i < 1000; i++ ) { collection.insert( { _id : i } ); } collection.getDB().getLastError(); }, ops: [ { op: "command", ns : "testdb", command : { count : "mycollection", query : { _id : { "$gt" : 10, "$lt" : 100 } } } } ] } );

Benchmark source code

Page 46: Mythbusting: Understanding How We Measure Performance at MongoDB

tests.push( { name: "Commands.CountsIntIDRange", pre: function( collection ) { collection.drop(); for ( var i = 0; i < 1000; i++ ) { collection.insert( { _id : i } ); } collection.getDB().getLastError(); }, ops: [ { op: "command", ns : "testdb", command : { count : "mycollection", query : { _id : { "$gt" : 10, "$lt" : 100 } } } } ] } );

Benchmark source code

Page 47: Mythbusting: Understanding How We Measure Performance at MongoDB

Code Change

Page 48: Mythbusting: Understanding How We Measure Performance at MongoDB

Workloads

• "public" workloads– YCSB– Sysbench

• "real world" simulations– Inbox fan in/out– Message Stores– Content Management

Page 49: Mythbusting: Understanding How We Measure Performance at MongoDB

Example: Bulk Load Performance16m Documents

Better

55% degradation 2.6.0-rc1 vs

2.4.10

Page 50: Mythbusting: Understanding How We Measure Performance at MongoDB

Ouch… where's the tree in the woods?

• 2.4.10 -> 2.6.0– 4495 git commits

Page 51: Mythbusting: Understanding How We Measure Performance at MongoDB

git-bisect

• Bisect between good/bad hashes

• git-bisect nominates a new githash– Build against githash– Re-run test– Confirm if this githash is good/bad

• Rinse and repeat

Page 52: Mythbusting: Understanding How We Measure Performance at MongoDB

Code Change - Bad Githash

Page 53: Mythbusting: Understanding How We Measure Performance at MongoDB

Code Change - Fix

Page 54: Mythbusting: Understanding How We Measure Performance at MongoDB

Bulk Load Performance - Fix

Better

11% improvement

2.6.1 vs 2.4.10

Page 55: Mythbusting: Understanding How We Measure Performance at MongoDB

The problem with measurement

• Observability– What can you observe on the system?

• Effect– What effects does the observation cause?

Page 56: Mythbusting: Understanding How We Measure Performance at MongoDB

mtools

Page 57: Mythbusting: Understanding How We Measure Performance at MongoDB

mtools

• MongoDB log file analysis– Filter logs for operations, events– Response time, lock durations– Plot

• https://github.com/rueckstiess/mtools

Page 58: Mythbusting: Understanding How We Measure Performance at MongoDB

Code Change – Yielding Policy

Page 59: Mythbusting: Understanding How We Measure Performance at MongoDB

Code Change

Page 60: Mythbusting: Understanding How We Measure Performance at MongoDB

Response TimesBulk Insert 2.6.0 vs 2.6.1

Ceiling similar, lower floor resulting in 40% improvement in

throughput

Page 61: Mythbusting: Understanding How We Measure Performance at MongoDB

Secondary effects of Yield policy changeWrite lock time reduced

Order of magnitude reduction of write lock

duration

Page 62: Mythbusting: Understanding How We Measure Performance at MongoDB

> db.serverStatus()

Yes – will cause a read lock to be acquired

> db.serverStatus({recordStats:0})

No – lock is not acquired

> mongostat

Yes - until SERVER-14008 resolved, uses db.serverStatus()

Unexpected side effects of measurement?

Page 63: Mythbusting: Understanding How We Measure Performance at MongoDB

CPU sampling

• Get an impression of– Call Graphs– CPU time spent on node and called nodes

Page 64: Mythbusting: Understanding How We Measure Performance at MongoDB

> sudo apt-get install google-perftools

> sudo apt-get install libunwind7-dev

> scons --use-cpu-profiler mongod

Setup & building with google-profiler

Page 65: Mythbusting: Understanding How We Measure Performance at MongoDB

> mongod –dbpath <…>

Note: Do not use –fork

> mongo

> use admin

> db.runCommand({_cpuProfilerStart: {profileFilename: 'foo.prof'}})

Execute some commands that you want to profile

> db.runCommand({_cpuProfilerStop: 1})

Start the profiling

Page 66: Mythbusting: Understanding How We Measure Performance at MongoDB

Sample start vs. end of workload

Page 67: Mythbusting: Understanding How We Measure Performance at MongoDB

Sample start vs. end of workload

Page 68: Mythbusting: Understanding How We Measure Performance at MongoDB

Code change

Page 69: Mythbusting: Understanding How We Measure Performance at MongoDB

Public Benchmarks – Not all forks are the same…

• YCSB– https://github.com/achille/YCSB

• sysbench-mongodb– https://github.com/mdcallag/sysbench-mongodb

Page 70: Mythbusting: Understanding How We Measure Performance at MongoDB

[email protected]

VP, Engineering

Andrew Erlichson

#MongoDBDays

Thank You


Top Related