我的任务是将数据从 MongoDB 数据库移植到 MySQL 数据库。(移植有充分的理由——所以必须这样做)。
MongoDB 集合:
- 拥有大约 1.1 亿份文档
- 大小为 60 GB
- 具有重要属性的索引
- 正在运行不为任何生产流量提供服务的 Windows 2008 独立独立服务器
我们尝试过的设置:
- 具有 7.5 Gigs RAM / 8 Gigs 页面文件的大型 Amazon EC2 Win2008 服务器实例
- AC# 控制台应用程序,将 MongoDB 数据转换为本地 MySQL 数据库
我们一次从 MongoDB 的内存中提取 1K 个文档,进行必要的处理,然后将它们保存到 MySQL db,一次批量写入 500 个。
我们面临的问题是,每 250 万个文档,服务器就会阻塞,Mongo 响应非常缓慢 - 应用程序的数据获取操作超时(在处理 100 万个文档时,可用 RAM 已经结束)
我们通过杀死 mongod 进程并在每 250 万条记录崩溃时重新启动它来缓慢前进——但我敢打赌我们做错了什么。
问题:
我是否应该为此将 Mongo 服务器移动到基于 Linux 的大型实例并将 MySQL 移动到 Amazon RDS 并用 PHP 重写转换应用程序?会有帮助吗?
我们决定将它全部放在一个盒子上的原因是在不同的盒子上拥有不同的服务器的延迟问题 - 但我想如果盒子窒息,那是没有实际意义的。
我还可以尝试哪些其他事情/可以使用的技巧?
感谢您阅读到这里!
-- 更新 01 --
自从我重新启动我的应用程序并进行了以下更改以来,已经过去了大约 6 个小时:
- 一次将 Mongo 读取计数从 1,000 条增加到 10,000 条。.skip(10K).limit(10K)
- 从 MySQL 目标数据库中删除了所有索引。
- 将 Windows 页面大小从 4 Gigs 增加到 8 Gigs
我的内存消耗为 100%,但应用程序仍在运行。(上次它在 52 分钟内发出呱呱叫声)。Mongo 吃 6.8 Gigs 的 RAM,MySQL - 450 Megs 和转换器应用程序 - 400 Megs(大约值)。
到目前为止处理了 1100 万条记录 - 但速度已经从大约 500 条记录/秒下降到 370 条记录/秒。
接下来的步骤将是将 Mongo 和 MySQL 服务器隔离到单独的盒子中,并将它们都放在同一个 Amazon 可用区中,以最大限度地减少延迟。
-- 更新 02 --
我们对代码进行了一些更改以使用 Mongo 光标并让它自动递增,而不是自己执行 .skip().limt()。这大大加快了这个过程,我们每秒可以处理 1250 条记录,而之前的记录是 300 多条。但是,应用程序开始消耗过多的内存,并且会耗尽 RAM 并崩溃,并且需要在每 2M 记录后重新启动。
我们使用了这个代码片段:
var docs = db[collectionName].Find(query);
docs.SetBatchSize(numOfResultsToFetchAtATime);
foreach (var d in docs) {
// do processing
}
因此,它的作用是一次获取“numOfResultsToFetchAtATime”记录,然后在循环中自动进行并获取下一组记录。Mongo 使用 Cursor 来处理这个进程,因此它要快得多。
但是,我们仍然无法成功移植它。当这种情况发生时,我会用代码发布我的回复。
-- 更新 03:成功 --
我们最终使用了@scarpacci 的建议做一个 mongoexport。请记住,mongodb 必须位于 linux 机器上而不是 windows 机器上。
我们首先尝试在本地 MongoDB 上从 Windows 执行 mongoexport,无论我们尝试什么,对于一个大型集合(13Gigs+),它都会在不同的地方失败
最后,我在 Linux 机器上恢复了数据库,mongoexport 就像一个魅力一样工作。
没有 Json -> MySQL 转换器 - 所以我们必须做很多事情。稍作调整,我们就可以使用我们以前的应用程序并读取文件并直接写入 MySQL。它快速且相对没有错误。
我们在处理大文件时遇到了一些问题,但是将 13GB 文件分解为 500 Meg 长文件有助于解决这个问题,我们能够成功地将所有数据迁移到 MySQL。
非常感谢大家花时间帮助我们。希望这个解释对将来的人有所帮助。