mongodb存儲引擎


存儲引擎(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>
復制代碼

 轉自:http://www.cnblogs.com/ljhdo/archive/2016/10/30/4947357.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM