GridFS是一種在Mongodb中存儲大二進制文件的機制。GridFS 用於存儲和恢復那些超過16M(BSON文件限制)的文件(如:圖片、音頻、視頻等)。
使用GridFS有如下幾個原因:
1 利用GridFS可以簡化需求
2 GridFS會直接利用已建立的復制或分片機制,所以對於文件存儲來說故障恢復和擴展都容易
3 GridFS可以避免用於存儲用戶上傳內容的文件系統出現的某些問題。GridFS 會將大文件對象分割成多個小的chunk(文件片段),一般為256k/個,每個chunk將作為MongoDB的一個文檔(document)被存儲在chunks集合中。
4 GridFS不產生磁盤碎片。
下面來看下具體的使用方法:
GridFS最近的使用方法就是采用mongofiles的命令,mongofiles可以用來在GridFS中上傳,下載,顯示文件。
(1)新建一個test.txt文檔
root@zhf-maple:/home/zhf# echo "hello mongod" > test.txt
root@zhf-maple:/home/zhf# cat test.txt
hello mongod
(2)通過mongofiles上傳
root@zhf-maple:/home/zhf# mongofiles put test.txt
2017-12-31T22:06:26.489+0800 connected to: localhost
added file: test.txt
(3)顯示文件
root@zhf-maple:/home/zhf# mongofiles list
2017-12-31T22:06:41.308+0800 connected to: localhost
test.txt 13
(4)在本端刪除掉該文件
root@zhf-maple:/home/zhf# rm test.txt
root@zhf-maple:/home/zhf# cat test.txt
cat: test.txt: 沒有那個文件或目錄
(5)從GridFS下載文件。
root@zhf-maple:/home/zhf# mongofiles get test.txt
2017-12-31T22:07:43.762+0800 connected to: localhost
finished writing to test.txt
root@zhf-maple:/home/zhf# cat test,txt
cat: test,txt: 沒有那個文件或目錄
root@zhf-maple:/home/zhf# cat test.txt
hello mongod
那么GridFS具體是如何存儲文件的呢。前面介紹到GridFS是為了解決單個document不能超過16M的問題而推出的。通過將文件進行切分存成一個單獨的集合:fs.chunks,並保存一個文件索引表:fs.files。在前面的例子中我們上傳了一個test.txt文件。我們進入數據庫看下是如何存儲的。
在數據庫中多了test數據庫
> show dbs
admin 0.000GB
local 0.000GB
maple 0.000GB
test 0.000GB
在test數據庫下有fs.chunks和fs.files兩個集合。
> use test
switched to db test
> show collections
fs.chunks
fs.files
在chunks中字段解釋如下:
_id:文件唯一的id
files_id:包含這個塊元數據的文件文檔的_id
n:表示塊編號。也就是這個塊在原文件中的順序編號。這里為0代表只有一個塊
data:組成文件塊的二進制數據
> db.fs.chunks.find()
{ "_id" : ObjectId("5a48eee22d33c14783a13d55"), "files_id" : ObjectId("5a48eee22d33c14783a13d54"), "n" : 0, "data" : BinData(0,"aGVsbG8gbW9uZ29kCg==") }
在files中的字段解釋如下:
_id:文件中唯一的id
length:文件長度
chunksize:每塊的大小。以字節為單位
uploadDate:文件存入GridFS的時間戳
md5:文件內容的md5校驗和。由服務器端生成。
> db.fs.files.find()
{ "_id" : ObjectId("5a48eee22d33c14783a13d54"), "chunkSize" : 261120, "uploadDate" : ISODate("2017-12-31T14:06:27.294Z"), "length" : 13, "md5" : "40a1f080f26be5a4c8cef7d78f974659", "filename" : "test.txt" }