如果有一个mongod已经有数据,则配置分片时数据不可见

问题描述

如果有一个mongod已经有数据,则在配置分片时该数据不可见 详细地 两个mongods具有相同名称的集合,并存储以下数据 信息(A,B mongod)

@H_404_3@DB : db_test
Collection : test_log

一个蒙古人

@H_404_3@{ "_id" : ObjectId("5f44cfa372c25aeff48e66d3"),"skey" : 100,"data" : 1 }

B mongod

@H_404_3@{ "_id" : ObjectId("5f44cf731eadcef49cd93e7b"),"skey" : 200,"data" : 2 }

在蒙哥斯,我执行了以下命令

@H_404_3@mongos> sh.addShard("A.MASTER:21011")
    { "shardAdded" : "shard0000","ok" : 1 }
    
    mongos> sh.addShard("B.SLAVE1:21011")
    { "shardAdded" : "shard0001","ok" : 1 }
    
    mongos> sh.addShardTag("shard0000","master")
    WriteResult({ "nMatched" : 1,"nUpserted" : 0,"nModified" : 1 })
    mongos> sh.addShardTag("shard0001","slave_1")
    WriteResult({ "nMatched" : 1,"nModified" : 1 })
    
    mongos> sh.enableSharding("db_test")
    { "ok" : 1 }
    
    mongos> sh.shardCollection("db_test.test_log",{skey:1})
    { "collectionsharded" : "db_test.test_log","ok" : 1 }

    mongos> sh.addTagRange("db_test.test_log",{skey:100},{skey:199},"master")
    WriteResult({
        "nMatched" : 0,"nUpserted" : 1,"nModified" : 0,"_id" : {
            "ns" : "db_test.test_log","min" : {
                "skey" : 100
            }
        }
    })
    mongos> sh.addTagRange("db_test.test_log",{skey:200},{skey:299},"slave_1")
    WriteResult({
        "nMatched" : 0,"min" : {
                "skey" : 200
            }
        }
    })

然后我在mongos中查找了数据(执行了“ find,aggregate ..”命令) 结果

@H_404_3@mongos> db.test_log.find()
{ "_id" : ObjectId("5f44cfa372c25aeff48e66d3"),"data" : 1 }

在分片之前,我执行了Command(创建索引(使用分片))

@H_404_3@mongos> db.test_log.createIndex({ "skey": 1 });
{
    "raw" : {
        "A.MASTER:21011" : {
            "createdCollectionAutomatically" : false,"numIndexesBefore" : 1,"numIndexesAfter" : 2,"ok" : 1
        }
    },"ok" : 1
}

我想知道是什么问题 在mongos中创建索引时,我也对仅分配给A.master的部分感到好奇。 请..

解决方法

在分片收集之前,收集数据应全部驻留在1个分片上。

运行shardCollection时,将在数据库的主分片上创建任何初始块。

其他块是通过拆分已经存在的块创建的。

当平衡器将一个块从一个分片移动到另一个分片时,它首先从目标集合中删除该块所覆盖的文档范围。

通过mongos查询时,路由器会与配置服务器进行检查,以找出哪些分片包含查询可能需要的分片,并将查询仅定向到那些分片。

标签和标签范围由平衡器查询,以确定将块移动到何处。 mongos路由器不咨询这些。

因此,在您的方案中发生的事情是,您有一个数据库,该数据库的集合存在于多个mongod节点上,每个节点的索引都位于{skey: 1}

然后您通过将两个mongod节点都添加为单独的分片来创建分片集群。

此时,配置服务器将没有有关数据库或集合的任何信息。

运行enableSharding时,配置服务器为数据库创建了一个配置文档,并将其中一个分片指定为数据库的主分片。 此时,对该数据库中任何未分片集合的任何查询都将由主分片处理。

当您运行shardCollection时,配置服务器会为该集合创建一个标识分片键的文档。它还创建了一个从MinKey到MaxKey的单个块,该块被标识为驻留在数据库的主分片上。

随后的数据查询由mongos提供,mongos查阅了集合的数据块列表,发现只有1个数据块。然后,它将请求转发给拥有的分片,分片返回其拥有的数据。另一个分片将永远不会被使用。

您可以通过运行sh.status(true)来检查块的分布方式。

在这一点上,拆分现有的块并使其平衡将无济于事,因为在移动块之前会清除范围。这意味着在移动空白块之前,将删除另一个分片上的所有文档。

没有简单的方法来获取2个单独的副本集,这些副本集已包含数据并将它们连接到分片群集中。在这种情况下,最简单的方法是对所有副本集进行数据转储,与另一个副本集创建分片群集,然后在所有数据库上启用分片,然后将其余副本集添加为第二个分片,然后mongorestore其余数据

对于包含数据的单个副本集,有一个记录到Convert a Replica Set to a Sharded Cluster

的过程。