讀古今文學網 > MongoDB實戰 > 1.3 MongoDB的核心服務器和工具 >

1.3 MongoDB的核心服務器和工具

MongoDB是用C++編寫的,由10gen積極維護。該項目能在所有主流操作系統上編譯,包括Mac OS X、Windows和大多數Linux。mongodb.org上提供了這些平台的預編譯二進制包。MongoDB是開源的,遵循GNU-AGPL許可,GitHub上可以免費獲取到源代碼,而且經常會接受來自社區的貢獻,但這一項目主要還是由10gen的核心服務器團隊來領導的,絕大多數提交亦來自該團隊。

GNU-AGPL

GNU-AGPL是一個頗受爭議的許可。實踐中,它表示源代碼能被免費獲取,而且它鼓勵社區的貢獻。GNU-AGPL的主要局限是,出於社區的利益,任何對源代碼的修改都必須公佈出來。對於那些想保護其核心服務器增強特性的公司來說,10gen提供了特殊的商業許可。

MongoDB 1.0發佈於2009年11月。基本每三個月人們便發佈它的一個主要版本,偶數發行號1代表穩定分支,奇數代表開發分支。在本書編寫時,最新版本是v2.02。

1. release number,即版本號中的第二個數字。——譯者注 2. 你應該總是使用穩定版本,例如2.0.1版。

下文概述了MongoDB自帶的組件,並粗略描述了工具和面向MongoDB開發應用程序所需的語言驅動。

1.3.1 核心服務器

通過可執行文件mongod(Windows上是mongodb.exe)可以運行核心服務器。mongod服務器進程使用一個自定義的二進制協議從網絡套接字上接收命令。mongod進程的所有數據文件默認都存儲在/data/db3里。

3. Windows裡是c:datadb。

mongod有多種運行模式,最常見的是作為副本集中的一員。因為推薦使用複製,通常副本集由兩個副本組成,再加一個部署在第三台服務器上的仲裁進程4(arbiter process)。對於MongoDB的自動分片架構而言,其組件包含配置為預先分片的副本集的mongod進程,以及特殊的元數據服務器,稱為配置服務器(config server)。另外還有單獨的名為mongos的路由服務器向適當的分片發送請求。

4. 這些仲裁進程都是輕量級的,也就是說能方便地運行在應用服務器上。

相比其他的數據庫系統,例如MySQL,配置一個mongod進程相對比較簡單。雖然可以指定標準端口和數據目錄,但沒有什麼調優數據庫的選項。在大多數RDBMS中,數據庫調優意味著通過一大堆參數來控制內存分配等內容,這已經變成了一門黑魔法。MongoDB的設計哲學指出,內存管理最好是由操作系統而非DBA或應用程序開發者來處理。如此一來,數據文件通過mmap系統調用被映射成了系統的虛擬內存。這一舉措行之有效地將內存管理的重任交給了操作系統內核。本書中我還會更多地闡述與mmap相關的內容,不過目前你只需要知道缺少配置參數是一個系統設計亮點,而非缺陷。

1.3.2 JavaScript Shell

MongoDB命令行Shell是一個基於JavaScript的工具,用於管理數據庫和操作數據。可執行文件mongo會加載Shell並連接到指定的mongod進程。MongoDB Shell的功能和MySQL Shell差不多,主要的區別在於不使用SQL,大多數命令使用的是JavaScript表達式。舉例來說,可以像下面這樣選擇一個數據庫,向users集合中插入一個簡單的文檔:

> use mongodb-in-action
> db.users.insert({name: \"Kyle\"})
  

第一條命令指明了想使用哪個數據庫,MySQL的用戶一定不會對此感到陌生。第二條命令是一個JavaScript表達式,插入一個簡單的文檔。要查看插入的結果,可以使用以下查詢:

> db.users.find
{ _id: ObjectId(\"4ba667b0a90578631c9caea0\"), name: \"Kyle\" }
  

find方法返回了之前插入的文檔,其中添加了一個對像ID。所有文檔都要有一個主鍵,存儲在_id字段裡。只要能保證唯一性,也可以輸入一個自定義_id。如果省略了_id,則會自動插入一個MongoDB對像ID。

除了可以插入和查詢數據,Shell還可以用於運行管理命令。例如,查看當前數據庫操作、檢查到從節點的複製狀態,以及配置一個用於分片的集合。如你所見,MongoDB Shell著實是一個強大的工具,值得好好掌握。

說了這麼多,你那些和MongoDB相關的大量工作都是通過特定編程語言編寫的應用程序來完成的。想知道這究竟是如何辦到的,必須先瞭解一下MongoDB語言驅動。

1.3.3 數據庫驅動

如果之前把數據庫驅動想像成搗騰低級設備的夢魘,那你大可放心,MongoDB的驅動很容易使用。MongoDB團隊竭盡全力在提供符合特定語言風格的API,並同時保持跨語言的、相對統一的接口。舉例來說,所有驅動都實現了向集合保存文檔的類似方法,但不同語言裡文檔本身的表述通常會有所不同,驅動盡量會對特定語言表現得更自然一些。例如,在Ruby中就是使用一個Ruby散列,在Python中字典更合適一點,Java中缺少類似的語言原語,需要用一個實現了 LinkedHashMap的特殊文檔構建器類來表示文檔。

因為驅動程序為數據庫提供了一個以語言為中心的富接口,在構建應用程序時幾乎不再需要驅動程序之外的抽像了。這與使用RDBMS的應用程序設計截然不同,在數據庫的關係型數據模型和大多數現代編程語言的面向對像模型之間幾乎都需要有一個庫來做中介。雖然不需要對像關係映射器(object-relational mapper),但很多開發者都喜歡在驅動上做一層薄薄的封裝,用它來處理關聯、驗證和類型檢查5。

5. 在本書編寫時,一些流行的包裝器包括Java的Morphia、PHP的Doctrine以及Ruby的MongoMapper。

本書編寫時,10gen官方支持C、C++、C#、Erlang、Haskell、Java、Perl、PHP、Python、Scala和Ruby的驅動,而且這個列表還在不斷增長。如果你需要支持其他語言,通常都會有一個社區支持的驅動。如果對於某語言還沒有社區支持的驅動,mongodb.org的文檔裡有用於構建新驅動的規範。官方支持的驅動被大量使用在生產環境中,而且這些驅動都遵循Apache許可,因此想要編寫驅動的人可以免費獲取到大量優秀的示例。

從第3章開始,我會描述驅動是如何工作的,以及如何使用它們編寫程序。

1.3.4 命令行工具

MongoDB自帶了很多命令行工具。

  • mongodumpmongorestore,備份和恢復數據庫的標準工具。mongodump用原生的BSON格式將數據庫的數據保存下來,因此最好只是用來做備份,其優勢是熱備時非常有用,備份後能方便地用mongorestore恢復。

  • mongoexportmongoimport,用來導入導出JSON、CSV和TSV數據,數據需要支持多種格式時很有用。mongoimport還能用於大數據集的初始導入,但是在導入前順便還要注意一下,為了能充分利用好MongoDB通常需要對數據模型做些調整。在這種情況下,通過使用驅動的自定義腳本來導入數據會更方便一些。

  • mongosniff,這是一個網絡嗅探工具,用來觀察發送到數據庫的操作。基本就是把網絡上傳輸的BSON轉換為易於人們閱讀的Shell語句。

  • mongostat,與iostat類似,持續輪詢MongoDB和系統以便提供有幫助的統計信息,包括每秒操作數(插入、查詢、更新、刪除等)、分配的虛擬內存數量以及服務器的連接數。

稍後會在書中討論另外兩個工具:bsondumpmongofiles