mongodb--GridFS
GridFS是一種將大型文件存儲在MongoDB的文件規(guī)范:
數(shù)據(jù)庫支持以BSON格式保存二進(jìn)制對象。 但是MongoDB中BSON對象最大不能超過4MB。
GridFS 規(guī)范提供了一種透明的機(jī)制,可以將一個(gè)大文件分割成為多個(gè)較小的文檔。
為實(shí)現(xiàn)這點(diǎn),該規(guī)范指定了一個(gè)將文件分塊的標(biāo)準(zhǔn)。每個(gè)文件都將在文件集合對象中保存一個(gè)元數(shù)據(jù)對象,一個(gè)或多個(gè)塊對象可被組合保存在一個(gè)塊集合中。
文件如何被分塊保存的細(xì)節(jié)可以參看GridFS Specification。
mongo自帶有一個(gè)實(shí)現(xiàn)mongofliles,基本操作如下:
列出所有文件:
上傳一個(gè)文件:
mongofiles put xxx.txt下載一個(gè)文件:
mongofiles get xxx.txt查找文件:
mongofiles search xxx //會查找所有文件名中包含“xxx”的文件 mongofiles list xxx //會查找所有文件名以“xxx”為前綴的文件參數(shù)說明:
–d 指定數(shù)據(jù)庫 ,默認(rèn)是fs,Mongofiles list –d testGridfs -u –p 指定用戶名,密碼 -h 指定主機(jī) -port 指定主機(jī)端口 -c 指定集合名,默認(rèn)是fs // 這個(gè)好像不對 -t 指定文件的MIME類型,默認(rèn)會忽略 //這個(gè)沒有測試過原理:
GridFS在數(shù)據(jù)庫中,默認(rèn)使用fs.chunks和fs.files來存儲文件。
1.fs.files集合存放文件的信息;
2.fs.chunks存放文件數(shù)據(jù);
fs.files集合包含了文件的元數(shù)據(jù),而fs.chunks集合則存儲實(shí)際的以256KB尺寸進(jìn)行分割的文件塊。如果你有分片的集合,那么文件塊會分布到多臺服務(wù)器上,或許能獲得比文件系統(tǒng)更好的性能。
> 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和文件塊數(shù)中創(chuàng)建了復(fù)合索引,以幫助快速訪問這些文件塊
> 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" } ] }一個(gè)fs.files集合中的一條記錄內(nèi)容如下,即一個(gè)file的信息如下:
{"_id" : ObjectId("4f4608844f9b855c6c35e298"), //唯一id,可以是用戶自定義的類型"filename" : "CPU.txt", //文件名"length" : 778, //文件長度"chunkSize" : 262144, //chunk的大小"uploadDate" : ISODate("2012-02-23T09:36:04.593Z"), //上傳時(shí)間"md5" : "e2c789b036cfb3b848ae39a24e795ca6", //文件的md5值"contentType" : "text/plain" //文件的MIME類型"meta" : null //文件的其它信息,默認(rèn)是沒有”meta”這個(gè)key,用戶可以自己定義為任意BSON對象 }對應(yīng)的fs.chunks中的chunk如下:
{"_id" : ObjectId("4f4608844f9b855c6c35e299"), //chunk的id"files_id" : ObjectId("4f4608844f9b855c6c35e298"), //文件的id,對應(yīng)fs.files中的對象,相當(dāng)于fs.files集合的外鍵"n" : 0, //文件的第幾個(gè)chunk塊,如果文件大于chunksize的話,會被分割成多個(gè)chunk塊"data" : BinData(0,"QGV...") //文件的二進(jìn)制數(shù)據(jù),這里省略了具體內(nèi)容 }默認(rèn)chunk的大小是256K:
public static final int DEFAULT_CHUNKSIZE = 256 * 1024;寫入:
如果文件大于chunksize,則把文件分割成多個(gè)chunk,再把這些chunk保存到fs.chunks中,最后再把文件信息存入到fs.files中。
讀取:
先據(jù)查詢的條件,在fs.files中找到一個(gè)合適的記錄,得到“_id”的值,再據(jù)這個(gè)值到fs.chunks中查找所有“files_id”為“_id”的chunk,并按“n”排序,最后依次讀取chunk中“data”對象的內(nèi)容,還原成原來的文件。
自定義Gridfs的hash函數(shù):
盡管從理論上,無論用什么hash函數(shù),都有可能出現(xiàn)hash值相同,但內(nèi)容不相同的文件,但是對于GridFS默認(rèn)使用的md5算法,目前已出現(xiàn)長度和md5值都相同但內(nèi)容不一樣的文件。
如果想要自已改用其它hash算法,可以從驅(qū)動入手。因?yàn)镚ridFS在MongoDB中實(shí)際也只是兩個(gè)普通的集合,所以完全可以自已修改驅(qū)動,替換下hash算法即可。
注意事項(xiàng):
GridFS的模塊
如果你想把存儲在MongoDB的GridFS的文件直接服務(wù)于Web服務(wù)器或文件系統(tǒng),那么你可以使用下面的GridFS插件:
1)GridFS-Fuse:讓GridFS的文件直接服務(wù)于文件系統(tǒng)
2)GridFS-Nginx:讓GridFS的文件直接服務(wù)于Nginx
GridFS的局限性
GridFS也并非十全十美的,它也有一些局限性:
1)工作集
伴隨數(shù)據(jù)庫內(nèi)容的GridFS文件會顯著地?cái)噭覯ongoDB的內(nèi)存工作集。如果你不想讓GridFS的文件影響到你的內(nèi)存工作集,那么可以把GridFS的文件存儲到不同的MongoDB服務(wù)器上。
2)性能
文件服務(wù)性能會慢于從Web服務(wù)器或文件系統(tǒng)中提供本地文件服務(wù)的性能。但是這個(gè)性能的損失換來的是管理上的優(yōu)勢。
3)原子更新
GridFS沒有提供對文件的原子更新方式。如果你需要滿足這種需求,那么你需要維護(hù)文件的多個(gè)版本,并選擇正確的版本。
轉(zhuǎn)載于:https://www.cnblogs.com/weloveshare/p/5752000.html
總結(jié)
以上是生活随笔為你收集整理的mongodb--GridFS的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: easyui combo自动高度(下拉框
- 下一篇: eclipse连接hdfs操作设置用户名