MongoDB 存儲引擎:WiredTiger和In-Memory

来源:http://www.cnblogs.com/ljhdo/archive/2016/10/30/4947357.html
-Advertisement-
Play Games

存儲引擎(Storage Engine)是MongoDB的核心組件,負責管理數據如何存儲在硬碟(Disk)和記憶體(Memory)上。從MongoDB 3.2 版本開始,MongoDB 支持多數據存儲引擎(Storage Engine),MongoDB支持的存儲引擎有:WiredTiger,MMAPv ...


存儲引擎(Storage Engine)是MongoDB的核心組件,負責管理數據如何存儲在硬碟(Disk)和記憶體(Memory)上。從MongoDB 3.2 版本開始,MongoDB 支持多數據存儲引擎(Storage Engine),MongoDB支持的存儲引擎有:WiredTiger,MMAPv1和In-Memory。

從MongoDB 3.2 版本開始,WiredTiger成為MongDB預設的Storage Engine,用於將數據持久化存儲到硬碟文件中,WiredTiger提供文檔級別(Document-Level)的併發控制,檢查點(CheckPoint),數據壓縮和本地數據加密( Native Encryption)等功能。

MongoDB不僅能將數據持久化存儲到硬碟文件中,而且還能將數據只保存到記憶體中;In-Memory存儲引擎用於將數據只存儲在記憶體中,只將少量的元數據和診斷日誌(Diagnostic)存儲到硬碟文件中,由於不需要Disk的IO操作,就能獲取索取的數據,In-Memory存儲引擎大幅度降低了數據查詢的延遲(Latency)。

一,指定MongoDB實例的存儲引擎

mongod 參數: --storageEngine  wiredTiger | inMemory

指定Storage Engine的類型,

  • 如果參數值是wiredTiger,MongoDB使用的存儲引擎是WiredTiger,將數據持久化存儲在Disk Files中;
  • 如果參數值是inMemory,MongoDB使用的存儲引擎是In-Memory,將數據存儲在記憶體中;
  • 從MongoDB 3.2 版本開始,MongoDB預設的存儲引擎是WiredTiger;

二,WiredTiger 存儲引擎將數據存儲到硬碟文件(Disk Files)

WiredTiger和MMAPv1都用於持久化存儲數據,相對而言,WiredTiger比MMAPv1更新,功能更強大。

1,文檔級別的併發控制(Document-Level Concurrency Control)

MongoDB在執行寫操作時,WiredTiger 在文檔級別進行併發控制,就是說,在同一時間,多個寫操作能夠修改同一個集合中的不同文檔;當多個寫操作修改同一個文檔時,必須以序列化方式執行;這意味著,如果該文檔正在被修改,其他寫操作必須等待,直到在該文檔上的寫操作完成之後,其他寫操作相互競爭,獲勝的寫操作在該文檔上執行修改操作。

對於大多數讀寫操作,WiredTiger使用樂觀併發控制(optimistic concurrency control),只在Global,database和Collection級別上使用意向鎖(Intent Lock),如果WiredTiger檢測到兩個操作發生衝突時,導致MongoDB將其中一個操作重新執行,這個過程是系統自動完成的。

For most read and write operations, WiredTiger uses optimistic concurrency control. WiredTiger uses only intent locks at the global, database and collection levels. When the storage engine detects conflicts between two operations, one will incur a write conflict causing MongoDB to transparently retry that operation.

2,檢查點(Checkpoint)

在Checkpoint操作開始時,WiredTiger提供指定時間點(point-in-time)的資料庫快照(Snapshot),該Snapshot呈現的是記憶體中數據的一致性視圖。當向Disk寫入數據時,WiredTiger將Snapshot中的所有數據以一致性方式寫入到數據文件(Disk Files)中。一旦Checkpoint創建成功,WiredTiger保證數據文件和記憶體數據是一致性的,因此,Checkpoint擔當的是還原點(Recovery Point),Checkpoint操作能夠縮短MongoDB從Journal日誌文件還原數據的時間。

當WiredTiger創建Checkpoint時,MongoDB將數據刷新到數據文件(Disk Files)中,在預設情況下,WiredTiger創建Checkpoint的時間間隔是60s,或產生2GB的Journal文件。在WiredTiger創建新的Checkpoint期間,上一個Checkpoint仍然是有效的,這意味著,即使MongoDB在創建新的Checkpoint期間遭遇到錯誤而異常終止運行,只要重啟,MongoDB就能從上一個有效的Checkpoint開始還原數據。

當MongoDB以原子方式更新WiredTiger的元數據表,使其引用新的Checkpoint時,表明新的Checkpoint創建成功,MongoDB將老的Checkpoint占用的Disk空間釋放。使用WiredTiger 存儲引擎,如果沒有記錄數據更新的日誌,MongoDB只能還原到上一個Checkpoint;如果要還原在上一個Checkpoint之後執行的修改操作,必須使用Jounal日誌文件。

3,預先記錄日誌(Write-ahead Transaction Log)

WiredTiger使用預寫日誌的機制,在數據更新時,先將數據更新寫入到日誌文件,然後在創建Checkpoint操作開始時,將日誌文件中記錄的操作,刷新到數據文件,就是說,通過預寫日誌和Checkpoint,將數據更新持久化到數據文件中,實現數據的一致性。WiredTiger 日誌文件會持久化記錄從上一次Checkpoint操作之後發生的所有數據更新,在MongoDB系統崩潰時,通過日誌文件能夠還原從上次Checkpoint操作之後發生的數據更新。

The WiredTiger journal persists all data modifications between checkpoints. If MongoDB exits between checkpoints, it uses the journal to replay all data modified since the last checkpoint.

3,記憶體使用

3.1 WiredTiger 利用系統記憶體資源緩存兩部分數據:

  • 內部緩存(Internal Cache)
  • 文件系統緩存(Filesystem Cache)

從MongoDB 3.2 版本開始,WiredTiger內部緩存的使用量,預設值是:1GB 或 60% of RAM - 1GB,取兩值中的較大值;文件系統緩存的使用量不固定,MongoDB自動使用系統空閑的記憶體,這些記憶體不被WiredTiger緩存和其他進程使用,數據在文件系統緩存中是壓縮存儲的。

3.2 調整WiredTiger內部緩存的大小

使用 mongod的參數 --wiredTigerCacheSizeGB 來修改MongoDB實例中WiredTiger內部緩存的大小,計算內部緩存大小的公式是:

  • Starting in MongoDB 3.2, the WiredTiger internal cache, by default, will use the larger of either: 60% of RAM minus 1 GB, or 1 GB.
  • For systems with up to 10 GB of RAM, the new default setting is less than or equal to the 3.0 default setting 
  • For systems with more than 10 GB of RAM, the new default setting is greater than the 3.0 setting.

4,數據壓縮(Data Compression)

WiredTiger壓縮存儲集合(Collection)和索引(Index),壓縮減少Disk空間消耗,但是消耗額外的CPU執行數據壓縮和解壓縮的操作。

預設情況下,WiredTiger使用塊壓縮(Block Compression)演算法來壓縮Collections,使用首碼壓縮(Prefix Compression)演算法來壓縮Indexes,Journal日誌文件也是壓縮存儲的。對於大多數工作負載(Workload),預設的壓縮設置能夠均衡(Balance)數據存儲的效率和處理數據的需求,即壓縮和解壓的處理速度是非常高的。

5,Disk空間回收

當從MongoDB中刪除文檔(Documents)或集合(Collections)後,MongoDB不會將Disk空間釋放給OS,MongoDB在數據文件(Data Files)中維護Empty Records的列表。當重新插入數據後,MongoDB從Empty Records列表中分配存儲空間給新的Document,因此,不需要重新開闢空間。為了更新有效的重用Disk空間,必須重新整理數據碎片。

WiredTiger使用compact 命令,移除集合(Collection)中數據和索引的碎片,並將unused的空間釋放,調用語法:

db.runCommand ( { compact: '<collection>' } )

在執行compact命令時,MongoDB會對當前的database加鎖,阻塞其他操作。在compact命令執行完成之後,mongod會重建集合的所有索引。

On WiredTiger, compact will rewrite the collection and indexes to minimize disk space by releasing unused disk space to the operating system. This is useful if you have removed a large amount of data from the collection, and do not plan to replace it.

二,In-Memory 存儲引擎將數據存儲到記憶體(Memory)

In-Memory存儲引擎將數據存儲在記憶體中,除了少量的元數據和診斷(Diagnostic)日誌,In-Memory存儲引擎不會維護任何存儲在硬碟上的數據(On-Disk Data),避免Disk的IO操作,減少數據查詢的延遲。

1,指定In-Memory存儲引擎

mongod --storageEngine inMemory --dbpath <path>

在選擇In-Memory存儲引擎時,需要指定兩個參數:

  • 設置mongod參數: --storageEngine ,設置參數的值是 inMemory;
  • 設置mongod參數: --dbpath ,設置參數的值是數據存儲的目錄;
  • 使用Disk存儲元數據,診斷數據和臨時數據:雖然 In-Memory 存儲引擎不會向文件系統寫入數據,但是它需要使用 --dbpath 維護少量的元數據和診斷(Diagnostic )日誌,在創建Large Index時,使用Disk存儲臨時數據;Although the in-memory storage engine does not write data to the filesystem, it maintains in the --dbpath small metadata files and diagnostic data as well temporary files for building large indexes.

2,文檔級別的併發(document-level concurrency)

In-Memory存儲引擎在執行寫操作時,使用文件級別的併發控制,就是說,在同一時間,多個寫操作能夠同時修改同一個集合中的不同文檔;當多個寫操作修改同一個文檔時,必須以序列化方式執行;這意味著,如果該文檔正在被修改,其他寫操作必須等待。

3,記憶體使用

In-Mmeory 存儲引擎需要將Data,Index,Oplog等存儲到記憶體中,通過mongod參數: --inMemorySizeGB 設置占用的記憶體數量,預設值是:50% of RAM-1GB。指定In-Memory 存儲引擎使用的記憶體數據量,單位是GB:

mongod --storageEngine inMemory --dbpath <path> --inMemorySizeGB <newSize>

4,持久化(Durable)

由於In-Memory 存儲引擎不會持久化存儲數據,只將數據存儲在記憶體中,讀寫操作直接在記憶體中完成,不會將數據寫入到Disk文件中,因此,不需要單獨的日誌文件,不存在記錄日誌和等待數據持久化的問題,當MongoDB實例關機或系統異常終止時,所有存儲在記憶體中的數據都將會丟失。

5,記錄oplog

In-Memory 存儲引擎不會將數據更新寫入到Disk,但是會記錄oplog,該oplog是存儲在記憶體中的集合,MongoDB通過Replication將Primary成員的oplog推送給同一副本集的其他成員。如果一個MongoDB實例是Replica Set的Primary成員,該實例使用In-Memory存儲引擎,通過Replication將oplog推送到其他成員,在其他成員中重做oplog中記錄的操作,這樣,就能將在Primary成員中執行的數據修改持久化存儲。

You can deploy mongod instances that use in-memory storage engine as part of a replica set. For example, as part of a three-member replica set, you could have:

With this deployment model, only the mongod instances running with the in-memory storange engine can become the primary. Clients connect only to the in-memory storage engine mongod instances. Even if both mongod instances running in-memory storage engine crash and restart, they can sync from the member running WiredTiger. The hidden mongod instance running with WiredTiger persists the data to disk, including the user data, indexes, and replication configuration information.

三,記錄日誌

數據是MongoDB的核心,MongoDB必須保證數據的安全,不能丟失,Journal 是順序寫入的日誌文件,用於記錄上一個Checkpoint之後發生的數據更新,能夠將資料庫從系統異常終止事件中還原到一個有效的狀態。MongoDB使用預寫日誌機制實現數據的持久化:WiredTiger 存儲引擎在執行寫操作時,先將數據更新寫入到Journal文件。Journal Files是存儲在硬碟的日誌文件,每個Journal File大約是100MB,存儲在--dbpath下的Journal子目錄中,在執行Checkpoint操作,將數據的更新同步到數據文件。

每隔一定的時間間隔,WiredTiger 存儲引擎都會執行Checkpoint操作,將緩存的數據更新日誌同步到硬碟上的數據文件中(On-Disk Files),在預設情況下,MongoDB啟用日誌記錄,也可以顯式啟用,只需要在啟動mongod 時使用--journal 參數:

mongod --journal

1,使用Journal日誌文件還原的過程

WiredTiger創建Checkpoint,能夠將MongoDB資料庫還原到上一個CheckPoint創建時的一致性狀態,如果MongoDB在上一個Checkpoint之後異常終止,必須使用Journal日誌文件,重做從上一個Checkpoint之後發生的數據更新操作,將數據還原到Journal記錄的一致性狀態,使用Journal日誌還原的過程是:

  1. 獲取上一個Checkpoint創建的標識值:從數據文件(Data Files)中查找上一個Checkpoint發生的標識值(Identifier);
  2. 根據標識值匹配日誌記錄:從Journal Files 中搜索日誌記錄(Record),查找匹配上一個Checkpoint的標識值的日誌記錄;
  3. 重做日誌記錄:重做從上一個Checkpoint之後,記錄在Journal Files中的所有日誌記錄;

2,緩存日誌

MongoDB配置WiredTiger使用記憶體緩衝區來存儲Journal Records,所有沒有達到128KB的Journal Records都會被緩存在緩衝區中,直到大小超過128KB。在執行寫操作時,WiredTiger將Journal Records存儲在緩衝區中,如果MongoDB異常關機,存儲在記憶體中的Journal Records將丟失,這意味著,WiredTiger將丟失最大128KB的數據更新。

WiredTiger syncs the buffered journal records to disk according to the following intervals or conditions:

  • New in version 3.2: Every 50 milliseconds.

  • MongoDB sets checkpoints to occur in WiredTiger on user data at an interval of 60 seconds or when 2 GB of journal data has been written, whichever occurs first.

  • If the write operation includes a write concern of j: true, WiredTiger forces a sync of the WiredTiger journal files.

  • Because MongoDB uses a journal file size limit of 100 MB, WiredTiger creates a new journal file approximately every 100 MB of data. When WiredTiger creates a new journal file, WiredTiger syncs the previous journal file.

3,日誌文件(Journal Files)

關於Journal文件,MongoDB在 --dbpath 目錄下創建 journal子目錄,WiredTiger將Journal 文件存儲在該目錄下,每一個Journal文件大約是100M,命名格式是:WiredTigerLog.<sequence>,sequence是一個左邊填充0的10位數字,從0000000001開始,依次遞增。

對於WiredTiger存儲引擎,Journal 文件具有以下特性:

  • 標識日誌記錄:Journal文件的每一個日誌記錄(Record)代表一個寫操作;每一個記錄都有一個ID,用於唯一標識該記錄;
  • 壓縮Journal文件:WiredTiger會壓縮存儲在Journal文件中的數據;
  • Journal文件大小的上限:每一個Journal文件大小的上限大約是100MB,一旦文件超過該限制,WiredTiger創建一個新的Journal文件;
  • 自動移除Journal文件:WiredTiger自動移除老的Journal文件,只維護從上一個Checkpoint還原時必需的Journal文件;
  • 預先分配Journal文件:WiredTiger預先分配Journal文件;

4,在異常宕機後恢複數據

在MongoDB實例異常宕機後,重啟mongod實例,MongoDB自動重做(redo)所有的Journal Files,在還原Journal Files期間,MongoDB資料庫是無法訪問的。

四,mongod 跟存儲引擎相關的參數

1,使用WiredTiger的參數設置

mongod 
--storageEngine wiredTiger 
--dbpath <path> 
--journal --wiredTigerCacheSizeGB <value>
--wiredTigerJournalCompressor <compressor>
--wiredTigerCollectionBlockCompressor <compressor>
--wiredTigerIndexPrefixCompression <boolean>

2,使用In-Memory的參數設置

mongod 
--storageEngine inMemory
--dbpath <path> 
--inMemorySizeGB <newSize>
--replSet <setname>
--oplogSize <value>

 

參考doc:

Storage Engines 

WiredTiger Storage Engine

Journaling

In-Memory Storage Engine

compact

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 學習本系列內容需要具備一定 HTML 開發基礎,沒有基礎的朋友可以先轉至 "HTML快速入門(一)" 學習 本人接觸 React Native 時間並不是特別長,所以對其中的內容和性質瞭解可能會有所偏差,在學習中如果有錯會及時修改內容,也歡迎萬能的朋友們批評指出,謝謝 文章第一版出自簡書,如果 ...
  • SwipeMenuListView(滑動菜單) A swipe menu for ListView.--一個非常好的滑動菜單開源項目。 Demo 一、簡介 看了挺長時間的自定義View和事件分發,想找一個項目練習下。。正好印證自己所學。 在github上找到了這個項目:SwipeMenuListVi ...
  • Oracle的推導參數(Derived Parameters)其實是初始化參數的一種。推導參數值通常來自於其它參數的運算,依賴其它參數計算得出。官方文檔關於推導參數(Derived Parameters)的概念如下: Derived Parameters Some initialization pa... ...
  • 1.在查詢結果中不顯示重覆記錄 查詢時不顯示重覆記錄主要應用了 DISTINCT 關鍵字,該關鍵字用於刪除重覆記錄。 在實現查詢操作時,如果查詢的選擇列表中包含一個表的主鍵,那麼每個查詢中的記錄都將是唯一的(因為主鍵在每一條記錄中有一個不同的值);如果主鍵不包含在查詢結果中,就可能出現重覆記錄。使用 ...
  • 【體繫結構】Oracle參數介紹 1 BLOG文檔結構圖 2 前言部分 2.1 導讀和註意事項 各位技術愛好者,看完本文後,你可以掌握如下的技能,也可以學到一些其它你所不知道的知識,~O(∩_∩)O~: ① Oracle中的各種參數介紹及其查詢方法 ② Oracle中V$PARAMETER及V$PA ...
  • 一、MySQL數據遷移(由遠端主機遷移到本地) 1、導出資料庫mysqldump -u root -p db > dump_db_date.sqlroot: 賬戶db: 需要導出的資料庫名 2、將導出的dump_db_date.sql文件scp到本地 3、在本地機器建立新資料庫mysql > cre ...
  • 今天在啟動Hadoop時遇到Name or service not knownstname這樣的錯誤 原因:slaves文件可能被污染了。 解決方法:刪除掉slaves文件,重新建立一個slaves文件,並配置好就可以了。 1 [root@master sbin]# ./start-all.sh 2 ...
  • 1.mysql 資料庫備份: 語法: 其中:USER 是用戶名,PASS 是密碼,DataBase 是資料庫名, Path 是資料庫備份存儲的位置。 備註:1)執行備份是在系統條件下,而非 mysql 狀態下。 2)請使用正確的文件地址,在文件地址中要使用雙斜杠 “\\” 來代替單斜杠 “\”。 2 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...