【问题标题】:MongoDB routes all data to one server in a shard clusterMongoDB 将所有数据路由到分片集群中的一台服务器
【发布时间】:2014-04-22 13:18:59
【问题描述】:

我第一次在 windows 上设置了一个 MongoDB 分片集群,如下所述:http://docs.mongodb.org/manual/tutorial/deploy-shard-cluster/

我使用以下脚本来建立配置服务器、mongos 实例和 mongo 数据服务器。

function get-cnfgServerObj($port, $path) {

    $firstCnfgSrv = New-Object PSObject
    $firstCnfgSrv | Add-Member Noteproperty -Name Port -value $port
    $firstCnfgSrv | Add-Member Noteproperty -Name Path -value $path

    return $firstCnfgSrv;
}

$mongodPath = "..\mongod.exe"
$mongosPath = "..\mongos.exe"
$cnfgServers = @(
    (get-cnfgServerObj -port 20001 -path "..\data\configdb20001"),
    (get-cnfgServerObj -port 20002 -path "..\data\configdb20002"),
    (get-cnfgServerObj -port 20003 -path "..\data\configdb20003")
)

$dataServers = @(
    (get-cnfgServerObj -port 27001 -path "..\data\shdb1"),
    (get-cnfgServerObj -port 27002 -path "..\data\shdb2")
)

# Create the mongo config servers first
$cnfgServers | foreach {

    if((Test-Path $_.Path) -eq $false)
    {
        New-Item -Path $_.Path -ItemType Directory
    }

    $args = "--configsvr --dbpath $($_.Path) --port $($_.Port)"
    start-process $mongodPath $args -windowstyle Normal
}

# Create the mongo servers
$dataServers | foreach {

    if((Test-Path $_.Path) -eq $false)
    {
        New-Item -Path $_.Path -ItemType Directory
    }

    $args = "--dbpath $($_.Path) --port $($_.Port)"
    start-process $mongodPath $args -windowstyle Normal
}

# Create the mongos instances
$mongosArgs = "--configdb localhost:20001,localhost:20002,localhost:20003"
start-process $mongosPath $mongosArgs -windowstyle Normal

运行上述脚本后,我连接了 mongos 实例:

mongo --host localhost --port 27017

后来,我添加了分片并在数据库和集合上启用了分片:

// add servers as shards
sh.addShard("localhost:27001")
sh.addShard("localhost:27002")

// Enable sharding on 'foo' db
sh.enableSharding("foo")

// Enable sharding on 'testData' collection of 'foo' database
sh.shardCollection("foo.testData", { "x": 1, "_id": 1 })

最后,我在 mongo shell(连接到 mongos 实例)内运行以下 cmets:

use foo

// init data
for (var i = 1; i <= 2500; i++) db.testData.insert( { x : i } )

后来,我连接到我的一台数据服务器:

mongo --host localhost --port 27001

当我尝试查看 testData 集合中的文档计数时,我看到数字是 2500,它代表了所有文档的计数:

use foo
db.testData.count()

简单地说,数据不是在所有分片之间进行负载平衡的。我在这里做错了什么?

编辑:

这里是 sh.status() 命令结果:

--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "version" : 3,
        "minCompatibleVersion" : 3,
        "currentVersion" : 4,
        "clusterId" : ObjectId("535673272850501ad810ff51")
}
  shards:
        {  "_id" : "shard0000",  "host" : "localhost:27001" }
        {  "_id" : "shard0001",  "host" : "localhost:27002" }
  databases:
        {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
        {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
        {  "_id" : "foo",  "partitioned" : true,  "primary" : "shard0000" }
                foo.testData
                        shard key: { "x" : 1, "_id" : 1 }
                        chunks:
                                shard0001       1
                                shard0000       1
                        { "x" : { "$minKey" : 1 }, "_id" : { "$minKey" : 1 } } -
->> { "x" : 1, "_id" : ObjectId("53567411cb144434eb53f08d") } on : shard0001 Tim
estamp(2, 0)
                        { "x" : 1, "_id" : ObjectId("53567411cb144434eb53f08d")
} -->> { "x" : { "$maxKey" : 1 }, "_id" : { "$maxKey" : 1 } } on : shard0000 Tim
estamp(2, 1)

【问题讨论】:

    标签: mongodb sharding mongodb-shell


    【解决方案1】:

    我会假设您的分片集群设置正确并且您正确连接到它(虽然我不知道您为什么要连接到一个 mongod 而不是 mongos,也许您正在插入到 @987654325 @ 而不是mongos?)

    缺乏平衡的一个原因是您的x,_id 键是单调的,线性范围从最低到最高,因此写入将从范围的开头开始,依此类推。

    由于 MongoDB 分片是基于范围的,它实际上会将整个第一个范围放在第一个分片上,直到它认为适合实际平衡它:http://docs.mongodb.org/manual/tutorial/manage-sharded-cluster-balancer/ 这很可能不是这种情况。

    基本上解决这个问题的方法是选择你的分片键:http://docs.mongodb.org/manual/tutorial/choose-a-shard-key/ wisely

    【讨论】:

    • 谢谢。所以,当它达到某个点(某个定义的大小等)时,mongo 将开始平衡分片之间的数据,对吗?我连接到一个 mongod 实例只是为了查看文档的数量。我是通过 mongos 写的。
    • @tugberk 确实应该,尝试插入 200 万条记录
    • 会的。 'chunksize' 有限制吗?
    • @tugberk 嗯,你能添加一个 sh.status() 吗?这将告诉我们更多
    • 将 sh.status() 结果添加到我的问题中。
    【解决方案2】:

    我猜你在这里没有做错任何事。 MongoDB 的默认块大小为 64MB,这意味着您的所有数据都在一个块内,因此将位于一个分片中。

    您可以通过发出来修改块大小

    db.settings.save( { _id:"chunksize", value: <sizeInMB> } )
    

    这也是in the docs的解释。

    【讨论】:

    • 修改块大小从来都不是一个好主意,而是应该选择正确的分片键
    • @Sammaye 我不会说从不,这肯定有用例。我并不是要建议更改块大小以用于生产或任何严重的事情,但我认为可以开始探索 MongoDB 并尝试这样做。
    • 确实,我猜它不是那样的 :)
    猜你喜欢
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 2016-09-13
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多