我收藏了 4 亿份文档。每个字段都有 6 个日期时间字段、1 个布尔字段、8 个双精度字段、9 个整数字段和 6 个字符串字段。我正在尝试建立以下索引:
db.MyCollection.ensureIndex(
{ "String1" : 1, "String2" : 1, "String3" : 1, "DateTime1" : 1, "Integer1" : 1, "DateTime2" : 1 },
{background: true}
);
运行了5天,只完成了一半。
该服务器运行 Windows Server Enterprise,拥有 4TB 磁盘空间和 256GB RAM。很少有其他进程针对数据库运行。没有分片或其他特殊配置。
有什么办法可以加快这个速度吗? (在不删除background = true
限定符,因为我不希望它完全将我排除在数据库之外,在这种情况下它就是这样做的。)
误解
Speed
即使不谈论多键索引,也会发生以下情况。正在进行大规模的表扫描。因此 mongoDB 迭代文档,尝试找到要索引的字段,评估该字段(以null
如果当前文档中不存在)并将其结果写入不少于 6 个文件,因为我们正在讨论 6 个索引。计算一下:200.000.000 / 86400 * 5 告诉我们 mongoDB 执行此操作的时间大约为每秒 460 个文档或者只需要每个文档 2.2 毫秒。我不会说那么慢。可能需要很长时间,但并不慢。
{background:true}
使用此参数可以not将您锁定在数据库之外。恰恰相反,文档中明确指出了这一点索引创建部分 http://docs.mongodb.org/manual/core/index-creation/#index-creation-background并在有关在后台创建索引的教程部分 http://docs.mongodb.org/manual/tutorial/build-indexes-in-the-background。不过,有一句话很容易被误解:
此外,在前台索引构建期间不能发生需要对所有数据库(例如 listDatabases)进行读或写锁定的操作。
这意味着您不能执行适用于所有数据库的操作and需要读或写锁。
改进方法(未来)
分片集群
使用具有副本集分片的共享集群。它易于设置,除了提高性能外,还具有多种优点。其中之一是添加分片(从而为集群添加空间和计算能力)的轻松可扩展性very简单的。备份对应用程序的影响较小。不再存在单点故障(如果做得正确,这甚至适用于整个数据中心规模的中断)。
使用不同的文件系统
抱歉,在 Windows Server 上运行依赖于磁盘 io 性能的应用程序对我来说根本没有意义。 ExtFS4 或 XFS 比 NTFS 或 ReFS 快 25% 到 40%,具体取决于优化情况。这使得real像您的用例一样依赖于磁盘 IO 的应用程序的差异。我们谈论的是几天的事情(甚至没有考虑 Linux 系统上操作系统更有效的内存映射和减少的内存消耗)。
{background:true}
虽然这并没有真正提高性能(实际上,出于明显的原因,在后台构建索引比在前台花费更长的时间),但您的应用程序在构建索引期间保持可用。因此,根据您的需求,这可能是一个可行的选择。
边注: 它是一个坏主意™,在使用 mongoDB 时垂直缩放,因为它被明确设计为水平缩放。这尤其适用于像您这样的大型集合,因为并行处理将极大地提高应用程序的性能。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)