簡體   English   中英

Mongorestore 似乎內存不足並殺死了 mongo 進程

[英]Mongorestore seems to run out of memory and kills the mongo process

在當前設置中,有兩個 Mongo Docker 容器,在主機 A 和 B 上運行,Mongo 版本為 3.4,並在副本集中運行。 我想將它們升級到 3.6 並增加一個成員,以便容器可以在主機 A、B 和 C 上運行。容器有 8GB 內存限制並且沒有分配交換(當前),並且在Rancher 中進行管理。 所以我的計划是啟動三個新容器,為它們初始化一個副本集,從 3.4 容器中獲取一個轉儲,並將其恢復為新的副本集 master。

轉儲很順利,它的大小約為 16GB。 當我嘗試將其恢復到新的 3.6 master 時,恢復開始正常,但是在恢復了大約 5GB 的數據后,mongo 進程似乎被 OS/Rancher 殺死,而容器本身沒有重新啟動,MongoDB 進程只是崩潰並重新加載自己。 如果我再次將 mongorestore 運行到同一個數據庫,它會顯示所有已插入條目的唯一鍵錯誤,然后從中斷處繼續,僅在 5GB 左右后再次執行相同操作。 所以看起來 mongorestore 將它恢復的所有條目加載到內存中。

所以我必須為此找到一些解決方案,並且:

  1. 每次崩潰時,只需運行 mongorestore 命令,以便它從停止的地方繼續。 它可能應該有效,但我覺得這樣做有點不安。
  2. 一次還原一個集合,但最大的集合大於5GB,因此它也無法正常工作。
  3. 將交換或物理內存(臨時)添加到容器中,以便在進程用完物理內存后該進程不會被終止。
  4. 別的東西,希望有更好的解決方案?

正如另一個答案指出的那樣,增加交換大小對我有用。 此外, --numParallelCollections選項控制mongodump / mongorestore應該並行轉儲/恢復的集合數量。 默認值為 4,可能會消耗大量內存。

由於 mongorestore 在成功停止的地方繼續運行,聽起來您並沒有耗盡磁盤空間,因此專注於內存問題是正確的響應。 在 mongorestore 過程中,您肯定會耗盡內存。

我強烈建議使用交換空間,因為這是最簡單、最可靠、最簡單的方法,並且可以說是處理此問題的最受官方支持的方法。

或者,如果您出於某種原因完全反對使用交換空間,您可以暫時使用具有較大內存量的節點,在該節點上執行 mongorestore,允許其復制,然后關閉該節點並將其替換為分配給它的資源較少的節點。 這個選項應該有效,但對於更大的數據集可能會變得非常困難,並且對於這樣的事情來說是非常矯枉過正的。

僅在此處記錄我在 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 集合。

無需啟動新的副本集,甚至可以在不下線的情況下進行整個擴展和升級。

  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的文檔。

作為測試副本集的一部分,我遇到了在一台機器上運行 3 個節點(總共 8GB RAM)的類似問題。 默認存儲緩存大小為 .5 *(總 RAM - 1GB)。 mongorestore 導致每個節點在還原時使用完整緩存大小並消耗所有可用 RAM。

我正在使用 ansible 來模板化mongod.conf這一部分,但是您可以將cacheSizeGB設置為任何合理的數量,這樣多個實例就不會消耗 RAM。

storage:
    wiredTiger:
        engineConfig:
            cacheSizeGB: {{ ansible_memtotal_mb /  1024 * 0.2 }}

我通過使用 mongod 的--wiredTigerCacheSizeGB參數解決了 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM