Sql-Server-2008

MongoDB 主從複製 - Windows 或 Linux

  • August 3, 2014

我最近將我的 MS SQL Server 數據庫移至 Windows Server 2008 上的 MongoDB (2.0)。它包含 2 個具有以下統計資訊的數據庫。(兩個數據庫每秒大約有 100 次讀取/寫入)。這些寫入由執行在同一數據庫伺服器上的 .Net 應用程序執行。

> db.stats()
{
       "db" : "FirstDB",
       "collections" : 112,
       "objects" : 94020788,
       "avgObjSize" : 62.86065307174409,
       "dataSize" : 5910208136,
       "storageSize" : 14340792320,
       "numExtents" : 1277,
       "indexes" : 110,
       "indexSize" : 4279800784,
       "fileSize" : 27837595648,
       "nsSizeMB" : 16,
       "ok" : 1
}

> db.stats()
{
       "db" : "SecondDB",
       "collections" : 10,
       "objects" : 2926198,
       "avgObjSize" : 158.5025346883567,
       "dataSize" : 463809800,
       "storageSize" : 720027648,
       "numExtents" : 49,
       "indexes" : 8,
       "indexSize" : 115248896,
       "fileSize" : 2080374784,
       "nsSizeMB" : 16,
       "ok" : 1
}

我發現 MongoDB 可以以所需的讀/寫速度保存我的所有數據。現在我需要專家幫助來加強我的單伺服器(數據庫+應用程序)設置的可靠性;

但是,在 1 個月的時間裡,我遇到了以下 MongoDB-On-Windows 問題;

  • 由於收集損壞而導致意外關閉
  • MongoDB 沒有為已刪除的對象釋放磁碟空間(目前大約 28 GB 並且還在增長)
  • 頁面錯誤數量增加
  • 無法控制 RAM 中的數據(無法在 RAM 中預載入所需數據並在幾分鐘後刪除)
  • 常見的數據庫錯誤,例如:無法從傳輸連接中讀取數據…

對我來說,可靠性/備份/性能的最佳救援設置是什麼?

  1. 將 MongoDB 遷移到 Linux(前提是我使用此數據庫的 .Net 應用程序將駐留在同一 LAN 內的 Windows Server 上)?要麼
  2. 使用 Windows 上的 Master 和 Linux 上的 Slave 設置 2 台伺服器副本集?要麼
  3. 你建議什麼…?

編輯-1:

> db.serverStatus()
{
       "host" : "OWNEROR-GTPD0H9",
       "version" : "2.2.2",
       "process" : "mongod",
       "pid" : 5972,
       "uptime" : 2246315,
       "uptimeMillis" : NumberLong("2246314871"),
       "uptimeEstimate" : 1418073,
       "localTime" : ISODate("2013-02-01T18:20:48.371Z"),
       "locks" : {
               "." : {
                       "timeLockedMicros" : {
                               "R" : NumberLong(1009609910),
                               "W" : NumberLong("41166641284")
                       },
                       "timeAcquiringMicros" : {
                               "R" : NumberLong("233444382285"),
                               "W" : NumberLong("26675293061")
                       }
               },
               "admin" : {
                       "timeLockedMicros" : {
                               "r" : NumberLong("20598738435"),
                               "w" : NumberLong(0)
                       },
                       "timeAcquiringMicros" : {
                               "r" : NumberLong("681905051780"),
                               "w" : NumberLong(0)
                       }
               },
               "local" : {
                       "timeLockedMicros" : {
                               "r" : NumberLong(7054206),
                               "w" : NumberLong(0)
                       },
                       "timeAcquiringMicros" : {
                               "r" : NumberLong(323140436),
                               "w" : NumberLong(0)
                       }
               },
               "FirstDB" : {
                       "timeLockedMicros" : {
                               "r" : NumberLong("40372661580"),
                               "w" : NumberLong("54059509747")
                       },
                       "timeAcquiringMicros" : {
                               "r" : NumberLong("769458843030"),
                               "w" : NumberLong("357708107433")
                       }
               },
               "SecondDB" : {
                       "timeLockedMicros" : {
                               "r" : NumberLong("25053503869"),
                               "w" : NumberLong("395081595504")
                       },
                       "timeAcquiringMicros" : {
                               "r" : NumberLong("69429086729"),
                               "w" : NumberLong("9163194312205")
                       }
               }
       },
       "globalLock" : {
               "totalTime" : NumberLong("2246314871000"),
               "lockTime" : NumberLong("41166641284"),
               "currentQueue" : {
                       "total" : 54,
                       "readers" : 52,
                       "writers" : 2
               },
               "activeClients" : {
                       "total" : 2,
                       "readers" : 0,
                       "writers" : 2
               }
       },
       "mem" : {
               "bits" : 64,
               "resident" : 69,
               "virtual" : 34059,
               "supported" : true,
               "mapped" : 16793,
               "mappedWithJournal" : 33586
       },
       "connections" : {
               "current" : 114,
               "available" : 19886
       },
       "extra_info" : {
               "note" : "fields vary by platform",
               "page_faults" : 631285910,
               "usagePageFileMB" : 6848,
               "totalPageFileMB" : 49132,
               "availPageFileMB" : 34274,
               "ramMB" : 24567
       },
       "indexCounters" : {
               "note" : "not supported on this platform"
       },
       "backgroundFlushing" : {
               "flushes" : 37430,
               "total_ms" : 86130745,
               "average_ms" : 2301.115281859471,
               "last_ms" : 3853,
               "last_finished" : ISODate("2013-02-01T18:19:49.233Z")
       },
       "cursors" : {
               "totalOpen" : 227,
               "clientCursors_size" : 227,
               "timedOut" : 125,
               "totalNoTimeout" : 226
       },
       "network" : {
               "bytesIn" : 46807928165,
               "bytesOut" : 24400717839,
               "numRequests" : 462799358
       },
       "opcounters" : {
               "insert" : 92590009,
               "query" : 92755757,
               "update" : 183285338,
               "delete" : 7489,
               "getmore" : 1004,
               "command" : 94208472
       },
       "asserts" : {
               "regular" : 0,
               "warning" : 0,
               "msg" : 0,
               "user" : 97431,
               "rollovers" : 0
       },
       "writeBacksQueued" : false,
       "dur" : {
               "commits" : 17,
               "journaledMB" : 0.139264,
               "writeToDataFilesMB" : 0.033338,
               "compression" : 2.2571516556184057,
               "commitsInWriteLock" : 0,
               "earlyCommits" : 0,
               "timeMs" : {
                       "dt" : 3291,
                       "prepLogBuffer" : 0,
                       "writeToJournal" : 8,
                       "writeToDataFiles" : 1,
                       "remapPrivateView" : 38
               }
       },
       "recordStats" : {
               "accessesNotInMemory" : 3942359,
               "pageFaultExceptionsThrown" : 15956,
               "FirstDB" : {
                       "accessesNotInMemory" : 163718,
                       "pageFaultExceptionsThrown" : 6931
               },
               "SecondDB" : {
                       "accessesNotInMemory" : 3778641,
                       "pageFaultExceptionsThrown" : 9025
               },
               "admin" : {
                       "accessesNotInMemory" : 0,
                       "pageFaultExceptionsThrown" : 0
               },
               "local" : {
                       "accessesNotInMemory" : 0,
                       "pageFaultExceptionsThrown" : 0
               }
       },
       "ok" : 1
}

這是一個相當複雜的問題,但我將對每個問題進行簡要回答。您應該嘗試這些,然後問一個更具體的問題(例如,提供有關 RAM 可用性和使用率的詳細資訊,以及用於診斷頁面錯誤的工作數據集大小)。

由於收集損壞而導致意外關閉

您沒有列出完整版本,但請確保您至少使用 2.0 的更高版本,最好是 2.2(在撰寫本文時,2.2.3 處於候選發布狀態)。後來在 2.0 分支中有多個與 Windows 相關的修復,其中一些修復了使 Windows 建構不易受到硬崩潰(這可能導致損壞)的問題。

MongoDB 沒有為已刪除的對象釋放磁碟空間(目前大約 28 GB 並且還在增長)

這已在許多其他文章和討論中有所涉及 - 請在此處查看我的答案:

https://stackoverflow.com/questions/13390160/does-mongodb-reuse-deleted-space

頁面錯誤數量增加無法控制 RAM 中的數據(無法在 RAM 中預載入所需數據並在幾分鐘後刪除)

如上所述,頁面錯誤和數據適合 RAM 需要更多詳細資訊 - 你有多少數據,你的工作集大小是多少,你的索引是否適合記憶體等。在 mongodb-user Google group 上也有很多討論以及有關此問題的 Stack Overflow 以及如何在MMS中跟踪此問題- 在您送出新問題之前,建議您在此處搜尋一些常用方法。您還應該注意,由於作業系統報告“軟”頁面錯誤(已經在記憶體中但未被程序擁有/觸及)和“硬”頁面錯誤(實際上是從磁碟分頁),Windows 中的頁面錯誤報告可能很難解釋以幾乎相同的方式。

關於預載入的說明,您可以使用 2.2+ 中的touch 命令執行此操作,用於索引、數據或兩者(請參閱連結頁面以獲取選項)。

常見的數據庫錯誤,例如:無法從傳輸連接中讀取數據…

同樣,這將需要日誌、系統上的相對負載的概念等。肯定需要更多細節 - 您可能只是遇到超時或類似情況,因為您正在超載數據庫。如果在您解決其他問題後這些錯誤仍然存在,我會建議一個單獨的問題

將 MongoDB 移動到 Linux(前提是我使用此數據庫的 .Net 應用程序將駐留在同一 LAN 內的 Windows Server 上)?

與 Windows 相比,在 Linux 上使用 MongoDB 的人更多,因此該平台上的社區對其進行了更廣泛的測試和使用,但在 Windows 和大型安裝中使用量很大。移動作業系統不一定會解決或自動修復問題。如果您的數據在 Windows 上不適合 RAM,例如,它可能也不適合在 Linux 上,也不會改變 MongoDB 重用已刪除空間的方式。

使用 Windows 上的 Master 和 Linux 上的 Slave 設置 2 台伺服器副本集?要麼

無論作業系統如何,您都應該始終執行副本集(最少的主要、​​從屬、仲裁者)。一般來說,這只是一個好主意,但特別是如果您看到您描述的一些問題。雖然理論上您可以像您提到的那樣混合作業系統,但我建議您選擇其中一個並使用它。

亞當已經涵蓋了大部分要點。但是,有幾件事要補充。

在生產環境中使用 Windows

對於 tl;dr 候選人:執行 mongod 實例(Windows 上的配置伺服器除外)是一個非常糟糕的主意™。

這就是為什麼。

  • ReFS 和 NTFS 都至少比 ext4 或 XFS(推薦用於 Linux 生產環境的文件系統)慢 1/3。有關詳細資訊,請參閱關於 slideshare 的詳細比較
  • Windows 中的記憶體管理通常不適用於 MongoDB。Windows 盡可能多地使用它的頁面文件,從而使操作成為文件操作,而在 Linux 上它們將成為 RAM 操作。後者要快幾個數量級,最高可達 40,000 (40k) 倍。這很容易加起來。
  • 對數據庫來說絕對沒用的作業系統 GUI 會佔用 RAM。

由於配置伺服器通常不像數據承載節點那樣看到那麼多動作,它可以在 Windows 上執行。

數據預熱

touch命令很有用,將使預熱變得非常容易。但是,它不是很精細。從 mongo shell 中使用 an 進行典型查詢.hint({<yourIndicesHere>).explain()不僅會將選定的索引載入到 RAM 中,而且還會找到該查詢的最佳查詢計劃,該計劃將一直保存到對集合進行 1000 次寫入操作之後,然後再重新評估它。

執行具有混合作業系統的副本集

雖然這通常是可能的,但這是另一個非常糟糕的主意™。由於 mongod 在 Windows 上的性能下降,很可能遲早會遇到稱為複制滯後的問題,如果滯後超過 oplog 長度,基本上會迫使您重新同步滯後的成員,從而帶走非常想要的重新同步時的冗餘。如果重新同步花費的時間超過了 oplog 長度可以橋接的時間,那麼對於所有實際目的,該節點都已失效。有一些方法可以處理複製滯後(例如,通過相應地設置寫入關注點),但從長遠來看,在不同作業系統上執行副本集的成員是解決問題的好方法。總而言之,我贊同 Adam 的建議,即不要在複製環境中混合作業系統。

引用自:https://dba.stackexchange.com/questions/33640