我的应用程序只需要对其所有数据库的读访问权限。其中一个数据库(db_1
)托管了一个集合coll_1
,其整个内容*需要定期更换**。
我的目标是对当前连接到数据库的服务器的读取性能没有影响或影响很小。
到目前为止我能想到的方法:
构建临时集合coll_tmp
,然后使用renameCollection
与dropTarget: true
将其内容移至coll_1
。这种方法的缺点是,据我所知,renameCollection
不复制索引,因此一旦重命名集合,coll_1
将需要重建索引。虽然我对这需要多长时间没有很好的估计,但我认为在重建索引完成之前,查询性能会受到很大影响。
在选定的替换期后,使用time-to-live index使文档到期,而不是直接替换。每个时间段插入新数据。这对我来说似乎是一个不错的解决方案,除了对于我们的特定应用,旧数据优于没有数据。在这种情况下,如果重新填充数据库的cron作业因任何原因失败,我们可能会留下一个空coll_1
,这是不可取的。我认为这可能会产生微不足道的影响,但是这个解决方案还需要在插入每个文档时进行动态索引。
只需使用两个不同的数据库(或集合?),并通知已连接的客户端哪个更新。此解决方案允许在使新coll_1_alt
(然后再coll_1
)可用之前完成索引。我个人不喜欢这个解决方案,因为它将读取的客户端与数据库本身紧密耦合,当然通信渠道也总是不完善。
使用copyDatabase将备用数据库db_tmp
重命名(指定)为db_1
。db_tmp
还有一个集合coll_1
。在db_tmp.coll_1
完成重建索引后,copyDatabase
可用于简单地将db_tmp
重命名为db_1
。看来这需要在重命名之前删除db_1
,留下一个无法访问数据的窗口。
理想情况(天真地),我只是将db_1
设置为类似symlink
的东西,根据需要切换到最新的数据库。
任何人都对如何达到预期的效果有很好的建议吗?
* coll_1
中有大约1000万份文件。
**目前的计划是每24小时更换一次。更换间隔可能会低至每30分钟一次,但不会低于。
答案 0 :(得分:1)
您在选项4中指出的问题是,您还可以使用选项1. dropTarget也意味着该集合不可用。
另一种选择可能是在同一个集合中同时拥有旧数据和新数据,并使用“版本ID”,然后您仍然必须与客户进行通信以进行查询。这至少可以阻止你像你指出的选项1一样重新编制索引。
我认为你最好的选择实际上是选项3,它最相当于更改符号链接,除了它在客户端。