1. 程式人生 > >淺析MongoDB數據庫的海量數據存儲應用

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

指數 table 系統重啟 ms sql nosql 高度 64位操作系統 sharding 同一文件

原文地址 http://www.cnblogs.com/nbpowerboy/p/4325692.html

【摘要】當今已進入大數據時代,特別是大規模互聯網web2.0應用不斷發展及雲計算所需要的海量存儲和海量計算發展,傳統的關系型數據庫已無法滿足這方面的需求。隨著NoSQL數據庫的不斷發展和成熟,可以較好地解決海量存儲和海量計算方面的應用需求。本文重點描述作為NoSQL之一MongoDB數據庫在海量數據存儲方面的應用。

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等)、多值數據庫(U2、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語句對照

3 過程分析與測試

3.1 GridFS概述

由於MongoDB中的Bson對象大小是有限制的,在1.7版本以前單個Bson對象最大容量為4M,1.7版本以後單個Bson對象最大容量為16M[5]。對於一般的文件存儲,單個對象的4到16M的存儲容量能夠滿足需求,但無法滿足對於一些大文件的存儲,如高清圖片、設計圖紙、視頻等,因此在海量數據存儲方面,MongoDB提供了內置的Grid

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等,方便管理和維護。

GridFS結合自動分片及自動復制技術,可以實現高性能的分布式數據庫集群架構,從而進行海量數據存儲,如下圖2所示。

技術分享圖片

圖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(至強)[email protected]

內存: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大容量文件分片信息

4 結論

隨著企業和個人數據的不斷擴大,隨著雲計算的高速發展,越來越多的應用需要存儲海量數據,並且對高並發和處理海量數據提出了更高的要求,傳統的關系型數據庫對於這些應用場景難以滿足應用需求,而作為NoSQL數據庫之一的MongoDB數據庫能夠完全滿足和解決在海量數據存儲方面的應用,越來越多的大網站和企業選擇MongoDB代替Mysql進行存儲。

註: 這個是本人四年前研究測試情況,目前MongoDB最新版本為3.0,已有廣泛的企業實際應用!

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

技術分享圖片


再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow

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