Reputation: 1319
I have a mongodb
(version: 2.0.8) installation on an EC2
instance (7GB RAM) and the data size is still less than 1GB
. I am using provisioned 100 IOPS
disk for increased disk performance.
The problem is, I am getting a number of random SLOW QUERIES like the one below, (from mongo log)
db.UserInfoShared query: { _id: "999081873179" } ntoreturn:1 idhack:1 reslen:108 1919ms
Took almost 2 secs
!
It is just an _id
lookup on a collection with around 100,000
entries each less than 500 bytes
in size. The instance has only mongo running in it and normally such lookups takes less than 0.01 sec
.
What could the possible cause for this? what should I try to get it resolved? Any help is much appreciated...
Upvotes: 2
Views: 1968
Reputation: 1319
@angela, @Asya, thanks a lot for helping me out.
As it turned out the main cause of latency was mongodb GLOBAL LOCK
itself. We had a lock percentage which was averaging at 5% and sometime peaks up to 30-50% and that results in the slow queries.
If you are facing this issue, the first thing you have to do it enable mongodb MMS service (mms.10gen.com
), which will give you a lot of insights on what exactly is happening in your db server.
In our case the LOCK PERCENTAGE was really high and there were multiple reasons for it. First thing you have to do to figure it out is to read mongodb documentation on concurrency, http://docs.mongodb.org/manual/faq/concurrency/
The reason for lock can be in application level, mongodb or hardware.
1) Our app was doing a lot of updates
and each update(more than 100 ops/sec
) holds a global lock
in mongodb. The issue was that when an update happens for an entry which is not in memory, mongo will have to load the data into memory first and then update (in memory) and the whole process happens while inside the global lock
. If say the whole thing takes 1 sec to complete (0.75sec
to load the data from disk and 0.25sec
to update in memory), the whole rest of the update calls waits (for the entire 1 sec
) and such updates starts queuing up... and you will notice more and more slows requests in your app server.
The solution for it (while it might sound silly) is to query
for the same data before you make an update
. What it effectively does is moving the 'load data to memory' (0.75sec) part out of the global lock
which greatly reduces your lock percentage
2) The other main cause of global lock is mongodb's data flush
to disk. Basically in every 60sec (or less) mongodb (or the OS) writes the data to disk and a global lock
is held during this process. (This kinda explains the random slow queries). In your MMS stats, see the graph for background flush avg
... if its high, that means you have to get faster disks.
In our case, we moved to a new EBS optimized
instance in EC2
and also bumped our provisioned IOPS
from 100
to 500
which almost halved the background flush avg
and the servers are much happier now.
Upvotes: 3