SlideShare a Scribd company logo
Optimising for performance, scale, analytics
~3333 write ops/s   0.07 - 0.05 ms response
David Mytton




Woop Japan!
MongoDB: Optimising for Performance, Scale & Analytics
MongoDB at Server Density
MongoDB at Server Density
•27 nodes
MongoDB at Server Density
•27 nodes
• June 2009 - +3yrs
MongoDB at Server Density
•27 nodes
• June 2009 - +3yrs
•MySQL -> MongoDB
MongoDB at Server Density
•27 nodes
• June 2009 - +3yrs
•MySQL -> MongoDB
•17TB data per month
MongoDB at Server Density


Queues

               Primary
              data store

Time series
Why?
Why?


• Replication
Why?


• Replication
• Official drivers
Why?


• Replication
• Official drivers
• Easy deployment
Why?


• Replication
• Official drivers
• Easy deployment
• Fast out of the box   (sort of)
Fast out of the box?




Photo: dannychoo.com
~3333 write ops/s   0.07 - 0.05 ms response
Fast out of the box?

• Softlayer cloud (1 core, 8GB)




Photo: dannychoo.com
Fast out of the box?

• Softlayer cloud (1 core, 8GB)
• Local instance storage



Photo: dannychoo.com
Fast out of the box?

• Softlayer cloud (1 core, 8GB)
• Local instance storage
• Ubuntu 10/12.04 LTS

Photo: dannychoo.com
MongoDB: Optimising for Performance, Scale & Analytics
Fast out of the box?

• Journaling




Photo: dannychoo.com
Fast out of the box?

• Journaling
• Replication



Photo: dannychoo.com
Fast out of the box?




Picture is unrelated! Mmm, ice cream.
Fast out of the box?

• Fast network




Picture is unrelated! Mmm, ice cream.
Fast out of the box?

• Fast network
• Working set in RAM



Picture is unrelated! Mmm, ice cream.
mongos> db.metrics_20120508_15_1m.stats()
{
    "sharded" : true,
    "flags" : 1,
    "ns" : "metrics.metrics_20120508_15_1m",
    "count" : 2752934,
    "numExtents" : 46,
    "size" : 746837640,
    "storageSize" : 823717888,
    "totalIndexSize" : 517581680,
    "indexSizes" : {
        "_id_" : 130358144,
        "a_1_i_1" : 155711920,
        "a_1_i_1_m_1_t_1" : 231511616
    },
    "avgObjSize" : 271.2878841265355,
    "nindexes" : 3,
    "nchunks" : 61,
"size" : 746837640,
    "totalIndexSize" : 517581680




Indexes = 493MB      Data = 712MB
"size" : 746837640,
    "totalIndexSize" : 517581680




Indexes = 493MB      Data = 712MB
"size" : 746837640,
    "totalIndexSize" : 517581680




Indexes = 493MB        Data = 712MB



            Total = 1205MB
Where should it go?


                                                     Should it be in
                            What?
                                                       memory?


                            Indexes                      Always


                               Data                     If you can



http://www.flickr.com/photos/comedynose/4388430444/
How you’ll know

1) Slow queries

                 Thu Oct 14 17:01:11 [conn7410] update sd.apiLog
                query: { c: "android/setDeviceToken", a: 1466, u:
                 "blah", ua: "Server Density Android" } 51926ms




www.flickr.com/photos/tonivc/2283676770/
How you’ll know

2) Timeouts

    cursor timed out (20000 ms)
How you’ll know

3) Disk i/o spikes




www.flickr.com/photos/daddo83/3406962115/
Fast out of the box?

• Fast network
• Working set in RAM



Picture is unrelated! Mmm, ice cream.
Fast out of the box?

• Fast network
• Working set in RAM
• Fast disks (optional)

Picture is unrelated! Mmm, ice cream.
MongoDB: Optimising for Performance, Scale & Analytics
MongoDB: Optimising for Performance, Scale & Analytics
Growing documents is bad
Updates in place




db.my_collection.update( { _id : ... },
{ $inc : { y : 2 } } )
BSON
BSON
Growing documents is bad



> db.coll.stats()
{
        "ns" : "...", ...,
        "paddingFactor" : 1, ...,
        "ok" : 1
}
Scaling writes

• Global DB lock
Scaling writes

• Global DB lock
• Concurrency
http://blog.pythonisito.com/2011/12/mongodbs-write-lock.html
http://blog.pythonisito.com/2011/12/mongodbs-write-lock.html
http://bit.ly/mongolock
Fast out of the box?

• Fast network
• Working set in RAM
• Fast disks (optional)
• Sharding (optional)
Picture is unrelated! Mmm, ice cream.
Scaling writes

• Global DB lock
• Concurrency
• Sharding
Scaling writes
MongoDB: Optimising for Performance, Scale & Analytics
Scaling writes

• Collection location
Scaling writes

• Collection location
• Pre-split / moveChunk
Scaling writes

• Collection location
• Pre-split / moveChunk
• Hashing (v2.4)
Failover

•Replica sets
Failover

•Replica sets
                •Master/slave
Failover

•Replica sets
                •Master/slave
                •Min 3 nodes
Failover

•Replica sets
                •Master/slave
                •Min 3 nodes
            •Automatic failover
rs.status()

       {
       !     "_id" : 1,
       !     "name" : "rs3b:27018",
       !     "health" : 1,
       !     "state" : 2,
       !     "stateStr" : "SECONDARY",
       !     "uptime" : 1886098,
       !     "optime" : {
       !     ! "t" : 1291252178000,
       !     ! "i" : 13
       !     },
       !     "optimeDate" : ISODate("2010-12-02T01:09:38Z"),
             "lastHeartbeat" : ISODate("2010-12-02T01:09:38Z")
       },


www.ex-astris-scientia.org/inconsistencies/ent_vs_tng.htm (yes it’s a replicator from Star Trek)
rs.status()

1) myState
       Value           Meaning
         0   Starting up (phase 1)
         1   Primary
         2   Secondary
         3   Recovering
         4   Fatal error
         5   Starting up (phase 2)
         6   Unknown state
         7   Arbiter
         8   Down
rs.status()

2) Optime

         "optimeDate" : ISODate("2010-12-02T01:09:38Z")




www.flickr.com/photos/robbie73/4244846566/
rs.status()

3) Heartbeat

         "lastHeartbeat" : ISODate("2010-12-02T01:09:38Z")




www.flickr.com/photos/drawblindfaith/3400981091/
Scaling reads
Scaling reads

•Replica slaves
Scaling reads

•Replica slaves
•Consistency
Scaling reads

•Replica slaves
•Consistency
•w flag / tags
WriteConcern




Changed Nov 27 2012
WriteConcern

• Safe by default

   >>> from pymongo import MongoClient
   >>> connection = MongoClient()
WriteConcern

• Safe by default

  >>> from pymongo import MongoClient
  >>> connection = MongoClient(w=int/str)

          Value            Meaning
            0     Unsafe
            1     Primary
            2     Primary + x1 secondary
            3     Primary + x2 secondaries
Tags


{
    _id : "someSet",
    members : [
        {_id : 0, host : "A", tags : {"dc":   "ny"}},
        {_id : 1, host : "B", tags : {"dc":   "ny"}},
        {_id : 2, host : "C", tags : {"dc":   "sf"}},
        {_id : 3, host : "D", tags : {"dc":   "sf"}},
        {_id : 4, host : "E", tags : {"dc":   "cloud"}}
    ]
    settings : {
        getLastErrorModes : {
            veryImportant : {"dc" : 3},
            sortOfImportant : {"dc" : 2}
        }
    }
}
> db.foo.insert({x:1})
> db.runCommand({getLastError : 1, w : "veryImportant"})
Tags


{
    _id : "someSet",
                               (A or B) + (C or D) + E
    members : [
        {_id : 0, host : "A", tags : {"dc":   "ny"}},
        {_id : 1, host : "B", tags : {"dc":   "ny"}},
        {_id : 2, host : "C", tags : {"dc":   "sf"}},
        {_id : 3, host : "D", tags : {"dc":   "sf"}},
        {_id : 4, host : "E", tags : {"dc":   "cloud"}}
    ]
    settings : {
        getLastErrorModes : {
            veryImportant : {"dc" : 3},
            sortOfImportant : {"dc" : 2}
        }
    }
}
> db.foo.insert({x:1})
> db.runCommand({getLastError : 1, w : "veryImportant"})
Tags


{
    _id : "someSet",
                                 (A + C) or (D + E) ...
    members : [
        {_id : 0, host : "A", tags : {"dc":   "ny"}},
        {_id : 1, host : "B", tags : {"dc":   "ny"}},
        {_id : 2, host : "C", tags : {"dc":   "sf"}},
        {_id : 3, host : "D", tags : {"dc":   "sf"}},
        {_id : 4, host : "E", tags : {"dc":   "cloud"}}
    ]
    settings : {
        getLastErrorModes : {
            veryImportant : {"dc" : 3},
            sortOfImportant : {"dc" : 2}
        }
    }
}
> db.foo.insert({x:1})
> db.runCommand({getLastError : 1, w : "sortOfImportant"})
WriteConcern

• Safe by default
•J
WriteConcern

• Safe by default
•J
• fsync
Bottlenecks

•EC2
Bottlenecks

•EC2
       •Local storage
Bottlenecks

•EC2
             •Local storage
   •EBS: RAID10 4-8 volumes
Bottlenecks

•EC2
               •Local storage
    •EBS: RAID10 4-8 volumes
•i/o: rand but not sequential
http://www.slideshare.net/jrosoff/mongodb-on-ec2-and-ebs
http://bit.ly/
ec2mongodb
Bottlenecks

•CPU
       •Index building
Tips: rand()

•_id
Tips: rand()

•_id
•Field names
Tips: rand()

•_id
•Field names
•Covered indexes
Tips: rand()

•_id
•Field names
•Covered indexes
•Collections / databases
mongostat
mongostat

Locks/Queues
mongostat

Diagnostics
Current operations
    db.currentOp();
    {
    ! ! ! "opid" : "shard1:299939199",
    ! ! ! "active" : true,
    ! ! ! "lockType" : "write",
    ! ! ! "waitingForLock" : false,
    ! ! ! "secs_running" : 15419,
    ! ! ! "op" : "remove",
    ! ! ! "ns" : "sd.metrics",
    ! ! ! "query" : {
    ! ! ! ! "accId" : 1391,
    ! ! ! ! "tA" : {
    ! ! ! ! ! "$lte" : ISODate("2010-11-24T19:53:00Z")
    ! ! ! ! }
    ! ! ! },
    ! ! ! "client" : "10.121.12.228:44426",
    ! ! ! "desc" : "conn"
    ! ! },
www.flickr.com/photos/jeffhester/2784666811/
Monitoring tools

Run yourself




    Ganglia
Monitoring tools

Server Density
Fast out of the box?

• Fast network
• Working set in RAM



Picture is unrelated! Mmm, ice cream.
Fast out of the box?

• Fast network
• Working set in RAM
• bit.ly/benchrun

Picture is unrelated! Mmm, ice cream.
www.serverdensity.com/mdb



Woop Japan!
David Mytton

 @davidmytton

david@serverdensity.com

www.serverdensity.com

Woop Japan!

More Related Content

MongoDB: Optimising for Performance, Scale & Analytics