我有多个客户端访问Mongo群集。有时他们需要创建新的集合。他们在进行任何插入之前调用ensureIndex。
现在我要对这些集合进行分片。我打算让每个客户端在插入新集合之前调用shardCollection。但是客户端彼此不协调,因此多个客户端可能会同时在同一个(新)集合上调用shardCollection。 (他们将首先检查集合是否存在,但是存在不可避免的竞争条件。)
Mongo shardCollection documentation说:
警告:不要同时在同一个集合上运行多个shardCollection命令。
这是否意味着我必须协调客户端,或者从专门的单独流程预先创建集合? (可能的集合集合不是有限的,因此预先创建很难。)
或者有没有办法让两个并行的shardCollection调用安全?我可以保证:
最后,Mongo shell命令sh.shardCollection
不包含上面的警告。它是在Mongo shell中实现的,所以我的驱动程序(reactivemongo)不提供它。这是否意味着它包含了我应该复制的一些逻辑?
基本原理:我的馆藏按日期和其他参数进行逻辑分区。也就是说,集合名称指定日期和其他参数。我创建了我需要的每个集合,并在第一次插入之前调用ensureIndex。这允许我有效地删除/备份/恢复旧集合。
答案 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>