mongodb的存儲引擎


mongodb版本為3.4

mongodb存儲引起的一些概述

存儲引擎是MongoDB的核心組件,負責管理數據如何存儲在硬盤和內存上。從MongoDB 3.2 版本開始,MongoDB 支持多數據存儲引擎,MongoDB支持的存儲引擎有:WiredTiger,MMAPv1和In-Memory。

從mongodb3.2開始默認的存儲引擎是WiredTiger,3.3版本之前的默認存儲引擎是MMAPv1,mongodb4.x版本不再支持MMAPv1存儲引擎。

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

WiredTiger存儲引擎

從mongodb3.2開始mongodb默認支持WiredTiger存儲引擎,對於3.2之前的版本可以使用參數指定存儲引擎。

storage:
   engine: wiredTiger
wireTiger:
[存儲引擎的參數設置]

WiredTiger是各種操作應用的理想選擇,因此是MongoDB的默認存儲引擎。它應該是所有新應用程序的起點,除了您需要內存或加密存儲引擎的特定功能的情況。

WiredTiger存儲引擎的主要優勢:

最大化可用緩存: WiredTiger最大限度地利用可用內存作為緩存來減少I / O瓶頸。使用了兩個緩存:WiredTiger緩存和文件系統緩存。WiredTiger緩存存儲未壓縮的數據並提供類似內存的性能。操作系統的文件系統緩存存儲壓縮數據。當在WiredTiger緩存中找不到數據時,WiredTiger將在文件系統緩存中查找數據。

 

在移動到WiredTiger緩存之前,在文件系統緩存中找到的數據首先經過解壓縮過程。

WiredTiger緩存在保存盡可能多的工作集時表現最佳。但是,為需要它的其他進程(如操作系統,包括文件系統緩存)保留內存也很重要。這也包括MongoDB本身,整體上消耗的內存比WiredTiger主動使用的內存多。

MongoDB默認為WiredTiger緩存大小約為RAM的60%離開文件系統緩存的最小量是可用內存的20%。任何較低的操作系統都可能受限於資源。

高吞吐量: WiredTiger使用“寫入時復制” - 當文檔更新時,WiredTiger將制作文檔的新副本並確定最新版本以返回給讀者。此方法允許多個客戶端同時修改集合中的不同文檔,從而實現更高的並發性和吞吐量。當應用程序使用具有多個內核的主機(越多越好)並且多個線程正在寫入不同的文檔時,實現最佳寫入性能。

減少存儲空間並改善磁盤IOP: WiredTiger使用壓縮算法來減少磁盤上存儲的數據量。不僅存儲減少了,而且隨着從磁盤讀取或寫入更少的位,IOP性能也會提高。某些類型的文件比其他文件壓縮得更好。文本文件是高度可壓縮的,而二進制數據可能不是可壓縮的,因為它可能已經被編碼和壓縮。使用壓縮時,WiredTiger會產生額外的CPU周期,但用戶可以配置壓縮方案以優化CPU開銷與壓縮比。Snappy是默認的壓縮引擎,在高壓縮率和低CPU開銷之間提供了良好的平衡。Zlib將實現更高的壓縮比,但會產生額外的CPU周期。

壓縮(索引和journals日志):索引可以在內存和磁盤上壓縮。WiredTiger利用前綴壓縮來壓縮索引,節省RAM使用以及釋放存儲IOP。默認情況下,使用Snappy壓縮壓縮journals日志。

多核可擴展性:隨着CPU制造商縮小到更小的平版印刷,功耗變得越來越成問題,處理器趨勢已轉向多核架構,以維持摩爾定律的節奏。WiredTiger在設計時考慮了現代的多核架構,並提供跨多核系統的可擴展性。危險指針,無鎖算法和快速鎖存等編程技術可最大限度地減少線程之間的爭用。線程可以執行操作而不會相互阻塞 - 從而減少線程爭用,更好的並發性和更高的吞吐量。

 WiredTiger允許用戶為其讀取指定隔離級別。讀取操作可以返回大部分副本集已接受或提交到磁盤的數據視圖。這樣可以保證應用程序只讀取在發生故障時仍然存在的數據,並且在將新的副本集成員提升為主要成員時不會回滾。

【以上關於wiredTiger存儲引擎的介紹來自官方文檔的一片博客:存儲引擎

下面關於mongodb的存儲引擎詳細介紹來自官方文檔:

文檔級並發

WiredTiger使用文檔級並發控制進行寫操作。因此,多個客戶端可以同時修改集合的不同文檔。

對於大多數讀寫操作,WiredTiger使用樂觀並發控制。WiredTiger僅在全局,數據庫和集合級別使用意圖鎖。當存儲引擎檢測到兩個操作之間的沖突時,會發生寫入沖突,導致MongoDB透明地重試該操作。

一些全局操作(通常是涉及多個數據庫的短期操作)仍然需要全局“實例范圍”鎖定。其他一些操作(例如刪除集合)仍需要獨占數據庫鎖。

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日志文件。

journal日志

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

壓縮

使用WiredTiger,MongoDB支持對所有集合和索引進行壓縮。壓縮可以以額外的CPU為代價最大限度地減少磁盤的使用。

默認情況下WiredTiger存儲引擎使用snappy方式壓縮所有集合,前綴壓縮方式壓縮索引。

對於集合的壓縮還可以使用zlib方式壓縮。

storage:
joural:
enabled: true #啟用journal日志,false為關閉
engine: wiredTiger #指定存儲引擎
wiredTiger:
cacheSizeGB: 8 #來指定mongodb使用內存的多少-8G
engineConfig: #存儲引擎的配置
journalCompressor: snappy #指定journal日志的壓縮方式
indexConfig: #索引配置
prefixCompression: true #前綴壓縮開啟
collectionConfig:
blockCompressor: snappy #指定集合的壓縮方式

內存使用

在上面提到過:【最大化可用緩存: WiredTiger最大限度地利用可用內存作為緩存來減少I / O瓶頸。使用了兩個緩存:WiredTiger緩存和文件系統緩存。WiredTiger緩存存儲未壓縮的數據並提供類似內存的性能。操作系統的文件系統緩存存儲壓縮數據。當在WiredTiger緩存中找不到數據時,WiredTiger將在文件系統緩存中查找數據。】

mongodb從3.4版本開始默認使用內存為下面兩個中的最大一個:

  • 50% of (RAM - 1 GB)
  • 256MB

默認情況下,WiredTiger對所有集合使用Snappy塊壓縮,對所有索引使用前綴壓縮。壓縮默認值可在全局級別配置,也可以在集合和索引創建時單獨指定壓縮級別。

wiredTiger內部緩存中的數據與磁盤格式使用不同的表示形式:

【官方文檔總結--站位】

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會重建集合的所有索引

把已經含有數據的mongdb的存儲引擎更改為WiredTiger

 當前mongdb實例存儲引擎為mmapv1,如下:

systemLog:
  destination: file
  logAppend: true
  path: /data/mongod/log/mongod.log

storage:
  engine: "mmapv1"
  dbPath: /data/db
  journal:
    enabled: true

processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongod.pid  # location of pidfile

# network interfaces
net:
  port: 27017
  bindIp: 
mmapv1的配置
#數據大小如下
> show dbs;
admin  0.078GB
local  0.078GB
mydb   0.453GB

開始更改mongdb實例的存儲引擎:

1.備份原來的數據庫文件:

[root@test2 data]# mkdir db_back          #創建備份目錄
[root@test2 bin]# ./mongodump -o /data/db_back/       #備份數據
2018-11-09T17:46:54.684+0800    writing admin.system.indexes to 
2018-11-09T17:46:54.685+0800    done dumping admin.system.indexes (2 documents)
2018-11-09T17:46:54.685+0800    writing admin.system.version to 
2018-11-09T17:46:54.686+0800    done dumping admin.system.version (1 document)
2018-11-09T17:46:54.686+0800    writing mydb.test to 
2018-11-09T17:46:57.676+0800    [###############.........]  mydb.test  636416/999999  (63.6%)
2018-11-09T17:46:58.632+0800    [########################]  mydb.test  999999/999999  (100.0%)
2018-11-09T17:46:58.632+0800    done dumping mydb.test (999999 documents)
[root@test2 bin]# 

2.停止mongodb實例

kill `netstat -lntp |grep mongod | awk '{print $NF}' | cut -d "/" -f1`

3.修改配置文件

storage:
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 4
      journalCompressor: none
    collectionConfig:
      blockCompressor: none
    indexConfig
      prefixCompression: false

4:把現在dbpath中的數據,改名備份起來!

[root@test2 data]# mv db db_mmapv1
[root@test2 data]# mkdir db             #然后再重新創建一個db目錄

5:啟動mongodb實例

[root@test2 bin]# ./mongod -f ../conf/mongod.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 14436
child process started successfully, parent exiting
[root@test2 bin]# 

6:導入之前導出的數據

[root@test2 bin]# ./mongorestore --dir=/data/db_back/                    #導入數據
2018-11-09T17:59:10.586+0800    preparing collections to restore from
2018-11-09T17:59:10.599+0800    reading metadata for mydb.test from /data/db_back/mydb/test.metadata.json
2018-11-09T17:59:10.646+0800    restoring mydb.test from /data/db_back/mydb/test.bson
2018-11-09T17:59:13.546+0800    [########................]  mydb.test  20.1MB/54.4MB  (37.0%)
2018-11-09T17:59:16.546+0800    [##################......]  mydb.test  42.7MB/54.4MB  (78.5%)
2018-11-09T17:59:18.354+0800    [########################]  mydb.test  54.4MB/54.4MB  (100.0%)
2018-11-09T17:59:18.354+0800    no indexes to restore
2018-11-09T17:59:18.354+0800    finished restoring mydb.test (999999 documents)
2018-11-09T17:59:18.354+0800    done
[root@test2 bin]# ./mongo                                                #查看數據
MongoDB shell version v3.4.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.2
Server has startup warnings: 
2018-11-09T17:57:26.586+0800 I STORAGE  [initandlisten] 
2018-11-09T17:57:26.586+0800 I STORAGE  [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2018-11-09T17:57:26.586+0800 I STORAGE  [initandlisten] **          See http://dochub.mongodb.org/core/prodnotes-filesystem
2018-11-09T17:57:26.688+0800 I CONTROL  [initandlisten] 
2018-11-09T17:57:26.688+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-11-09T17:57:26.688+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2018-11-09T17:57:26.688+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2018-11-09T17:57:26.688+0800 I CONTROL  [initandlisten] 
> show dbs
admin  0.000GB
local  0.000GB
mydb   0.077GB                               #數據占有空間明顯變小了

比較兩個存儲引擎,數據目錄文件的不同

[root@test2 db]# pwd
/data/db
[root@test2 db]# ls                               #當前正在使用的wiredTiger存儲引擎
collection-0-1470999101568290858.wt  diagnostic.data                 index-4-1470999101568290858.wt  _mdb_catalog.wt  storage.bson      WiredTiger.lock
collection-2-1470999101568290858.wt  index-1-1470999101568290858.wt  index-6-1470999101568290858.wt  mongod.lock      WiredTiger        WiredTiger.turtle
collection-5-1470999101568290858.wt  index-3-1470999101568290858.wt  journal                         sizeStorer.wt    WiredTigerLAS.wt  WiredTiger.wt
[root@test2 db]# ls ../db_mmapv1/                 #之前備份的mmapv1存儲引擎的目錄
admin.0  admin.ns  diagnostic.data  journal  local.0  local.ns  mongod.lock  mydb.0  mydb.1  mydb.2  mydb.ns  storage.bson  _tmp
[root@test2 db]#

 


免責聲明!

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



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