Mongodb 从多个客户端使用Mongo的shardCollection命令安全吗?

Mongodb 从多个客户端使用Mongo的shardCollection命令安全吗?,mongodb,sharding,Mongodb,Sharding,我有多个客户端访问Mongo群集。有时他们需要创建新的集合。在进行任何插入之前,他们会调用ensureIndex 现在我想把这些收藏分成碎片。我打算在插入新集合之前让每个客户端调用shardCollection。但是客户端之间不协调,因此多个客户端可能会同时对同一个新集合调用shardCollection。他们会先检查收藏是否存在,但这是不可避免的竞争条件 Mongo说: 警告:请勿在同一集合上同时运行多个shardCollection命令 这是否意味着我必须协调客户机,或者从专门的单独流程中预

我有多个客户端访问Mongo群集。有时他们需要创建新的集合。在进行任何插入之前,他们会调用ensureIndex

现在我想把这些收藏分成碎片。我打算在插入新集合之前让每个客户端调用shardCollection。但是客户端之间不协调,因此多个客户端可能会同时对同一个新集合调用shardCollection。他们会先检查收藏是否存在,但这是不可避免的竞争条件

Mongo说:

警告:请勿在同一集合上同时运行多个shardCollection命令

这是否意味着我必须协调客户机,或者从专门的单独流程中预创建集合?可能的集合集不是有限的,因此很难预先创建

或者有没有办法让两个并行shardCollection调用安全?我可以保证:

对shardCollection的多个调用将使用相同的shard密钥等。 每个应用程序都将等待自己对shardCollection的调用完成,然后再执行任何插入操作。 因此,在插入任何文档之前,shardCollection将在空集合上至少成功完成一次。 最后,mongoshell命令sh.shardCollection不包含上述警告。它是在Mongo shell中实现的,所以我的驱动程序reactivemongo不提供它。这是否意味着它包含一些我应该复制的逻辑


理由:我的集合按日期和其他参数进行逻辑分区。也就是说,集合名称指定了一天和其他参数。我创建所需的每个集合,并在第一次插入之前调用ensureIndex。这使我能够高效地删除/备份/恢复旧集合

假设您通过了所有相关检查未封顶、shard key通过,而不是系统集合等。然后,如果您发出另一个shardCollection命令,您应该只收到集合已被切分的消息,请参阅。如果您保证每个名称空间的命令都是相同的切分键,那么您至少要删除竞争请求竞争条件

最大的问题是,是否存在一个有问题的竞争条件,即初始shardCollection命令尚未完成,而您发出了另一个相同的命令,以及可能产生的影响-我认为唯一要做的是实际测试和查看。您可能只需要在允许运行这样的命令之前实现一个检查,以避免第一时间的竞争

至于运行命令,如果驱动程序没有为您实现助手,那么他们通常会实现一种运行原始命令的方法。基于的reactivemongo就是这种情况,如果您查看在没有括号的情况下运行的shell helper代码,您会注意到它只是对参数进行一些快速的健全性检查,然后是命令调用本身:

> sh.shardCollection
function ( fullName , key , unique ) {
sh._checkFullName( fullName )
assert( key , "need a key" )
assert( typeof( key ) == "object" , "key needs to be an object" )

var cmd = { shardCollection : fullName , key : key }
if ( unique )
cmd.unique = true;

return sh._adminCommand( cmd );
}

cmd变量中存储的字符串是构造命令时所需的字符串,请注意,然后使用adminCommand helper对管理数据库运行该字符串。

test and see的问题是,很难通过测试证明不存在争用条件。我可以在调用shardCollection之前检查集合是否被切分,如果有一个集合消除了竞争。您建议使用什么check db命令?您可以检查它是否在config.collections中,以确定是否有碎片。您可能可以在config.locks中查找某些内容,以确定是否已经有飞行中的命令,不过我必须进行一些检查/测试,以确定这是否是我要处理的情况。我希望我不会面临任何比赛条件。谢谢