如何在分片 MongoDB 中激活分片平衡器

bro*_*nze 3 mongodb sharding

我有一个非常简单的 MongoDB 数据库结构。另外我有 5 个分片(其中 3 个是副本集)。但是我们正在测试数据库加载,目前似乎没有启用分片平衡。

mongos我检查了下一个:

mongos> sh.getBalancerState()
true
mongos> sh.isBalancerRunning()
false
Run Code Online (Sandbox Code Playgroud)

我无法将 BalancerRunning 设置为 true。我试过:

sh.startBalancer()
Run Code Online (Sandbox Code Playgroud)

请帮助我为我所有的分片启动它。谢谢你。

Ada*_*m C 5

基本上你在这里有一些误解,第一个是平衡器是负载平衡器。事实并非如此——它只是想解决分片上块计数的不平衡问题。当它移动块时,这可能会产生平衡流量的副作用,但严格来说,它不是负载平衡器。它也不会连续运行,而是在有工作要做和不平衡需要解决时运行,否则它处于休眠状态。

为了解释您从命令中获得的输出,让我们一次一个。首先,让我们看看是做什么的sh.getBalancerState()(在mongoshell 中运行任何没有括号的函数,你会看到它背后的代码):

mongos> sh.getBalancerState
function () {
    var x = db.getSisterDB( "config" ).settings.findOne({ _id: "balancer" } )
    if ( x == null )
        return true;
    return ! x.stopped;
}
Run Code Online (Sandbox Code Playgroud)

因此,该命令所做的是检查配置数据库中的设置集合以确定是否启用了平衡器。如果我们停止平衡器,我们会看到设置更改:

mongos> sh.stopBalancer()
Waiting for active hosts...
Waiting for the balancer lock...
Waiting again for active hosts after balancer is off...
mongos> sh.getBalancerState()
false
Run Code Online (Sandbox Code Playgroud)

如果我们将其翻转回启用状态,我们会再次看到 true 返回:

mongos> sh.startBalancer()
mongos> sh.getBalancerState()
true
Run Code Online (Sandbox Code Playgroud)

所以,sh.getBalancerState()基本上是为了检查设置并告诉您是否启用了平衡器。它没有说明平衡器当前是否正在积极运行(即检查不平衡,迁移以解决它发现的任何不平衡)。这就是sh.isBalancerRunning()进来的地方。

但是,如果平衡器当前没有做任何工作,它将不会“运行”,因此它将返回 false:

mongos> sh.isBalancerRunning()
false
Run Code Online (Sandbox Code Playgroud)

因此,让我们给它一些工作要做。我将重新使用这个答案中的示例,并在平衡器关闭时产生不平衡。这是我完成预拆分后sh.status()的输出sh.getBalancerState()

mongos> sh.getBalancerState()
false
mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "version" : 3,
    "minCompatibleVersion" : 3,
    "currentVersion" : 4,
    "clusterId" : ObjectId("53b5d3b5d95df3a66a597548")
}
  shards:
    {  "_id" : "shard0000",  "host" : "localhost:30000" }
    {  "_id" : "shard0001",  "host" : "localhost:30001" }
    {  "_id" : "shard0002",  "host" : "localhost:30002" }
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0001" }
    {  "_id" : "users",  "partitioned" : true,  "primary" : "shard0001" }
        users.userInfo
            shard key: { "_id" : 1 }
            chunks:
                shard0001   2049
            too many chunks to print, use verbose if you want to force print
Run Code Online (Sandbox Code Playgroud)

一旦我重新启用平衡器,将有大量工作要做,以在 3 个分片上均匀地重新分配那些 2049(空)块,因此我将有很多机会运行sh.isBalancerRunning()并获得积极的结果。有趣的是,我花了几次尝试才让它返回 true(为了简洁起见,只显示了两个):

mongos> sh.isBalancerRunning()
false
mongos> sh.isBalancerRunning()
true
Run Code Online (Sandbox Code Playgroud)

这是为什么?好吧,让我们再看看这个函数:

mongos> sh.isBalancerRunning
function () {
    var x = db.getSisterDB("config").locks.findOne({ _id: "balancer" });
    if (x == null) {
        print("config.locks collection empty or missing. be sure you are connected to a mongos");
        return false;
    }
    return x.state > 0;
}
Run Code Online (Sandbox Code Playgroud)

这又是对配置数据库的查询,这次是在锁集合上。它查找属于平衡器的锁,如果状态大于 0,则返回 true。以下是文档的两个示例,一个返回 false,一个返回 true:

db.getSisterDB("config").locks.findOne({ _id: "balancer" });
{
    "_id" : "balancer",
    "process" : "adamc-mbp:30999:1404425140:16807",
    "state" : 2,
    "ts" : ObjectId("53b5d86fd95df3a66a5975ff"),
    "when" : ISODate("2014-07-03T22:25:51.574Z"),
    "who" : "adamc-mbp:30999:1404425140:16807:Balancer:1622650073",
    "why" : "doing balance round"
}
db.getSisterDB("config").locks.findOne({ _id: "balancer" });
{
    "_id" : "balancer",
    "process" : "adamc-mbp:30999:1404425140:16807",
    "state" : 0,
    "ts" : ObjectId("53b5d86ed95df3a66a5975fe"),
    "when" : ISODate("2014-07-03T22:25:50.528Z"),
    "who" : "adamc-mbp:30999:1404425140:16807:Balancer:1622650073",
    "why" : "doing balance round"
}
Run Code Online (Sandbox Code Playgroud)

如果您仔细观察,您会注意到这些ts字段基本上是连续的,并且您将看到空块的非零状态非常短暂。如果我用数据填充块,则更容易产生积极的结果。

你有它 - 对你正在运行的命令的完整解释以及你为什么得到你所看到的结果。我怀疑问题的根源实际上与流量不平衡有关,但通常不是平衡器导致这种类型的问题(如前所述,它不是负载平衡器)-流量不平衡更有可能是由以下原因引起的:

  • 一个糟糕的分片键(可能非常糟糕)
  • 未为数据库/集合启用平衡(有关说明,请参阅先前的拆分前答案)
  • 有些东西阻止了平衡器工作(配置服务器关闭、平衡器窗口、迁移中止)