MongoDB內部結構分析

2021-08-27 21:39:11 字數 2227 閱讀 4746

對於大多數的mongodb的使用者來說,mongodb就像是乙個大黑盒但是如果你能夠了解到mongodb內部一些構造的話,將有利於你更好地理解和使用mongodb。

bson

在mongodb中,文件是對資料的抽象,它被使用在client端和server端的互動中。所有的client端(各種語言的driver)都會使用這種抽象,它的表現形式就是我們常說的bson(binary json)。

bson 是乙個輕量級的二進位制資料格式。mongodb能夠使用bson,並將bson作為資料的儲存存放在磁碟中。

當client端要將寫入文件,使用查詢等操作時,需要將文件編碼為bson格式,然後再傳送給server端。同樣,server端的返回結果也是編碼為bson格式再返回給client端的。

使用bson格式出於以下3種目的:

1)效率

bson是為效率而設計的,它只需要使用很少的空間。即使在最壞的情況下,bson格式也比json格式在最好的情況下儲存效率高。

2)傳輸性

在某些情況下,bson會犧牲額外的空間讓資料的傳輸更加方便。比如,字串的傳輸的字首會標識字串的長度,而不是在字串的末尾打上結束的標記。這樣的傳輸形式有利於mongodb修改傳輸的資料。

3)效能

最後,bson格式的編碼和解碼都是非常快速的。它使用了c風格的資料表現形式,這樣在各種語言中都可以高效地使用。

寫入協議

client端訪問server端使用了輕量級的tcp/ip寫入協議。這種協議在mongodb wiki中有詳細介紹,它其實是在bson資料上面做了一層簡單的包裝。比如說,寫入資料的命令中包含了1個20位元組的訊息頭(由訊息的長度和寫入命令標識組成),需要寫入的collection名稱和需要寫入的資料。

資料檔案

在mongodb的資料資料夾中(預設路徑是/data/db)由構成資料庫的所有檔案。每乙個資料庫都包含乙個.ns檔案和一些資料檔案,其中資料檔案會隨著資料量的增加而變多。所以如果有乙個資料庫名字叫做foo,那麼構成foo這個資料庫的檔案就會由foo.ns,foo.0,foo.1,foo.2等等組成。

資料檔案每新增一次,大小都會是上乙個資料檔案的2倍,每個資料檔案最大2g。這樣的設計有利於防止資料量較小的資料庫浪費過多的空間,同時又能保證資料量較大的資料庫有相應的空間使用。

mongodb會使用預分配方式來保證寫入效能的穩定(這種方式可以使用–noprealloc關閉)。預分配在後台進行,並且每個預分配的檔案都用0進行填充。這會讓mongodb始終保持額外的空間和空餘的資料檔案,從而避免了資料增長過快而帶來的分配磁碟空間引起的阻塞。

名字空間和盤區

每乙個資料庫都由多個名字空間組成,每乙個名字空間儲存了相應型別的資料。資料庫中的每乙個collection都有各自對應的名字空間,索引檔案同樣也有名字空間。所有名字空間的元資料都儲存在.ns檔案中。

名字空間中的資料在磁碟中分為多個區間,這個叫做盤區。在下圖中,foo這個資料庫包含3個資料檔案,第三個資料檔案屬於空的預分配檔案。頭兩個資料檔案被分為了相應的盤區對應不同的名字空間。

上圖顯示了名字空間和盤區的相關特點。每乙個名字空間可以包含多個不同的盤區,這些盤區並不是連續的。與資料檔案的增長相同,每乙個名字空間對應的盤區大小的也是隨著分配的次數不斷增長的。這樣做的目的是為了平衡名字空間浪費的空間與保持某乙個名字空間中資料的連續性。上圖中還有乙個需要注意的名字空間:$freelist,這個名字空間用於記錄不再使用的盤區(被刪除的collection或索引)。每當名字空間需要分配新的盤區的時候,都會先檢視$freelist是否有大小合適的盤區可以使用。

記憶體對映儲存引擎

mongodb目前支援的儲存引擎為記憶體對映引擎。當mongodb啟動的時候,會將所有的資料檔案對映到記憶體中,然後作業系統會託管所有的磁碟操作。這種儲存引擎有以下幾種特點:

* mongodb中關於記憶體管理的**非常精簡,畢竟相關的工作已經有作業系統進行託管。

* mongodb伺服器使用的虛擬記憶體將非常巨大,並將超過整個資料檔案的大小。不用擔心,作業系統會去處理這一切。要注意的是,mongodb自己是不管理記憶體的,無法指定記憶體大小,完全交給作業系統來管理,因此有時候是不可控的,在生產環境使用必須在os層面監控記憶體使用情況。

* mongodb無法控制資料寫入磁碟的順序,這樣將導致mongodb無法實現writeahead日誌的特性。所以,如果mongodb希望提供一種durability的特性(這一特性可以參考我寫的關於cassandra文章:需要實現另外一種儲存引擎。

* 32位系統的mongodb伺服器每乙個mongod例項只能使用2g的資料檔案。這是由於位址指標只能支援32位。mongodb

docker映象內部結構分析

一直以來我都是使用docker命令pull映象,那如果我們要製作自己的映象檔案呢?這就需要我們研究下docker image的內部結構 核心空間是 kernel,linux 剛啟動時會載入 bootfs 檔案系統,之後 bootfs 會被解除安裝掉。使用者空間的檔案系統是 rootfs,包含我們熟悉...

HBase內部結構

table表 就是有乙個或者多個列族組成,加上之前的 使用,這個表概念應該很熟了 row行 乙個行包括了多個列,這些列通過列族來分類 column family列族 列族是多個列的集合,hbase會盡量的將乙個列族的列放入同乙個伺服器內,這樣可以提高訪問效能,並且可以批量管理有關聯的一堆列,所有的資...

Oracle檢視內部結構

1 分析資料檔案塊,轉儲資料檔案n的塊m alter system dump datafile n block m 2 分析日誌檔案 alter system dump logfile logfilename 3 分析控制檔案的內容 alter session set events immediat...