我正在构建一个使用mongoDB进行操作存储的ETL应用程序。 ETL过程从数据源执行频繁的增量转储,并且偶尔执行全表转储。
当我执行完全转储时,我想要替换整个mongoDB集合 - 索引和所有。
PHP tutorial建议使用此方法插入多个文档:
<?php
$connection = new MongoClient();
$collection = $connection->database->collectionName;
for ( $i = 0; $i < 100; $i++ )
{
$collection->insert( array( 'i' => $i, "field{$i}" => $i * 2 ) );
}
?>
如果我有数百万个文档,这会导致与mongoDB的数百万个连接 - 显然是一个很大的瓶颈,特别是在远程数据库上。更不用说我是否要等待来自DB的回调确认插入成功。
mongoDB中是否有一个方法,由PHP驱动程序支持,用大数组替换整个集合,从而执行对数据库的单个调用?我认为mongoDB也会更快,例如db.colleciton.drop()
与db.collection.remove()
。
如果那是不可能的,那么在运行PHP脚本的同一台服务器上安装主数据库并远程复制它会更有效吗?通过这种方式,我可以从本地数据库获得更快的响应,并且只能从复制中获得一些延迟,但我想这会使PHP脚本更早可用。
有什么建议吗?
谢谢,
克
答案 0 :(得分:4)
如果我有数百万个文档,这会导致与mongoDB的数百万个连接
不,只有一个连接。每次迭代后它都不会关闭连接。
更不用说我是否要等待来自DB确认插入成功的回调。
确实没有简单的方法。如果你想知道实际插入的东西,你必须......好吧,知道。
我认为mongoDB也会更快,例如db.colleciton.drop()与db.collection.remove()。
由于MongoDB的内部及其释放记录对象的方式(一个很好的演示:http://www.10gen.com/presentations/storage-engine-internals)drop()
在这种情况下性能更高,因为它直接“删除”了集合。不仅如此,所有记录对象都将不复存在,并且该集合将作为一个空闲范围存在,等待再次使用。
用大数组替换整个集合,从而对数据库执行一次调用吗?
您可以在删除集合后始终使用batchInsert
(http://php.net/manual/en/mongocollection.batchinsert.php)。但是,如果事情失败,你将会遇到尴尬,你将需要后退场景。您可以逐个进行插入操作,通过单次调用可以判断是否应该继续进行或是否需要进行干预。
这里有一些关于索引的注释,删除索引并在插入数据后重建它们。它的速度要快得多。
如果那是不可能的话,在运行PHP脚本的同一台服务器上安装主数据库并远程复制它会更有效吗?
这取决于。通常在工作集上,您是否可以在应用服务器上实际运行MongoDB。另一个考虑因素是单点故障,您的辅助设备将被远距离,您将依靠应用服务器上的单个mongod
来为您提供此优势;所以,如果有故障转移,你就不会保持这种优势。
理论上没有什么可以阻止你这样做并在RP_PRIMARY
中使用w
和MongoClient
1并在本地托管的mongod
有备用后的某个时间复制辅助副本时间在手上。