将数据从Mongo转换为MySQL(110M docs,60Gigs) - 提示和建议?

sau*_*bhj 10 c# mysql mongodb windows-server-2008 mongodb-.net-driver

我的任务是将数据从MongoDB数据库移植到MySQL数据库.(有用于移植强有力的理由-因此它做).

MongoDB集合:

  • 有大约1.1亿份文件
  • 重量为60 GB
  • 具有重要属性的索引
  • 正在运行Windows 2008独立服务器,该服务器不提供任何生产流量

我们尝试过的安装程序:

  • 一个大型Amazon EC2 Win2008 Server实例,具有7.5 GB RAM/8 Gig页面文件
  • AC#console app将MongoDB数据转换为本地MySQL数据库

我们从MongoDB中一次在内存中获取1K文档,进行必要的处理,然后将它们保存到MySQL数据库,一次批量写入500.

我们面临的问题是每2.5 MB文档,服务器窒息而Mongo响应非常缓慢 - 超时应用程序的数据获取操作(在处理1M文档时释放RAM)

我们正在慢慢地通过杀死mongod进程并在崩溃时每2.5M记录再次启动它 - 但我敢打赌我们做错了什么.

题:

我应该将Mongo服务器移动到基于Linux的大型实例和MySQL移动到Amazon RDS并在PHP中重写转换应用程序吗?会有帮助吗?

我们决定将它们全部放在一个盒子上的原因是在不同的盒子上安装不同服务器的延迟问题 - 但我想如果盒子窒息那就没有实际意义.

我可以尝试哪些其他东西/我可以使用的提示?

感谢您阅读这篇文章!

- 更新01 -

自从我重新启动我的应用程序并进行了以下更改后大约需要6个小时:

  1. Mongo读取次数从1,000次增加到10,000次..skip(10K).limit(10K)
  2. 从MySQL目标数据库中删除了所有索引.
  3. Windows页面大小从4 Gigs增加到8 Gigs

我的记忆是100%消耗,但应用程序仍在运行.(上次它在52分钟内嘶哑).Mongo吃了6.8 GB的RAM,MySQL - 450 Megs和转换器应用程序 - 400 Megs(约值).

到目前为止处理了11M的记录 - 但速度从大约500条记录/秒下降到370记录/秒.

接下来的步骤是将Mongo和MySQL服务器隔离在一起,并将所有这些服务器保存在同一个Amazon可用区中,以最大限度地减少延迟.

- 更新02 -

我们对代码进行了一些更改以使用Mongo Cursor并让它自动自动增加,而不是自己执行.skip().limt().这大大加快了这个过程,我们从之前的300多个每秒做了1250条记录.但是,应用程序开始消耗太多内存,并且会耗尽RAM并崩溃,并且需要在每2M记录后重新启动.

我们使用了这段代码:

var docs = db[collectionName].Find(query);
docs.SetBatchSize(numOfResultsToFetchAtATime);
foreach (var d in docs) {
  // do processing
}
Run Code Online (Sandbox Code Playgroud)

所以它的作用是一次获取'numOfResultsToFetchAtATime'记录 - 但随后在循环中自动进行并获取下一组记录.Mongo使用Cursor处理这个进程,因此速度要快得多.

但是,我们仍然无法成功移植它.如果发生这种情况,我会用代码发布我的回复.

- 更新03:成功 -

我们终于使用了@ scarpacci关于做mongoexport的建议.请记住,mongodb必须在linux盒子而不是windows盒子上.

我们首先尝试在本地MongoDB上从Windows执行mongoexport,无论我们尝试什么,它都会在一个大型集合的不同位置失败(13Gigs +)

最后,我在Linux机器上恢复了数据库,而mongoexport就像魅力一样.

没有Json - > MySQL转换器 - 所以我们必须这么做.通过一些调整,我们能够使用我们以前的应用程序并读取文件并直接写入MySQL.它很快且相对没有错误.

我们在使用大文件时遇到了一些问题,但是将13GB文件分解为500兆字节的文件有助于解决这个问题,我们能够成功地将所有数据迁移到MySQL.

非常感谢大家花时间帮助我们.希望这个解释能够帮助将来的某个人.

sca*_*cci 1

您是否考虑过使用mongoexport然后执行某种批量插入到 MySQl 中?不确定这在 MySql 中是否可用,但我们一直在 SQL Server 中执行类似的操作。可能会使转储/插入更容易分解和优化?只是一个想法....