《MongoDB GridFS最佳應用概述》
作者:chszs,轉載需註明。部落客頁:http://blog.csdn.net/chszs
GridFS是MongoDB資料庫之上的一個簡單檔案系統抽象。如果你熟悉Amazon S3的話,那麼GridFS與之相似。為什麼像MongoDB這樣的NoSQL資料庫會提供這樣的一個檔案層抽象呢?
一、使用GridFS的理由
理由如下:
1)儲存使用者產生的檔案內容
大多數Web應用都允許使用者上傳檔案。當使用者使用關聯式資料庫時,這些使用者產生的檔案會儲存在檔案系統中,與資料庫相隔離,而不是放在資料庫內。這就帶來了一些問題。如何將檔案複製到所有需要檔案的伺服器上?當檔案刪除後,怎樣刪除所有的拷貝?怎樣保障檔案的安全以及做災備呢?GridFS很好地解決了這些問題,你可以利用你的Database Backup來備份你的檔案。而且由於MongoDB自身的複製技術,在MongoDB叢集中的每一個副本處都有你的檔案拷貝。刪除檔案跟刪除資料庫中的對象一樣簡單。
2)訪問檔案內容的分區
當把檔案上傳到GridFS後,檔案會被分割成大小為256KB的塊,並單獨存放。因此當你需要讀檔案中的某個範圍的位元組時,只需把相應的檔案塊載入記憶體,而無需把整個檔案載入到記憶體。這一點對於選擇讀或編輯尺寸很大的媒體內容檔案時非常有用。
3)在MongoDB中儲存16MB以上的檔案
MongoDB預設的檔案大小上限為16MB。所以,如果你的檔案超過了16MB,那麼你就應該使用GridFS。
4)克服檔案系統的限制
如果你需要儲存大量的檔案,你就需要考慮檔案系統自身的限制,因為檔案系統對目錄下的檔案數量是有要求的。而使用GridFS後,你無需再擔心這個問題。GridFS和MongoDB的分區使得你的檔案可以分布到多個伺服器上,而且沒有增加操作的複雜性。
二、深入GridFS
GridFS使用了兩種集合Collection來儲存資料
> show collections;fs.chunksfs.filessystem.indexes>
fs.files集合包含了檔案的中繼資料,而fs.chunks集合則儲存實際的以256KB尺寸進行分割的檔案塊。如果你有分區的集合,那麼檔案塊會分布到多台伺服器上,或許能獲得比檔案系統更好的效能。
> db.fs.files.findOne();{"_id" : ObjectId("530cf1bf96038f5cb6df5f39"),"filename" : "./conn.log","chunkSize" : 262144,"uploadDate" : ISODate("2014-02-25T19:40:47.321Z"),"md5" : "6515e95f8bb161f6435b130a0e587ccd","length" : 1644981}>
MongoDB還在files_id和檔案塊數中建立了複合索引,以協助快速存取這些檔案塊
> db.fs.chunks.getIndexes();[{"v" : 1,"key" : {"_id" : 1},"ns" : "files.fs.chunks","name" : "_id_"},{"v" : 1,"key" : {"files_id" : 1,"n" : 1},"ns" : "files.fs.chunks","name" : "files_id_1_n_1"}]>
三、GridFS執行個體
MongoDB有一個內建的工具mongofiles,可以協助練習實際使用GridFS的情境。請參閱相關的Driver文檔,查看如何使用GridFS。
Put#mongofiles -h -u -p --db files put /conn.logconnected to: 127.0.0.1added file: { _id: ObjectId('530cf1009710ca8fd47d7d5d'), filename: "./conn.log", chunkSize: 262144, uploadDate: new Date(1393357057021), md5: "6515e95f8bb161f6435b130a0e587ccd", length: 1644981 }done!Get#mongofiles -h -u -p --db files get /conn.logconnected to: 127.0.0.1done write to: ./conn.logList# mongofiles -h -u -p listconnected to: 127.0.0.1/conn.log 1644981Delete[root@ip-10-198-25-43 tmp]# mongofiles -h -u -p --db files delete /conn.logconnected to: 127.0.0.1done!
四、GridFS的模組
如果你想把儲存在MongoDB的GridFS的檔案直接服務於Web伺服器或檔案系統,那麼你可以使用下面的GridFS外掛程式:
1)GridFS-Fuse:讓GridFS的檔案直接服務於檔案系統
2)GridFS-Nginx:讓GridFS的檔案直接服務於Nginx
五、GridFS的局限性
GridFS也並非十全十美的,它也有一些局限性:
1)工作集
伴隨資料庫內容的GridFS檔案會顯著地攪動MongoDB的記憶體工作集。如果你不想讓GridFS的檔案影響到你的記憶體工作集,那麼可以把GridFS的檔案儲存體到不同的MongoDB伺服器上。
2)效能
檔案服務效能會慢於從Web伺服器或檔案系統中提供本地檔案服務的效能。但是這個效能的損失換來的是管理上的優勢。
3)原子更新
GridFS沒有提供對檔案的原子更新方式。如果你需要滿足這種需求,那麼你需要維護檔案的多個版本,並選擇正確的版本。