![将大型 mongo 数据库的一部分复制到另一台服务器的最快/最佳方法是什么?](https://linux22.com/image/604404/%E5%B0%86%E5%A4%A7%E5%9E%8B%20mongo%20%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E4%B8%80%E9%83%A8%E5%88%86%E5%A4%8D%E5%88%B6%E5%88%B0%E5%8F%A6%E4%B8%80%E5%8F%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E6%9C%80%E5%BF%AB%2F%E6%9C%80%E4%BD%B3%E6%96%B9%E6%B3%95%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F.png)
我有一个包含 1 亿条推文的数据集,存储在 MongoDB 中,未优化且未编入索引。
我需要将上个月的所有推文复制到另一台服务器上,最好的方法是什么?
我的想法是使用 Ruby 脚本提取相关推文并将其复制到服务器上的新数据库,然后运行 mongo copyDatabase 命令将其复制过来。但这需要很长时间,还有其他方法吗?
require 'mongo_mapper'
MongoMapper.database = 'twitter'
require './models'
tweets = TwitterTweet.where(:created_at => {"$gt" => 1.month.ago}).all; # about 15 million
MongoMapper.database = 'monthly'
# copy the tweets over to the new db
tweets.each do |tweet|
tweet.save!
end;
答案1
首先,您提到它未编入索引/未优化 - 至少有一个索引吗created_at
?如果没有,那么您正在执行一个效率极低的查询(表扫描),而且速度不会很快。
一般来说,最简单的方法可能是让现有服务器成为主服务器,然后创建辅助服务器(请参阅副本集基本概念)。在副本集中,当你添加新的辅助节点时,它会从主节点同步,克隆所有现有数据,然后通过操作日志一旦您对拥有所需的所有数据感到满意(并且假设您不想保留副本集),只需重新启动mongod
不带--replSet
参数的 s(通常在不同的端口上重新启动是个好主意),您将在新主机上获得完整的副本。
更手动的方法是关闭当前mongod
(或fsyncLock()
以保证没有变化),然后手动将数据库文件复制到新主机 - 它们将在您的主机中,dbpath
如下所示:
<databasename>.ns
<databasename>.0
<databasename>.1
<databasename>.2
etc.
它们包含了其他人需要的所有信息mongod
,所以一旦您将它们复制到新主机并且启动了 MongoDB 实例,您就应该能够简单地use <databasename>
开始工作。
在每种情况下,对于任何未使用/不需要的部分,只需在新主机上启动并运行后删除它们,然后运行维修如果您想回收磁盘空间。
最后,如果你确实只想获取部分记录,那么你可以mongodump使用查询过滤器的相关集合,然后使用mongorestore导入到新主机。不过,我认为这不会比您上面建议的 ruby 快很多,特别是如果您缺少该created_at
索引。