Three points about this:
1) The only reasonable way to handle such situations is to query the
DB and insert new document, or add the new information to the existing
one using update.
Adding the new information using an update would be more efficient
than query and then insert (you would use the "upsert" flag to avoid
potential race conditions). Query and then insert or update by
application is not only less efficient, but it is prone to race
conditions if two threads are trying to insert the same document at
once.
2) Pre-splitting the data is not an option, because I need to record
data coming from a streaming interface at the rate of 10-100 docs per
second.
Pre-splitting refers to splitting the shard key ranges into many
chunks and distributing them evenly across your cluster *before* you
load any data - moving empty chunks is very inexpensive. Hash shard
keys already are supposed to do this, and so there should have been no
migrations during your data load *except* when you add a new shard to
an already populated cluster.
So in your second test with unhashed shard key I'm saying that
splitting the chunks and distributing them over the shards before
starting the data load would have avoided the "very long periods of
time when only one node was accepting all incoming records" while
competing for resources with the balancer.
3) The sharding key is almost monotonic.
This means that inserts are almost always going to be going into only
a single chunk (highest one) and the only reason that the distribution
will end up even is that there is an "edge case" handling code in
sharding where when it detects that all the inserts are going into the
highest chunk on the next split it will split it near the max and
migrate the new highest empty chunk to another shard. But if the
reason you needed sharding is to distribute the write load then a
monotonically increasing shard key is a poor choice.
Another thing I would say is that I wish you would file a Jira SERVER
ticket - if balancing with hashed shard keys is slower than balancing
with unhashed shard keys then I feel that it is possible that there is
simply a bug (which hopefully could be fixed if it's identified) and
since your dataset seems to have triggered this behavior it would be
very valuable to figure out why. We did some performance testing
before releasing the hashed shard keys feature and didn't see a
noticeable performance (but I know that there are different hashing
algorithms that were considered and it's possible that on your shard
key values a different hashing algorithm maybe would be measurably
faster.
I just ran a very quick test comparing moving a chunk in two identical
collections when it is sharded based on _id (regular) or on _id hashed
and here are my results for one and the other:
mongos> sh.moveChunk("test.test",{_id:1},"shard0001")
{ "millis" : 1086, "ok" : 1 }
mongos> sh.moveChunk("test.test",{_id:1},"shard0000")
{ "millis" : 1090, "ok" : 1 }
mongos> sh.moveChunk("test.test",{_id:1},"shard0001")
{ "millis" : 1077, "ok" : 1 }
mongos> sh.moveChunk("test.test",{_id:1},"shard0000")
{ "millis" : 1068, "ok" : 1 }
mongos> sh.moveChunk("test.test",{_id:1},"shard0001")
{ "millis" : 1076, "ok" : 1 }
AND the other:
mongos> sh.moveChunk("test.test",{_id:1},"shard0000")
{ "millis" : 1085, "ok" : 1 }
mongos> sh.moveChunk("test.test",{_id:1},"shard0001")
{ "millis" : 2164, "ok" : 1 }
mongos> sh.moveChunk("test.test",{_id:1},"shard0000")
{ "millis" : 1087, "ok" : 1 }
mongos> sh.moveChunk("test.test",{_id:1},"shard0001")
{ "millis" : 1180, "ok" : 1 }
mongos> sh.moveChunk("test.test",{_id:1},"shard0000")
{ "millis" : 1169, "ok" : 1 }
mongos>
You can see that other than the one outlier (second test in my
_UNHASHED_ key test) they were completely equal.
Since you have a test set-up I would love to see the numbers from your
migrations with and without hashing the shard key and since they seem
to show very different performance in your case what exactly differs -
I'm guessing the key that's being sharded, but maybe there is
something else in the environment that I haven't thought of yet.
Asya
On Thu, Sep 5, 2013 at 10:32 PM, Jacek Radzikowski