【问题标题】:MongoDB replicates data to all shardsMongoDB 将数据复制到所有分片
【发布时间】:2012-06-12 07:15:42
【问题描述】:

我在测试环境中有 4 台服务器,用于测试 MongoDB 副本和分发: RepSetA 拥有 RepSetA1 和 RepSetA2。 RepSetB 拥有 RepSetB1 和 RepSetB2。 所有服务器都充当路由器,RepSetA1 充当单个配置服务器。

我有一个“播放器”数据(10,000 条记录,该对象包含一个“Id”和一个“Name”字段),我希望它在副本集之间分片(或分布),并在服务器之间克隆在同一个副本集中。因此,仅举一个简单的例子: Player1-5000:存在于 RepSetA1 和 RepSetA2 中,但不存在于 RepSetB1 和 RepSetB2 中。 Player5000-10000:RepSetB1 和 RepSetB2 中都存在,但 RepSetA1 和 RepSetA2 中不存在。

我得到的是所有 4 个服务器中的所有玩家。

如果我打印分片状态,我会得到以下信息:

mongos> db.printShardingStatus();

--- Sharding Status ---
  sharding version: { "_id" : 1, "version" : 3 }
  shards:

        {  "_id" : "RepSetA",  "host" : "RepSetA/MongoRepSetA1:27018,MongoRepSetA2:27018" }
        {  "_id" : "RepSetB",  "host" : "RepSetB/MongoRepSetB1:27018,MongoRepSetB2:27018" }
  databases:
        {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
        {  "_id" : "GamesDB",  "partitioned" : true,  "primary" : "RepSetA" }
                GamesDB.Player chunks:
                                RepSetA 2
                        { "_id" : { $minKey : 1 } } -->> { "_id" : 0 } on : RepSetA { "t" : 1000, "i" : 1 }
                        { "_id" : 0 } -->> { "_id" : { $maxKey : 1 } } on : RepSetA { "t" : 1000, "i" : 2 }
        {  "_id" : "test",  "partitioned" : false,  "primary" : "RepSetB" }
        {  "_id" : "EOO",  "partitioned" : false,  "primary" : "RepSetB" }

我使用以下命令构建分片:

db.adminCommand( { addShard : "RepSetA/MongoRepSetA1:27018,MongoRepSetA2:27018" } )
db.adminCommand( { addShard : "RepSetB/MongoRepSetB1:27018,MongoRepSetB2:27018" } )
db.runCommand( { enablesharding : "GamesDB" } );
db.runCommand( { shardcollection : "GamesDB.Player", key : { _id :1 } , unique : true} );

我做错了什么?

【问题讨论】:

  • 您是如何查询哪些玩家存在于哪个分片上的?
  • 使用MongoVue GUI,甚至尝试连接到特定服务器并执行“db.Player.find().limit(100);”

标签: mongodb sharding replicate


【解决方案1】:

如果您通过 mongos 进程连接到您的节点,它看起来就像所有都包含数据。从您的输出来看,并非所有节点上的所有数据都可用。 RepSetA 包含 2 个块,而 RepSetB 应该不包含任何块。您可以通过直接连接节点而不是通过 mongos 来验证这一点。
顺便说一句,如果您使用 MongoDBs ObjectId 作为 _id(shard key),请考虑在另一个 key 上进行分片,因为这将导致所有插入都进入一个节点,因为 key 变化单调。

【讨论】:

  • 如果我使用 MongoVue 或 Mongo.exe shell 直接连接它们,我仍然会在 RepSetA1 和 RepSetB1 中看到相同的记录(它们位于不同的副本集上)。
  • 正如 gregor 和我所指出的,数据被正确分片,而不是复制到所有节点。您是否非常认为您连接到 RepSetB 而不是意外连接到 RepSetA?你用的是什么版本?我唯一能想象的,可能导致这种现象的原因是 mongo.exe 和 MongoGUI 会自动连接到 mongos 而不是 mongod。无论如何,我非常怀疑,情况就是这样。 RepSetA 和 RepSetB 实际上指向不同的 IP/服务器?也许那些指向相同,所以看起来你有 RepSetA 和 RepSetB,而只有 RepSetA。
  • 我尝试查询 RepSetA (MongoRepSetA1 & MongoRepSetA2) 的服务器 - 其中包含 10,000 条插入记录,同样的 10,000 条记录也出现在 RepSetB (MongoRepSetB1 & MongoRepSetB2) 的服务器中。我仔细检查了一切。我正在使用最新的 Mongo 版本(mongodb-win32-x86_64-2.0.5)。顺便说一句,我刚刚尝试使用 MongoVue 从 MongoRepSetA1 中删除一条记录,它也从所有其他节点中删除了它。
  • 嗯,我真的只能想象你的 DNS 设置没有正确完成,所以你总是连接到同一个系统。您能否粘贴一些连接到给定节点时获得的输出,以便我们验证您希望使用的那个)?请通过isMaster 测试您是否真的在 SetA 或 SetB 上。
【解决方案2】:

这很好。它并不表明所有数据都在所有服务器上。输出显示 GamesDB.Player 的所有块(数据)都在 shard RepSetA 上

 GamesDB.Player chunks:
                            RepSetA 2
                    { "_id" : { $minKey : 1 } } -->> { "_id" : 0 } on : RepSetA { "t" : 1000, "i" : 1 }
                    { "_id" : 0 } -->> { "_id" : { $maxKey : 1 } } on : RepSetA { "t" : 1000, "i" : 2 }

这意味着平衡器尚未开始平衡您的块。平衡器仅在有 8 个块差异时才起作用。 http://www.mongodb.org/display/DOCS/Sharding+Administration#ShardingAdministration-Balancing

您可以通过手动拆分块来强制平衡(如果您愿意) http://www.mongodb.org/display/DOCS/Splitting+Shard+Chunks

如果您想更快地看到平衡,您可以减小块大小。 http://www.mongodb.org/display/DOCS/Sharding+Administration#ShardingAdministration-ChunkSizeConsiderations

【讨论】:

  • 看起来不错,但如果我使用 MongoVue 或 Mongo.exe shell 直接连接它们,我会在 RepSetA1 和 RepSetB1(位于不同的副本集)中看到相同的记录。
猜你喜欢
  • 2021-08-21
  • 2019-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-29
  • 1970-01-01
  • 1970-01-01
  • 2013-11-12
相关资源
最近更新 更多