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

时间:2014-01-02 10:20:15

标签: mongodb sharding

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

现在我要对这些集合进行分片。我打算让每个客户端在插入新集合之前调用shardCollection。但是客户端彼此不协调,因此多个客户端可能会同时在同一个(新)集合上调用shardCollection。 (他们将首先检查集合是否存在,但是存在不可避免的竞争条件。)

Mongo shardCollection documentation说:

  

警告:不要同时在同一个集合上运行多个shardCollection命令。

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

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

  • 对shardCollection的多次调用将是相同的(相同的分片键等)。
  • 在进行任何插入之前,每个应用程序都会等待自己对shardCollection的调用。
  • 因此,在插入任何文档之前,shardCollection将至少在空集合上成功完成一次。

最后,Mongo shell命令sh.shardCollection不包含上面的警告。它是在Mongo shell中实现的,所以我的驱动程序(reactivemongo)不提供它。这是否意味着它包含了我应该复制的一些逻辑?

基本原理:我的馆藏按日期和其他参数进行逻辑分区。也就是说,集合名称指定日期和其他参数。我创建了我需要的每个集合,并在第一次插入之前调用ensureIndex。这允许我有效地删除/备份/恢复旧集合。

1 个答案:

答案 0 :(得分:0)

假设您通过了所有相关检查(没有上限,分片密钥通过,而不是系统集合等),那么如果您发出另一个shardCollection命令,您应该只收到该集合已经分片的消息(请参阅here)。如果您保证命令相同(每个命名空间的分片键相同),则至少删除竞争请求竞争条件。

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

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

> 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变量中的字符串是构造命令时所需的部分(并注意它随后使用admin帮助程序对adminCommand数据库运行。 / p>