How big is your MongoDB?

原文鏈接

How big is your MongoDB?

Update 11/10/14: The next blog post in this series is on managing disk space in MongoDB.

As your MongoDB grows in size, information from the db.stats() diagnostic command (or the database “Stats” tab in our management portal) becomes increasingly helpful for evaluating hardware requirements.

We frequently get questions about the dataSize, storageSize and fileSize metrics, so we want to help developers better understand how MongoDB storage works and what these particular metrics mean.

MongoDB storage structure basics

First, we’ll go over the basics of how MongoDB stores your data.

Data files

Every MongoDB instance consists of a namespace file,  journal files and data files. For our discussion, we’ll only be focusing on data files, since that is where all of the data and indexes for your database reside.

Data files store BSON documents, indexes, and MongoDB-generated metadata in structures called extents. Each data file is made up of multiple extents.

Extents

Extents are logical containers within data files used to store documents and indexes.

Photo of data files and extents

The above diagram illustrates the relationship between data files and extents. Note:

  • Data and indexes are each contained in their own sets of extents; no extent will ever contain content for more than one collection
  • Data and indexes are never contained within the same extent
  • The data and indexes for a collection will usually span multiple extents
  • When a new extent is needed, MongoDB will attempt to use available space within current data files. If space cannot be found MongoDB will create new data files.

Metrics from db.stats()

Now that we understand the basics of how MongoDB storage is organized, we can explore metrics commonly examined with db.stats(): dataSize, storageSize and fileSize.

dataSize

Picture of MongoDB dbStats dataSize

The dataSize metric is the sum of the sizes (in bytes) of all the documents and padding stored in the database.

While dataSize does decrease when you delete documents, dataSize does not decrease when documents shrink because the space used by the original document has already been allocated (to that particular document) and cannot be used by other documents.

Alternatively, if a user updates a document with more data, dataSize will remain the same as long as the new document fits within its originally padded pre-allocated space.

storageSize

Photo of MongoDB dbStats storageSize

The storageSize metric is equal to the size (in bytes) of all the data extents in the database. This number is larger than dataSize because it includes yet-unused space (in data extents) and space vacated by deleted or moved documents within extents.

The storageSize does not decrease as you remove or shrink documents.

fileSize

Photo of MongoDB dbStats fileSize

The fileSize metric is equal to the size (in bytes) of all the data extents, index extents and yet-unused space (in data files) in the database. This metric represents the storage footprint of your database on disk. fileSize is larger than storageSize because it includes index extents and yet-unused space in data files.

While fileSize does decrease when you delete a database, fileSize does not decrease as you remove collections, documents or indexes.


原文鏈接

數據庫文件類型

MongoDB的數據庫文件主要有3種:

  • journal 日誌文件
  • namespace 表名文件
  • data 數據及索引文件

日誌文件

跟一些傳統數據庫不同,MongoDB的日誌文件只是用來在系統出現宕機時候恢復尚未來得及同步到硬盤的內存數據。日誌文件會存放在一個分開的目錄下面。啓動時候MongoDB會自動預先創建3個每個爲1G的日誌文件(初始爲空)。除非你真的有持續海量數據併發寫入,一般來說3個G已經足夠。

命名文件 dbname.ns

這個文件用來存儲整個數據庫的集合以及索引的名字。這個文件不大,默認16M,可以存儲24000個集合或者索引名以及那些集合和索引在數據文件中得具體位置。通過這個文件MongoDB可以知道從哪裏去開始尋找或插入集合的數據或者索引數據。這個值可以通過參數調整至2G。

數據文件 dbname.0, dbname.1,… dbname.n

MongoDB的數據以及索引都存放在一個或者多個MongoDB數據文件裏。第一個數據文件會以“數據庫名.0”命名,如 my-db.0。這個文件默認大小是64M,在接近用完這個64M之前,MongoDB 會提前生成下一個數據文件如my-db.1。數據文件的大小會2倍遞增。第二個數據文件的大小爲128M,第三個爲256M。一直到了2G以後就會停止,一直按這個2G這個大小增加新的文件。

當然MongoDB還會生成一些臨時文件如 _tmp 和 mongod.lock等, 不過他們跟我們的討論都沒有太大相關性。

數據文件結構

Extent

在每一個數據文件內,MongoDB把所存儲的BSON文檔的數據和B樹索引組織到邏輯容器“Extent”裏面。如下圖所示(my-db.1和my-db.2 是數據庫的兩個數據文件):

  • 一個文件可以有多個Extent
  • 每一個Extent只會包含一個集合的數據或者索引
  • 同一個集合的數據或索引可以分佈在多個Extent內。這幾個Extent也可以分步於多個文件內
  • 同一個Extent不會又有數據又有索引

Record 記錄

在每個Extent裏面存放有多個”Record“, 每一個記錄裏包含一個記錄頭以及MongoDB的BSON文檔,以及一些額外的padding空間。Padding是MongoDB在插入記錄時額外分配一些未用空間,這樣將來文檔變大的時候不至於需要把文檔遷移到別處。 記錄頭以整個記錄的大小開始,包括該記錄自己的位置以及前一個記錄和後一個記錄的位置。可以想象成一個Double Linked List。

數據庫大小參數

在之前的基礎上,我們可以來理解一下db.stats()裏面關於空間大小參數的含義。

dataSize

dataSize是最接近真實數據大小的一個參數。你可以用來檢查你的數據有多少。這個大小包括了數據庫(或者集合)的每條記錄的總和。注意每條記錄除了BSON文檔外還有header及padding這些額外開銷。所以實際大小會比真正數據所佔空間會稍大。

當刪除文檔的時候,這個參數會相應變小因爲它是所有文檔數的大小總和。如果你的文檔沒有刪除,只是文檔內部的字段被刪除或縮小,則不會對dataSize 有影響。原因就是因爲文檔所在記錄還在,並且整條記錄所佔空間並無改動,只不過記錄內的未用空間變多了而已。

storageSize

這個參數等於數據庫或者某個集合所有用到的Data Extents的總和。注意這個數字會大於dataSize因爲Extent裏面會有一些刪除文檔之後留下來的碎片(deleted)。及時你的storageSize大出dataSize很多,這個也不一定就是很糟糕的情況。 如果有新插入的文檔小於或等於碎片的大小,MongoDB會重新利用這個碎片來存儲新的文檔。不過在這之前這些碎片將一直會被保留在那裏佔用空間。由於這個原因,你刪除文檔的時候這個參數不會變小。

碎片問題會因爲運行的時間變長而變得嚴重。你可以通過 compact 命令來進行碎片清理或者通過新架一臺從機複製所有數據,然後變成主節點的方式來解決這些碎片。

fileSize

這個參數只在數據庫上有效,指的是實際文件系統中用到的文件的大小。它包括所有的數據Extents的總和,索引Extent的總和,以及一些未被分配的空間。之前提到MongoDB會對數據庫文件創建時候進行預分配,例如最小就是64M,哪怕你只有幾百個KB的數據。所以這個參數可能會比實際的數據大小會大不少。 這些額外未用空間是用來保證MongoDB可以在新的數據寫入時候快速的分配新的Extent,避免引起磁盤空間分配引起的延遲。

值得注意的是,當你刪除文檔,或甚至集合和索引,這個參數不會變小。換句話說,數據庫所使用的硬盤空間只會上升(或者不變),而不會因爲刪除數據而變小。當然需要知道的是這並不就意味着浪費,只是說有很多預留空間而已。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章