mongodb使用哪些存儲(chǔ)引擎

小晨
166
2021-07-19 12:51:56
欄目: 云計(jì)算

mongodb使用的存儲(chǔ)引擎有:1、WiredTiger存儲(chǔ)引擎是mongodb3.2的默認(rèn)存儲(chǔ)引擎;2、MMAPv1是mongodb基于內(nèi)存映射最初的存儲(chǔ)引擎;3、In-Memory是一種內(nèi)存存儲(chǔ)引擎,它是非持久性的,不會(huì)持久化數(shù)據(jù)。

mongodb使用哪些存儲(chǔ)引擎

一、mongodb存儲(chǔ)引擎種類

mongodb主要有3種存儲(chǔ)引擎,分別是:

(1) WiredTiger

(2) MMAPv1

(3) In-Memory

下面分別介紹這三種存儲(chǔ)引擎。

二、WiredTiger

MongoDB 3.0版本開始啟用,64位版本。

MongoDB 3.2 成為默認(rèn)存儲(chǔ)引擎

(1) 文檔級(jí)別的并發(fā)

WiredTiger 對(duì)寫操作執(zhí)行文檔級(jí)別的并發(fā)控制,也就是說,在同一時(shí)間,可以修改一個(gè)集合中的不同文檔。

針對(duì)大多數(shù)的讀寫操作,WiredTiger采取樂觀的并發(fā)控制機(jī)制。WiredTiger 在全局、數(shù)據(jù)庫和集合級(jí)別身上僅使用意向鎖。當(dāng)存儲(chǔ)引擎檢測(cè)到兩個(gè)操作產(chǎn)生沖突時(shí),其中一個(gè)操作會(huì)引發(fā)一個(gè)寫沖突,促使mongodb顯式的的重新執(zhí)行該操作。

一些全局的操作,典型的有涉及多個(gè)庫的短暫操作,需要實(shí)例鎖;

一些像刪除集合的操作,還需要排他鎖。

(2) 快照和檢查點(diǎn)

WiredTiger 使用多版本的并發(fā)控制(MVCC)。

一個(gè)操作開始時(shí),WiredTiger 會(huì)為事務(wù)提供一個(gè)實(shí)時(shí)的數(shù)據(jù)快照,快照呈現(xiàn)內(nèi)存中數(shù)據(jù)的一致性視圖。

將數(shù)據(jù)寫入磁盤時(shí),WiredTiger 以一致性的方式將快照中的所有數(shù)據(jù)寫入磁盤。檢查點(diǎn)確保數(shù)據(jù)文件中所有的數(shù)據(jù)是一致的,并且包含最后一個(gè)檢查點(diǎn)。檢查點(diǎn)可以作為回復(fù)數(shù)據(jù)的點(diǎn)。mongodb配置WiredTiger 來創(chuàng)建檢查點(diǎn)(即將快照數(shù)據(jù)寫入磁盤),創(chuàng)建的時(shí)機(jī)是:每60秒或者當(dāng)日志文件達(dá)到2G。

在寫一個(gè)新檢查點(diǎn)的過程中,上一個(gè)檢查點(diǎn)仍然是有效的,如果寫的過程中出現(xiàn)宕機(jī)或者其他異常,一旦重啟成功,mongodb會(huì)從上一個(gè)有效的檢查點(diǎn)恢復(fù)數(shù)據(jù)。

當(dāng)WiredTiger的元數(shù)據(jù)表關(guān)聯(lián)到新的檢查點(diǎn)時(shí),該新的檢查點(diǎn)才是可訪問和持久的,此時(shí),會(huì)釋放老檢查點(diǎn)的頁。

(3) 日志文件系統(tǒng)Journal

默認(rèn)提交時(shí)間間隔為100毫秒。

WiredTiger使用預(yù)寫事務(wù)日志與檢查點(diǎn)結(jié)合的方式來確保數(shù)據(jù)持久化。即開啟Journal功能,Journal會(huì)記錄在兩個(gè)檢查點(diǎn)之間的所有修改,當(dāng)mongodb突然退出并重啟之后,WiredTiger會(huì)根據(jù)Journal中的記錄恢復(fù)最后一個(gè)檢查點(diǎn)之后發(fā)生的數(shù)據(jù)修改。

Journal用snappy庫壓縮。用storage.wiredTiger.engineConfig.journalCompressor指定其他的壓縮算法或者不采用壓縮策略。WiredTiger 最小的日志記錄大小是128字節(jié),如果記錄為128字節(jié)或者更小,則不會(huì)壓縮該條記錄。

將storage.journal.enabled設(shè)置為False,則不會(huì)啟動(dòng)Journaling。

對(duì)單實(shí)例而言,如果禁用journal意味著我們會(huì)丟失mongodb異常終止后上一個(gè)有效檢查點(diǎn)之后的所有數(shù)據(jù)。對(duì)于復(fù)制集(主從的mongodb集群)中的一些成員來說,復(fù)制過程可能提供充分的持久性保證。

(4) 壓縮

使用WiredTiger存儲(chǔ)引擎,mongodb支持壓縮所有集合和索引。壓縮以使用額外的CPU為代價(jià)來降低存儲(chǔ)消耗。WiredTiger 對(duì)集合采用塊壓縮(使用snappy壓縮庫或者zlib),對(duì)索引采用前綴壓縮??梢酝ㄟ^配置來更改壓縮方式,換用其他壓縮算法或者不進(jìn)行壓縮。再建立一個(gè)集合或者一個(gè)索引的時(shí)候,可以為其制定壓縮方式。對(duì)于大多數(shù)的工作負(fù)載,默認(rèn)的壓縮設(shè)置會(huì)平衡存儲(chǔ)效率和處理需求。

(5) 內(nèi)存使用

使用WiredTiger存儲(chǔ)引擎,MongoDB 既會(huì)使用WiredTiger的內(nèi)部緩存,也會(huì)使用文件系統(tǒng)的緩存.

從MongoDB3.4開始,WiredTiger 內(nèi)部緩存會(huì)使用下面兩個(gè)數(shù)中的較大者:

a. RAM的50% 減去1 GB

b. 256MB

對(duì)于文件系統(tǒng)緩存,MongoDB會(huì)自動(dòng)使用除WiredTiger內(nèi)部緩存以及其他進(jìn)程占用內(nèi)存的所有空閑內(nèi)存。文件系統(tǒng)中的緩存會(huì)被壓縮。

想要調(diào)整WiredTiger的內(nèi)部緩存, 可以參考storage.wiredTiger.engineConfig.cacheSizeGB和wiredTigerCacheSizeGB.

避免增加WiredTiger內(nèi)部緩存的大小超過其默認(rèn)值。

三、MMAPv1

MMAPv1是MongoDB基于內(nèi)存映射的最初的存儲(chǔ)引擎,它在大量的讀寫和就地更新的任務(wù)上有很好的表現(xiàn)。從3.2版本開始,MMAPv1 不在是默認(rèn)的存儲(chǔ)引擎。

注意:big-endian架構(gòu)不支持MMAPv1存儲(chǔ)引擎,如果在大端機(jī)器上采用該存儲(chǔ)引擎,會(huì)報(bào)錯(cuò)。Endian表示數(shù)據(jù)在存儲(chǔ)器中的存放順序,采用大端方式 進(jìn)行數(shù)據(jù)存放符合人類的正常思維,而采用小端方式進(jìn)行數(shù)據(jù)存放利于計(jì)算機(jī)處理。大端指低地址存放最高有效字節(jié),小端是指低地址存放最低有效字節(jié)。

例如:我們要存儲(chǔ)一個(gè)16進(jìn)制的數(shù)0x31323334;

小端機(jī)器的存儲(chǔ)方式為:

低地址 –> 高地址

34 33 32 31

大端機(jī)器的存儲(chǔ)方式為:

低地址 –> 高地址

31 32 33 34

(1) Journal

為了確保所有的數(shù)據(jù)都被持久化到磁盤,MongoDB默認(rèn)將所有修改都保存到磁盤的日志文件中,MongoDB寫日志文件要比寫數(shù)據(jù)文件頻繁。

storage.syncPeriodSecs:設(shè)置數(shù)據(jù)文件存儲(chǔ)時(shí)間間隔,默認(rèn)60秒。不要在生產(chǎn)環(huán)境設(shè)置該參數(shù),在幾乎所有場景,你都應(yīng)該用該默認(rèn)的參數(shù),如果將該參數(shù)設(shè)置為0,MongoDB 將不會(huì)同步內(nèi)存映射文件到磁盤。

storage.journal.commitIntervalMs:默認(rèn)值為100毫秒或30毫秒,取值范圍是0~500毫秒,取值越低,數(shù)據(jù)持久性越高,但是會(huì)犧牲磁盤性能。

默認(rèn)日志存儲(chǔ)時(shí)間間隔為100毫秒。但是如果日志文件被存儲(chǔ)在于數(shù)據(jù)文件不同的區(qū)塊設(shè)備上,例如physical volume, RAID device, or LVM volume,默認(rèn)日志提交間隔會(huì)變?yōu)?0毫秒,此外, when a write operation with j:true is pending, 提交的時(shí)間間隔將要變成設(shè)置值的三分之一。

在許多情況下,MongoDB 和操作系統(tǒng)更新數(shù)據(jù)到磁盤要比設(shè)置的時(shí)間間隔頻繁的多,所以,以上的設(shè)置值只是理論上的最大值。

當(dāng)mongod實(shí)例異常退出時(shí),MongoDB 可以根據(jù)這些數(shù)據(jù)文件恢復(fù)數(shù)據(jù)庫。

(2) 記錄存儲(chǔ)特性

所有記錄都是連續(xù)的存儲(chǔ)在磁盤上,當(dāng)一條記錄被更新并且超出原來分配的記錄大小,則需要重新分配一個(gè)記錄,之后將文檔移動(dòng)到新記錄中,并且更新與文檔相關(guān)的所有索引。這顯然比原地更新記錄要花費(fèi)更多的時(shí)間,同時(shí)還會(huì)導(dǎo)致存儲(chǔ)碎片。

從3.0版本開始,分配策略有所改變。

(3) 記錄分配策略

從3.0版本開始,MongoDB使用Power of 2 Sized Allocations策略,將一個(gè)文檔存儲(chǔ)到一條記錄中,同時(shí)記錄中還有額外的空間,這些額外的空間允許更新操作帶來的文檔大小的增長,使得重新分配內(nèi)存的可能新降到最低。

不同的分配策略支持不同種類的操作:

the power of 2 allocations:對(duì)insert/update/delete操作更加有效; 采用該策略之后,所有記錄的大小均為2的n次冪字節(jié)。對(duì)于大于2MB的文檔,分配將要向上取整到2MB的倍數(shù)。該策略有以下兩個(gè)關(guān)鍵特性:

能重新使用釋放的記錄來減少碎片。

能減少文檔移動(dòng),但是不能完全消除重新分配的情況。

exact fit allocations(No Padding Allocation Strategy):對(duì)沒有更新和刪除操作的集合更理想。

對(duì)于那些沒有改變文檔大小操作或者只有插入操作的集合,我們可以將the power of 2 allocations設(shè)置為無效。在3.0版本以前,MongoDB 通過動(dòng)態(tài)計(jì)算填充大小來作為文檔大小的因素。

(4) 內(nèi)存使用

采用MMAPv1存儲(chǔ)引擎,MongoDB自動(dòng)使用機(jī)器所有空閑的內(nèi)存作為它的緩存,系統(tǒng)資源監(jiān)控顯示,MongoDB用了許多內(nèi)存,但是它的使用是動(dòng)態(tài)的,當(dāng)其他進(jìn)程需要使用內(nèi)存時(shí),MongoDB會(huì)放棄部分緩存所占用的內(nèi)存給其他進(jìn)程。

從技術(shù)上來說,操作系統(tǒng)的虛擬內(nèi)存子系統(tǒng)管理著MongoDB內(nèi)存,這意味著MongoDB會(huì)盡可能多的使用空閑內(nèi)存,當(dāng)需要的是有也會(huì)切換到磁盤,部署足夠的內(nèi)存來適應(yīng)工作數(shù)據(jù)集將會(huì)獲得做好的性能。

三、In-Memory(內(nèi)存存儲(chǔ)引擎)

(1) 并發(fā)性

內(nèi)存存儲(chǔ)引擎使用文檔級(jí)別的并發(fā)控制,可以在同一時(shí)刻對(duì)不同文檔進(jìn)行更新操作。

(2) 內(nèi)存使用

內(nèi)存存儲(chǔ)引擎要求它的所有數(shù)據(jù)必須符合在命令行參數(shù)(–inMemorySizeGB)或者在YAML配置文件中設(shè)置的內(nèi)存大小。

默認(rèn)情況下,內(nèi)存存儲(chǔ)引擎使用物理RAM的50%減去1 GB的內(nèi)存。

如果一個(gè)寫操作超出指定的內(nèi)存大小,mongodb將會(huì)報(bào)錯(cuò),錯(cuò)誤信息如下:

“WT_CACHE_FULL: operation would overflow cache”

(3) 持久化

內(nèi)存存儲(chǔ)引擎是非持久性的,不會(huì)持久化數(shù)據(jù)。非持久化的數(shù)據(jù)包括應(yīng)用程序數(shù)據(jù),系統(tǒng)數(shù)據(jù),例如用戶、權(quán)限、索引、副本設(shè)置配置、分片集群配置等。數(shù)據(jù)庫正?;蛘弋惓jP(guān)閉的情況下,數(shù)據(jù)均不可恢復(fù)。

在采用內(nèi)存存儲(chǔ)引擎,或者其他存儲(chǔ)引擎但是關(guān)閉了Journal功能是,必須將writeConcernMajorityJournalDefault參數(shù)設(shè)置為False。

(4) 部署結(jié)構(gòu)

除了作為單實(shí)例運(yùn)行,采用內(nèi)存存儲(chǔ)引擎的mongod實(shí)例也可以作為副本集或者分片集群的一部分。

作為副本集的一部分

例如,一個(gè)有三個(gè)成員的副本集,其結(jié)構(gòu)可以為:

兩個(gè)mongod實(shí)例運(yùn)行在In-Memory存儲(chǔ)引擎上

另外一個(gè)mongod實(shí)例運(yùn)行在WiredTiger存儲(chǔ)引擎上,并將該實(shí)例配置為隱藏成員。

在該配置結(jié)構(gòu)下,只有采用IN-memory的數(shù)據(jù)庫實(shí)例會(huì)被選舉為最主要者,客戶端只會(huì)連接到該實(shí)例上。即使兩個(gè)使用In-memory的數(shù)據(jù)庫實(shí)例均死機(jī)或者重啟,他們都會(huì)從運(yùn)行在WiredTiger的實(shí)例上同步數(shù)據(jù)。隱藏的數(shù)據(jù)庫實(shí)例會(huì)將用戶數(shù)據(jù)、索引和其他復(fù)制配置信息都持久化到磁盤上。

作為分片集群的一部分

例如,一個(gè)有三個(gè)成員的分片集群,其結(jié)構(gòu)可以為:

兩個(gè)mongod實(shí)例運(yùn)行在In-Memory存儲(chǔ)引擎上

另外一個(gè)mongod實(shí)例運(yùn)行在WiredTiger存儲(chǔ)引擎上,并將該實(shí)例配置為隱藏成員。

為分片加inmem標(biāo)簽。如果該分片的名字為”shardC”,則連接mongos ,然后運(yùn)行sh.addShardTag(“shardC”, “inmem”),對(duì)于其他的分片,分別添加一個(gè)persisted 標(biāo)簽,

sh.addShardTag(“shardA”, “persisted”)

sh.addShardTag(“shardB”, “persisted”)

對(duì)于每個(gè)應(yīng)該駐留在內(nèi)存中的分片集合,分配給整塊范圍的inmem標(biāo)簽。

sh.addTagRange(“test.analytics”, { shardKey: MinKey }, { shardKey: MaxKey }, “inmem”)

對(duì)于每個(gè)應(yīng)該駐留在持久化中的分片集合,分配給整塊范圍的persisted標(biāo)簽。:

sh.addTagRange(“salesdb.orders”, { shardKey: MinKey }, { shardKey: MaxKey }, “persisted”)

對(duì)于內(nèi)存中的分片,創(chuàng)建一個(gè)數(shù)據(jù)庫或者移動(dòng)一個(gè)數(shù)據(jù)庫。

0