淺析MongoDB數據庫的海量數據存儲應用

【摘要】當今已進入大數據時代,特別是大規模互聯網web2.0應用不斷髮展及雲計算所須要的海量存儲和海量計算髮展,傳統的關係型數據庫已沒法知足這方面的需求。隨着NoSQL數據庫的不斷髮展和成熟,能夠較好地解決海量存儲和海量計算方面的應用需求。本文重點描述做爲NoSQL之一MongoDB數據庫在海量數據存儲方面的應用。html

1  引言
NoSQL,全稱是「Not Only Sql」,指的是非關係型的數據庫。這類數據庫主要有這些特色:非關係型的、分佈式、開源的、水平可擴展的。原始目的是爲了大規模web應用,這場全新的數據庫革命運動早期就有人提出,發展至2009年趨勢愈加高漲。非關係型的數據存儲一般的應用如:模式自有、支持簡易複製、簡單的API、最終的一致性(非ACID)、大容量數據等。它的種類繁多,如列式數據庫(Hadoop/HBase、Cassandra、Hypertable、Amazon SimpleDB等)、文檔型數據庫(MongoDB、CouchDB、OrientDB等)、鍵值數據庫(Azure Table Storage、MEMBASE、Redis、Berkeley DB、MemcacheDB等)、圖形數據庫(Neo4J、Infinite Graph、Sones、Bigdata等)、面向對象數據庫(db4o、Versant、Objectivity、Starcounter等)、網格及雲數據庫(GigaSpaces、Queplix、Hazelcast等)、XML數據庫(Mark Logic Server、EMC Documentum xDB、BaseX、Berkeley DB XML等)、多值數據庫(U二、OpenInsight、OpenQM等)及其餘非關係型數據庫(如FileDB)等。
MongoDB屬於NoSQL數據的一種,是由10gen公司提供的一個開源的、模式自由的、面向文檔存儲的、分佈式的數據庫,是一個介於關係數據庫和非關係數據庫之間的產品。由C++語言編寫,旨在爲Web應用提供可擴展的高性能數據存儲解決方案。他支持的數據結構很是鬆散,是相似Json的Bson格式,所以能夠存儲比較複雜的數據類型。
他能夠運行在Solaris、Linux、Windows和OSX平臺上,支持32位和64位應用,其中在32位應用中單個數據庫最大容量爲2G,在64位應用中存儲容量大小隻與實際存儲空間大小有關,而且提供了Java、C#、PHP、C、C++、Javascript、Python、Ruby、Perl等多種語言的驅動程序,最新的生產版本爲2.0,官方下載地址:http://www.mongodb.org/downloads。目前正在使用他的網站和企業已超過了100家,如視覺中國、大衆點評網、淘寶網、盛大、Foursquare、Wordnik、OpenShift、SourceForge、Github等。
隨着企業數據不斷積累和增長及Web2.0應用不斷向前發展,已進入了我的信息時代,對於大中型企業來講,可能天天將產生大量的數據,來之於各種系統,如各種文檔(OA文檔、項目文檔等)、設計圖紙、高清圖片、視頻等,對於員工來講,更關心的是我的信息方面的存儲和計算,當這些信息量足夠大時,想要實時提取或分析數據,傳統集中式方式難以知足這方面的需求,所以採用分佈式的存儲和計算成爲必然的選擇,一方面主要解決海量存儲問題,另外一方面解決海量計算問題。採用MongoDB的數據庫技術能有效地解決分佈式方面的應用,本文重點分析MongoDB在海量數據存儲方面的應用。
2  概述
2.1  MongoDB的主要特色
(1)文件存儲格式爲Bson,使用易於掌握和理解的Json風格語法。相對Json來講,Bson擁有更好的性能,主要表現爲更快的遍歷速度、操做更簡易、增長了額外的
數據類型。
(2)模式自由,支持嵌入子文檔和數組,無需事先建立數據結構,屬於逆規範化的數據模型,有利於提升查詢速度。
(3)動態查詢,支持豐富的查詢表達式,使用Json形式的標記,可輕易查詢文檔中內嵌的對象和數組及子文檔。
(4)完整的索引支持,包括文檔內嵌對象和數據,同時還提供了全文索引方式,MongoDB的查詢優化器會分析查詢表達式,並生成一個高效的查詢計劃。
(5)使用高效的二進制數據存儲,適合存儲大型對象(如高清圖片、視頻等)。
(6)支持多種複製模式,提供冗餘及自動故障轉移。支持Master-Slave、Replica Pairs/Replica Sets、有限Master-Master模式。
(7)支持服務端腳本和Map/Reduce,能夠實現海量數據計算,即實現雲計算功能。
(8)性能高、速度快。在多數場合,其查詢速度對於MySQL要快的多,對於CPU佔用很是小。部署很簡單,幾乎是零配置。
(9)自動處理碎片,支持自動分片功能實現水平擴展的數據庫集羣,能夠動態添加或移除節點。
(10)內置GridFS,支持海量存儲。
(11)可經過網絡訪問,採用高效的MongoDB網絡協議,在性能方面要優於http或Rest協議。
(12)第三方支持豐富,MongoDB社區活躍,愈來愈多的公司和網站在生產環境中使用MongoDB進行技術架構優化,同時由10gen公司官方提供強大技術支持。
2.2  MongoDB的適用場景
MongoDB的主要目標是在鍵/值存儲方式(提供了高性能和高度伸縮性)以及傳統的RDBMS系統(豐富的功能)架起一座橋樑,集二者的優點於一身。
(1)網站數據:MongoDB很是適合實時的插入,更新與查詢,並具有網站實時數據存儲所需的複製及高度伸縮性。
(2)緩存:因爲性能很高,MongoDB也適合做爲信息基礎設施的緩存層。在系統重啓以後,由MongoDB搭建的持久化緩存層能夠避免下層的數據源過載。
(3)大尺寸,低價值的數據:使用傳統的關係型數據庫存儲一些數據時可能會比較昂貴,在此以前,不少時候程序員每每會選擇傳統的文件進行存儲。
(4)高伸縮性的場景:MongoDB很是適合由數十或數百臺服務器組成的數據庫。MongoDB的路線圖中已經包含對MapReduce
引擎的內置支持。
(5)用於對象及JSON數據的存儲:MongoDB的Bson數據格式很是適合文檔化格式的存儲及查詢。
2.3  MongoDB的體系結構
MongoDB是由一系列物理文件(數據文件,日誌文件等)的集合與之對應的邏輯結構(集合、文檔等)構成的數據庫。
MongoDB的邏輯結構實際是一種層次結構,由文檔(document,至關於關係數據庫中的row)、集合(collection,至關於關係數據庫中的table)、數據庫(database,至關於關係數據庫中的database)這三部分組成。
一個MongoDB實例支持多個數據庫。在MongoDB內部,每一個數據庫都包含一個.ns文件和一些數據文件,採用預分配空間的機制,始終保持額外的空間和空餘的數據文件,從而有效避免了因爲數據暴增帶來的磁盤壓力過大問題。每一個預分配的文件都用0進行填充,數據文件每新分配一次,他的大小都會是上一個數據文件大小的2倍,每一個數據文件最大爲2G。
2.4  MongoDB與MS SQL Server的語句對照
MongoDB提供了功能豐富的查詢表達式,能夠實現絕大多數關係數據庫的sql語句功能,以表employee(id,name,age)舉例對照說明,以下圖1所示。前端

 

圖1  MongoDB與MS SQL Server語句對照git

過程分析與測試程序員

3.1  GridFS概述github

因爲MongoDB中的Bson對象大小是有限制的,在1.7版本之前單個Bson對象最大容量爲4M,1.7版本之後單個Bson對象最大容量爲16M[5]。對於通常的文件存儲,單個對象的4到16M的存儲容量可以知足需求,但沒法知足對於一些大文件的存儲,如高清圖片、設計圖紙、視頻等,所以在海量數據存儲方面,MongoDB提供了內置的Gridweb

FS,能夠將一個大文件分割成爲多個較小的文檔,能夠指定文件分塊標準,對用戶是透明的。GridFS使用兩個數據結構來存儲數據:files(包含元數據對象)、chunks(包含其餘一些相關信息的二進制塊)。爲了使多個GridFS命名爲一個單一的數據庫,文件和塊都有一個前綴,默認前綴爲fs,用戶有權改變這個前綴。
GridFS對Java、C#、Perl、PHP、Python、Ruby等程序言語均支持,且提供了良好的API接口。
3.2  基於GridFS的海量數據存儲測試
本文主要採用MongoDB最新版2.0及官方提供的C#語言驅動進行測試,C#驅動下載地址:https://github.com/mongodb/Mongo-csharp-driver。
MongoDB在bin目錄下提供了一系列有用的工具,能夠很方便的進行運維管理:
(1)bsondump:將Bson格式的文件轉儲爲Json格式的數據。
(2)mongo:客戶端命令行工具,支持js語法。
(3)mongod:數據庫服務端,每一個實例啓動一個進程,能夠fork爲後臺運行。
(4)mongodump:數據庫備份工具。
(5)mongorestore:數據庫恢復工具。
(6)mongoexport:數據導出工具。
(7)mongoimport:數據導入工具。
(8)mongofiles:GridFS管理工具,可實現二進制文件的存取。
(9)mongos:分片路由,若是使用了sharding功能,則應用程序鏈接的是mongos,而非mongod。
(10)mongosniff:這一工具的做用相似於tcpdump,不一樣的是他只監控MongoDB相關包請求,而且是以指定的可讀性的形式輸出。
(11)mongostat:實時性能監控工具。
同時有好幾個第三方提供的客戶端圖形工具,如MongoVUE、RockMongo、MongoHub等,方便管理和維護。sql

GridFS結合自動分片及自動複製技術,能夠實現高性能的分佈式數據庫集羣架構,從而進行海量數據存儲,以下圖2所示。mongodb

 

圖2  高性能的分佈式數據庫集羣架構數據庫

MongoDB Sharding Cluster須要三種角色:數組

(1)Shard Server:即存儲實際數據的分片,每一個Shard能夠是一個mongod實例,也能夠是一組mongod實例構成的Replica Set。

(2)Config Server:用來存儲全部shard節點的配置信息、每一個chunk的shard key範圍、chunk在各shard的分佈狀況、該集羣中全部DB和collection的sharding配置信息。

(3)Route Process:這是一個前端路由,客戶端由此接入,而後詢問Config Servers須要到哪一個shard上查詢或保存記錄,再鏈接相應的shard進行操做,最後將結果返回給客戶端,而這一切對客戶端是透明的,客戶端不用關心所操做的記錄存儲在哪一個shard上。

爲了測試方便,下面在同一臺物理機器上構建一個簡單的Sharding Cluster,以下圖3所示。

 

 

 

圖3  簡單的Sharding Cluster架構圖

 

配置測試環境以下:

模擬2個Shard服務器和1個Config服務器,均運行在本機127.0.0.1上,只是端口不一樣:

(1)Shard Server1:127.0.0.1:27020。

(2)Shard Server2:127.0.0.1:27021。

(3)Config Server:127.0.0.1:27022。

(4)Route Process:127.0.0.1:27017。

啓動相關服務進程:

c:\mongodb 2.0.0\bin>mongod --shardsvr --dbpath "c:\mongodb 2.0.0\db" --port 27020

d:\mongodb 2.0.0\bin>mongod --shardsvr --dbpath "d:\mongodb 2.0.0\db" --port 27021

e:\mongodb 2.0.0\bin>mongod --configsvr --dbpath "e:\mongodb 2.0.0\db" --port 27022

e:\mongodb 2.0.0\bin>mongos --configdb 127.0.0.1:27022

配置Sharding:

(1)e:\mongodb 2.0.0\bin>mongo

(2)use admin

(3)db.runCommand( { addshard : "127.0.0.1:27020", allowLocal : 1,

maxSize:2 , minKey:1, maxKey:10 } )

(4)db.runCommand( { addshard : "127.0.0.1:27021", allowLocal : 1, minKey:100  } )

(5)config =connect("127.0.0.1:27022")

(6)config = config.getSisterDB("config")

(7)ecDocs=db.getSisterDB("ecDocs")

(8)db.runCommand({enablesharding:"ecDocs"})

(9)db.runCommand( { shardcollection : "ecDocs.filedocs.chunks", key : { files_id : 1 } } )

(10)db.runCommand( { shardcollection : "ecDocs.filedocs.files", key : { _id : 1 } } )

以上的ecDocs是指數據庫名,filedocs是指用戶自定義的GridFS的文件集合名,系統默認文件集合名爲fs。

使用官方提供的C#驅動,須要在程序中引用MongoDB.Driver.dllMongoDB.Bson.dll,循環添加同一文件到GridFS示例代碼,以下圖4所示。

 

 

 

圖4  循環添加同一文件到GridFS代碼

 

測試配置環境以下:

操做系統:WindowsXP專業版32位SP3。

處理器(CPU):英特爾Xeon(至強)W3503@2.40GHz。

內存:3567MB(DDR31333MHz/FLASH)。

硬盤:希捷ST3250318AS(250GB/7200轉/分)。

因爲本機是32位操做系統,所以單個服務實例只支持GridFS的文件容量大小爲0.9G左右,因爲採用了兩臺Shard服務實例,能夠支持存儲的文件總容量大小爲1.8G左右,若是是64位操做系統就沒有此限制。

本文主要測試GridFS採用循環插入大容量文件的性能和分片容量大小,測試結果,以下圖5所示。

從圖5能夠看出,第1到3步驟,只添加單個文件時,Shard2並無產生分片數據,只有測試到步驟4連續添加100個相同文件時Shard2才產生分片數據,而且添加三四百兆的單個文件,只需11秒多就完成了操做,而即便經過文件拷貝方式這麼大的文件也至少須要二三十秒才能完成,可見MongoDB在大容量文件存儲方面擁有很是高的性能。

經過在客戶端的mongo工具輸入db.printShardingStatus()命令能夠查看詳細分片狀況,以下圖6所示。

從圖6能夠看出,在shard1中分配了6個chunks,在shard2中分配了7個chunks,分片數據相對仍是比較均勻的。

從以上的測試能夠得知,採用GridFS能夠存儲海量數據,而且能夠經過廉價服務器進行大規模數據庫集羣,很是容易擴展部署,程序編碼也很是容易,所以可以有效支持雲存儲的應用,可以知足大規模數據存儲的應用需求。

 

圖5  GridFS大容量文件測試結果

 

圖6  GridFS大容量文件分片信息

結論

隨着企業和我的數據的不斷擴大,隨着雲計算的高速發展,愈來愈多的應用須要存儲海量數據,而且對高併發和處理海量數據提出了更高的要求,傳統的關係型數據庫對於這些應用場景難以知足應用需求,而做爲NoSQL數據庫之一的MongoDB數據庫可以徹底知足和解決在海量數據存儲方面的應用,愈來愈多的大網站和企業選擇MongoDB代替Mysql進行存儲。

 

注: 這個是本人四年前研究測試狀況,目前MongoDB最新版本爲3.0,已有普遍的企業實際應用!

同時歡迎關注本人的微信訂閱號QYXXHQY,不按期更新企業信息化前沿相關技術和應用,歡迎掃描關注,二維碼以下:

   

本博客爲軟件人生原創,歡迎轉載,轉載請標明出處:http://www.cnblogs.com/nbpowerboy/p/4325692.html。演繹或用於商業目的,可是必須保留本文的署名軟件人生(包含連接)。如您有任何疑問或者受權方面的協商,請給我留言。

相關文章
相關標籤/搜索