我有一个mongodb碎片,有2个碎片(比方说A和B),每个碎片有17GB的可用空间.我将包含对象ID的_id设置为分片键.
以下是用于设置db和collection的命令.
sh.enableSharding("testShard");
sh.shardCollection("testShard.shardedCollection", {_id:1});
Run Code Online (Sandbox Code Playgroud)
然后我尝试向mongos服务器发出4,000,000次插入查询.我执行脚本4次以下.
for(var i=0; i<1000000; i++){
db.shardedCollection.insert({x:i});
}
Run Code Online (Sandbox Code Playgroud)
使用_id作为分片键,根据我的理解,所提到的4000000文档将适合1个分片,所有插入仅在分片中发生.
然而,结果并不像我预期的那样,在一个碎片中插入了大约1,300万个文件,在B碎片中插入了另外~270万个文件.
为什么会这样?是否在分片设置命令中缺少某些内容?或者我的理解是错误的,也许在mongodb中有类似默认范围的分片键?
如果有人可以共享默认范围分片键的行为(没有标记识别),将会非常有帮助.
下面是sh.status()结果
shard key: { "_id" : 1 }
chunks:
B 5
A 5
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : ObjectId("540c703398c7efdea6037cbc") } on : B Timestamp(6, 0)
{ "_id" : ObjectId("540c703398c7efdea6037cbc") } -->> { "_id" : ObjectId("540c703498c7efdea603bfe3") } on : A Timestamp(6, 1)
{ "_id" : ObjectId("540c703498c7efdea603bfe3") } -->> { "_id" : ObjectId("540c704398c7efdea605d818") } on : A Timestamp(3, 0)
{ "_id" : ObjectId("540c704398c7efdea605d818") } -->> { "_id" : ObjectId("540c705298c7efdea607f04e") } on : A Timestamp(4, 0)
{ "_id" : ObjectId("540c705298c7efdea607f04e") } -->> { "_id" : ObjectId("540c707098c7efdea60c20ba") } on : B Timestamp(5, 1)
{ "_id" : ObjectId("540c707098c7efdea60c20ba") } -->> { "_id" : ObjectId("540c7144319c0dbee096f7d6") } on : B Timestamp(2, 4)
{ "_id" : ObjectId("540c7144319c0dbee096f7d6") } -->> { "_id" : ObjectId("540c7183319c0dbee09f58ad") } on : B Timestamp(2, 6)
{ "_id" : ObjectId("540c7183319c0dbee09f58ad") } -->> { "_id" : ObjectId("540eb15ddace5b39fbc32239") } on : B Timestamp(4, 2)
{ "_id" : ObjectId("540eb15ddace5b39fbc32239") } -->> { "_id" : ObjectId("540eb192dace5b39fbca8a84") } on : A Timestamp(5, 2)
{ "_id" : ObjectId("540eb192dace5b39fbca8a84") } -->> { "_id" : { "$maxKey" : 1 } } on : A Timestamp(5, 3)
Run Code Online (Sandbox Code Playgroud)
正如@LalitAgarwal所指出的,默认情况下,ObjectIds产生一个错误的分片键。但是,如果您真的不在乎数据位于哪个分片上,而只希望在这些分片之间平均分配写操作和块,则很容易获得:
db.shardedCollection.ensureIndex({_id:"hashed"});
sh.enableSharding("testShard");
sh.shardCollection("testShard.shardedCollection", {_id:"hashed"});
Run Code Online (Sandbox Code Playgroud)
但是,这带来了一些(通常可以忽略不计)的缺点:
一种更好的方法是找到一个非人工的分片密钥。有关详细信息,请阅读选择分片键的注意事项。简而言之:
是的,你是对的,它应该进入单个碎片。但是,虽然在单个分片上进行插入,但平衡器也会平衡分片并将块移动到其他分片。
话虽如此,您应该做的是通过从 mongos 调用以下命令来停止/禁用平衡器。
http://docs.mongodb.org/manual/reference/method/sh.disableBalancing/#sh.disableBalancing
sh.disableBalancing(namespace)
//namespace string The namespace of the collection.
Run Code Online (Sandbox Code Playgroud)
完成后,启动插入件并查看所有插入件的去向。
对于 _id 字段分片,您还可以查看此处:
http://docs.mongodb.org/manual/faq/sharding/#can-you-shard-on-the-id-field
Be aware that ObjectId() values, which are the default value of the _id field,
increment as a timestamp. As a result, when used as a shard key, all new documents
inserted into the collection will initially belong to the same chunk on a single
shard. Although the system will eventually divide this chunk and migrate its contents
to distribute data more evenly, at any moment the cluster can only direct insert
operations at a single shard. This can limit the throughput of inserts. If most of
your write operations are updates, this limitation should not impact your performance.
However, if you have a high insert volume, this may be a limitation.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2083 次 |
最近记录: |