我有 mongodb 分片集群,分片键是散列的。它有 2 个分片副本集。每个副本集有 2 台机器。
我通过添加另外 2 个分片副本集进行了一个实验,它开始重新平衡。
但是,过了一段时间我发现块迁移相当缓慢。移动 1.4GB 数据需要 1 小时。
这让我很担心,这意味着我必须等待 13 天才能完成 500GB 的块迁移!
我对这些东西很陌生,我对它是慢、快还是正常没有感觉。但是,这些数字仍然不能说服我。
实验的附加说明: - 使用 m3 中型 aws 机器 - 没有其他进程运行,只有块迁移 - 默认 mongodb 分片安装,无需进一步配置 - shardkey 使用对象 id (_id) 的散列 - 最大块大小 64MB
更新:2018 年 4 月
这个答案在提出问题时是正确的,但从那时起事情就发生了变化。由于 3.4 版本引入了并行性,我最初引用的票已关闭。有关更多信息,我将在这个更新的答案中介绍一些细节。我将按原样保留其余答案,因为它仍然是一般问题/约束的一个很好的参考,并且对旧版本的任何人都有效。
原始答案
如果您有兴趣,我会在M202 高级课程中完整解释块迁移会发生什么。一般而言,我们只是说迁移不是很快,即使对于空块也是如此,因为正在执行内务管理以确保迁移在活动系统中工作(即使只发生平衡,这些仍然会发生)。
此外,整个集群一次只发生一次迁移——没有并行性。因此,尽管您有两个“完整”节点和两个“空”节点,但在任何给定时间最多发生一次迁移(在具有最多块的分片和最少的分片之间)。因此,添加 2 个碎片在平衡速度方面没有任何好处,只会增加必须移动的块的数量。
对于迁移本身,块的大小可能约为 30MiB(取决于您填充数据的方式,但通常这将是默认最大块大小的平均值)。您可以运行
db.collection.getShardDistribution()
以获取其中的一些信息,并在此处查看我的答案以获取有关您的块的更多信息的方法。由于没有其他活动正在进行,因此要进行迁移,目标分片(新添加的分片之一)将需要从源分片(原始分片之一)读取约 30MiB 的数据并将配置服务器更新为完成后反映新的块位置。对于没有负载的正常系统来说,移动 30MiB 的数据应该不是太大的瓶颈。
如果速度很慢,可能有多种原因,但对于不忙的系统来说,最常见的原因是:
w:2
或w:majority
默认使用,并且需要最新的辅助节点来满足它。如果系统很忙,那么内存争用,锁争用通常也是这里的嫌疑人。
要获取有关迁移需要多长时间、是否失败等的更多信息,请查看以下条目
config.changelog
:正如您所看到的,并且正如我在进行培训/教育时通常告诉人们的那样,如果您知道您将需要 4 个分片,那么通常最好从 4 个分片开始,而不是逐步增加。如果你这样做了,那么你需要知道添加一个分片可能需要很长时间,并且最初是对资源的净负面而不是收益(有关更详细的讨论,请参阅我的分片陷阱系列的第二部分)。
最后,要跟踪/支持/评论功能请求以提高块迁移的并行性,请查看SERVER-4355