5

在当前设置中,有两个 Mongo Docker 容器,在主机 A 和 B 上运行,Mongo 版本为 3.4,并在副本集中运行。我想将它们升级到 3.6 并增加一个成员,以便容器可以在主机 A、B 和 C 上运行。容器有 8GB 内存限制并且没有分配交换(当前),并且在Rancher中管理。所以我的计划是启动三个新容器,为它们初始化一个副本集,从 3.4 容器中进行转储,然后将其恢复为新的副本集 master。

转储顺利进行,其大小约为 16GB。当我尝试将其恢复到新的 3.6 主服务器时,恢复开始正常,但在恢复了大约 5GB 的数据后,mongo 进程似乎被 OS/Rancher 杀死,而容器本身没有重新启动,MongoDB 进程只是崩溃并重新加载自己再次备份。如果我再次将 mongorestore 运行到同一个数据库,它会为所有已插入的条目显示唯一键错误,然后从中断处继续,仅在 5GB 左右后再次执行相同操作。因此,似乎 mongorestore 会将它恢复到内存的所有条目加载到内存中。

所以我必须得到一些解决方案,并且:

  1. 每次它崩溃时,只需运行 mongorestore 命令,让它从中断的地方继续。它可能应该工作,但我觉得这样做有点不安。
  2. 一次恢复数据库一个集合,但最大的集合大于 5GB,因此它也无法正常工作。
  3. 将交换或物理内存(临时)添加到容器中,以便在进程用完物理内存后进程不会被杀死。
  4. 还有什么,希望有更好的解决方案?
4

6 回答 6

8

正如另一个答案指出的那样,增加交换大小对我有用。此外,该--numParallelCollections选项控制收集的数量mongodump/mongorestore应该并行转储/恢复。默认值为 4,这可能会消耗大量内存。

于 2018-10-15T00:03:14.750 回答
2

由于听起来您并没有因为 mongorestore 继续成功停止而导致磁盘空间不足,因此关注内存问题是正确的响应。在 mongorestore 过程中,您肯定会耗尽内存。

我强烈建议使用交换空间,因为这是最简单、最可靠、最不麻烦的方法,并且可以说是处理此问题的最官方支持的方法。

或者,如果您出于某种原因完全反对使用交换空间,您可以临时使用具有较大内存量的节点,在该节点上执行 mongorestore,允许其复制,然后关闭该节点并将其替换为分配给它的资源较少的节点。这个选项应该可以工作,但是对于更大的数据集可能会变得相当困难,并且对于这样的事情来说是相当大的。

于 2018-04-19T19:46:24.080 回答
2

--wiredTigerCacheSizeGB我通过使用mongod的参数解决了OOM问题。摘自我的docker-compose.yaml以下内容:

version: '3.6'
services:
    db:
        container_name: db
        image: mongo:3.2
        volumes:
            - ./vol/db/:/data/db
        restart: always
        # use 1.5GB for cache instead of the default (Total RAM - 1GB)/2:
        command: mongod --wiredTigerCacheSizeGB 1.5
于 2020-07-06T22:00:49.633 回答
2

只是在这里记录我在 2020 年使用 mongodb 4.4 的经验:

我在具有 4GB 内存的机器上恢复 5GB 集合时遇到了这个问题。我添加了似乎有效的 4GB 交换,我不再看到该KILLED消息。

但是,过了一会儿,我发现我丢失了很多数据!事实证明,如果 mongorestore 在最后一步(100%)内存不足,它不会显示被杀死,但它还没有导入您的数据

您要确保看到最后一行:

[########################]  cranlike.files.chunks  5.00GB/5.00GB  (100.0%)
[########################]  cranlike.files.chunks  5.00GB/5.00GB  (100.0%)
[########################]  cranlike.files.chunks  5.00GB/5.00GB  (100.0%)
[########################]  cranlike.files.chunks  5.00GB/5.00GB  (100.0%)
[########################]  cranlike.files.chunks  5.00GB/5.00GB  (100.0%)
restoring indexes for collection cranlike.files.chunks from metadata
finished restoring cranlike.files.chunks (23674 documents, 0 failures)
34632 document(s) restored successfully. 0 document(s) failed to restore.

就我而言,我需要 4GB 内存 + 8GB 交换空间来导入 5GB GridFS 集合。

于 2020-12-19T16:36:55.250 回答
1

无需启动新的副本集,甚至可以在不离线的情况下进行整个扩展和升级。

  1. 在主机 C 上启动 MongoDB 3.6
  2. 在主节点(当前为 A 或 B)上,将节点 C 添加到副本集中
  3. 节点 C 将进行数据的初始同步;这可能要花点时间
  4. 完成后,取下节点B;您的副本集仍然有两个工作节点(A 和 C),因此将继续不间断
  5. 将节点 B 上的 v3.4 替换为 v3.6 并重新启动备份
  6. 当节点B准备好时,取下节点A
  7. 将节点 A 上的 v3.4 替换为 v3.6 并重新启动备份

您将与以前一样运行相同的副本集,但现在三个节点都在运行 v.3.4。

PS 在开始之前,请务必查看有关将副本集升级到 3.6的文档。

于 2018-04-20T21:22:21.397 回答
1

作为测试副本集的一部分,我遇到了在单台机器上运行 3 个节点(总共 8GB RAM)的类似问题。默认存储缓存大小为 0.5 *(总RAM - 1GB)。mongorestore 导致每个节点在恢复时使用完整的缓存大小并消耗所有可用的 RAM。

我正在使用 ansible 对这部分进行模板化mongod.conf,但您可以将其设置cacheSizeGB为任何合理的数量,这样多个实例就不会消耗 RAM。

storage:
    wiredTiger:
        engineConfig:
            cacheSizeGB: {{ ansible_memtotal_mb /  1024 * 0.2 }}
于 2020-03-31T04:08:37.787 回答