GridFS是一種在MongoDB中存儲(chǔ)大二進(jìn)制文件的機(jī)制。使用GridFS存文件有一下優(yōu)勢(shì):
- GridFS會(huì)直接利用已經(jīng)建立的復(fù)制或分片機(jī)制,所以對(duì)于文件存儲(chǔ)來(lái)說(shuō)故障恢復(fù)和拓展都很容易
- 避免用于存儲(chǔ)用戶上傳內(nèi)容的文件系統(tǒng)出現(xiàn)某些問(wèn)題。比如,GridFS在同一個(gè)目錄下放置大量的文件沒(méi)有任何問(wèn)題
- GridFS不產(chǎn)生磁盤碎片,因?yàn)镸ongoDB分配數(shù)據(jù)文件空間時(shí)以2GB為一塊
- GridFS 會(huì)將大文件對(duì)象分割成多個(gè)小的chunk(文件片段),一般為256k/個(gè),每個(gè)chunk將作為MongoDB的一個(gè)文檔(document)被存儲(chǔ)在chunks集合中。
- GridFS 用兩個(gè)集合來(lái)存儲(chǔ)一個(gè)文件:fs.files與fs.chunks。
- 每個(gè)文件的實(shí)際內(nèi)容被存在chunks(二進(jìn)制數(shù)據(jù))中,和文件有關(guān)的meta數(shù)據(jù)(filename,content_type,還有用戶自定義的屬性)將會(huì)被存在files集合中
- 如果你希望訪問(wèn)一個(gè)超大的文件,而不希望將它全部加入內(nèi)存,而是有“range access”的情況,即分段讀取,那么GridFS天生就具備這種能力,你可以隨意訪問(wèn)任意片段。
? ~ echo "hello world" > foo.txt
? ~ mongofiles put foo.txt
> db.getCollectionNames()
[ "fs.chunks", "fs.files", "my_collection" ]
> db['fs.chunks'].find()
{
"_id" : ObjectId("595a6cc382cd540c2284e44a"),
"files_id" : ObjectId("595a6cc382cd540c2284e449"),
"n" : 0,
"data" : BinData(0,"aGVsbG8gd29ybGQK")
}
>
- _id: 塊id
- file_id: 該塊所屬的文件id
- n: 塊編號(hào)
- data: 包含組成文件塊的二進(jìn)制數(shù)據(jù)
> db['fs.files'].find()
{
"_id" : ObjectId("595a6cc382cd540c2284e449"),
"chunkSize" : 261120,
"uploadDate" : ISODate("2017-07-03T16:11:47.778Z"),
"length" : 12,
"md5" : "6f5902ac237024bdd0c176cb93063dc4",
"filename" : "foo.txt"
}
>
- id: 文件id
- uploadDate: 文件存入GridFS的時(shí)間戳
- chunkSize: 每個(gè)塊的大小,默認(rèn)256K
- length: 文件內(nèi)容總的字節(jié)數(shù)
- md5: 文件內(nèi)容的md5校驗(yàn)和
- filename: 文件名