亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

MongoDbgridfs-ngnix文件存儲方案

2019-11-14 15:56:52
字體:
來源:轉載
供稿:網友

      在各類系統應用服務端開發中,我們經常會遇到文件存儲的問題。 常見的磁盤文件系統,DBMS傳統文件流存儲。今天我們看一下基于NoSQL數據庫MongoDb的存儲方案。筆者環境 以CentOS 6.5,MongoDb 2.6.3,  Nginx-1.4.7 為例,您需要了解linux常用命令。
先來回顧一下MongoDb的內部文件結構

O6EzR

  1. MongoDB在數據存儲上按命名空間來劃分,一個collection是一個命名空間,一個索引也是一個命名空間
  2. 同一個命名空間的數據被分成很多個Extent,Extent之間使用雙向鏈表連接
  3. 在每一個Extent中,保存了具體每一行的數據,這些數據也是通過雙向鏈接連接的
  4. 每一行數據存儲空間不僅包括數據占用空間,還可能包含一部分附加空間,這使得在數據update變大后可以不移動位置
  5. 索引以BTree結構實現

然后是GridFs的結構

gridfs1

GridFS在數據庫中,默認使用fs.chunks和fs.files來存儲文件。

其中fs.files集合存放文件的信息,fs.chunks存放文件數據。

一個fs.files集合中的一條記錄內容如下,即一個file的信息如下:

{ "_id" : ObjectId("4f4608844f9b855c6c35e298"),       //唯一id,可以是用戶自定義的類型"filename" : "CPU.txt",      //文件名"length" : 778,      //文件長度"chunkSize" : 262144,    //chunk的大小"uploadDate" : ISODate("2012-02-23T09:36:04.593Z"), //上傳時間"md5" : "e2c789b036cfb3b848ae39a24e795ca6",      //文件的md5值"contentType" : "text/plain"     //文件的MIME類型"meta" : null    //文件的其它信息,默認是沒有”meta”這個key,用戶可以自己定義為任意BSON對象}

對應的fs.chunks中的chunk如下:

{ "_id" : ObjectId("4f4608844f9b855c6c35e299"),    //chunk的id"files_id" : ObjectId("4f4608844f9b855c6c35e298"),  //文件的id,對應fs.files中的對象,相當于fs.files集合的外鍵"n" : 0,     //文件的第幾個chunk塊,如果文件大于chunksize的話,會被分割成多個chunk塊"data" : BinData(0,"QGV...")     //文件的二進制數據,這里省略了具體內容}

文件存入到GridFS過程中,如果文件大于chunksize,則把文件分割成多個chunk,再把這些chunk保存到fs.chunks中,最后再把文件信息存入到fs.files中。

在讀取文件的時候,先據查詢的條件,在fs.files中找到一個合適的記錄,得到“_id”的值,再據這個值到fs.chunks中查找所有“files_id”為“_id”的chunk,并按“n”排序,最后依次讀取chunk中“data”對象的內容,還原成原來的文件。

安裝Install與配置

1.安裝mongoDb

增加MongoDB Repository,不清楚vim,請參考VIM

vim /etc/yum.repos.d/mongodb.repo

如果是64bit的

[mongodb]

name=MongoDB Repository

baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/

gpgcheck=0

enabled=1

32bit的系統:

[mongodb]

name=MongoDB Repository

baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/i686/

gpgcheck=0

enabled=1

然后安裝,會提示Y/N:

yum install mongo-10gen mongo-10gen-server

啟動:

service mongod start

查看狀態

service mongod status

停止

service mongod stop

更多,關于3.0以上版本,請參考官網。

2.安裝nginx及nginx-gridfs

依賴庫、工具

# yum -y install pcre-devel openssl-devel zlib-devel

# yum -y install gcc gcc-c++

下載nginx-gridfs源碼

# git clone https://github.com/mdirolf/nginx-gridfs.git

# cd nginx-gridfs

# git checkout v0.8

# git submodule init

# git submodule update

下載nginx源碼,編譯安裝。(高版本支持不好)

# wget http://nginx.org/download/nginx-1.4.7.tar.gz

# tar zxvf nginx-1.4.7.tar.gz

# cd nginx-1.4.7

# ./configure --with-openssl=/usr/include/openssl --add-module=../nginx-gridfs/

# make -j8 && make install –j8

注意藍色字符配置成對應nginx-gridfs的路徑

3. 配置nginx-gridfs

vim /usr/local/nginx/conf/nginx.conf

在 server 節點中添加 location 節點

location /img/ {
        gridfs testdb
        field=filename
        type=string;
        mongo 192.168.0.159:27017;
}

location /files/ {
        gridfs testdb
        field=_id
        type=objectid;
        mongo 192.168.0.159:27017;
}

這里我們的mongo服務在ip 192.168.0.159。
如果不指定 field,默認為 MongoDB 的自增ID,且type為int

配置參數介紹:

gridfs:nginx識別插件的關鍵字
testdb:db名
[root_collection]: 選擇collection,如root_collection=blog, mongod就會去找blog.files與blog.chunks兩個塊,默認是fs
[field]: 查詢字段,保證mongdb里有這個字段名,支持_id, filename, 可省略, 默認是_id
[type]: 解釋field的數據類型,支持objectid, int, string, 可省略, 默認是int
[user]: 用戶名, 可省略
[pass]: 密碼, 可省略
mongo: mongodb url

啟動nginx服務

# /usr/local/nginx/sbin/nginx

可能出現:
Nginx [emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use)

這時可用使用命令關閉占用80端口的程序

sudo fuser -k 80/tcp


簡單測試

用原生的命令行上傳一個文件

mongofiles put 937910.jpg --local ~/937910_100.jpg --host 192.168.0.159 --port 27017 --db testdb --type jpg

937910.jpg是我們提前下載好一個圖片文件,注意我們沒有指定collection,默認是fs

從http://www.robomongo.org/安裝robomongo管理工具, 查看剛剛上傳的文件

image

最后我們在瀏覽器訪問,如果看到圖片就OK了

http://192.168.0.159/img/937910.jpg

對于.net環境下mongodb CSharpDriver  1.10.0 從Nuget:
Install-Package mongocsharpdriver -Version 1.10.0
我們使用如下片段代碼:

                int nFileLen = fileUploadModel.FileBytes.Length;                MongoGridFSSettings fsSetting = new MongoGridFSSettings() { Root = CollectionName };                MongoGridFS fs = new MongoGridFS(mongoServer, MongoDatabaseName, fsSetting);                //調用Write、WriteByte、WriteLine函數時需要手動設置上傳時間                //通過Metadata 添加附加信息                MongoGridFSCreateOptions option = new MongoGridFSCreateOptions();                option.Id = ObjectId.GenerateNewId();                var currentDate = DateTime.Now;                option.UploadDate = currentDate;                option.Aliases = alias;                BsonDocument doc = new BsonDocument();                //文檔附加信息存儲                if(fileUploadModel.DocExtraInfo!=null&&fileUploadModel.DocExtraInfo.Count>0)                {                    foreach(var obj in fileUploadModel.DocExtraInfo)                    {                        if (!doc.Elements.Any(p => p.Name == obj.Key))                        {                            doc.Add(obj.Key, obj.Value);                        }                    }                }                option.Metadata = doc;                //創建文件,文件并存儲數據                using (MongoGridFSStream gfs = fs.Create(fileUploadModel.FileName, option))                {                    gfs.Write(fileUploadModel.FileBytes, 0, nFileLen);                    gfs.Close();                }                log.ErrorFormat("附件標識:{0} 文件名:{1} 上傳成功", alias, fileUploadModel.FileName);                return option.Id.ToString();

注意,目前gridfs-ngnix不支持_id類型是GUID的,關于ObjectId參考官網,如下圖:

mongodb-objectid

mongodb產生objectid還有一個更大的優勢,就是mongodb可以通過自身的服務來產生objectid,也可以通過客戶端的驅動程序來產生。

什么時候使用Gridfs

來自官方2.6.10版本 手冊內容

For documents in a MongoDB collection, you should always use GridFS for storing files larger than 16 MB.  In some situations, storing large files may be more efficient in a MongoDB database than on a system-level filesystem.

? If your filesystem limits the number of files in a directory, you can use GridFS to store as many files as needed.
? When you want to keep your files and metadata automatically synced and deployed across a number of systems and facilities. When using geographically distributed replica sets MongoDB can distribute files and their metadata automatically to a number of mongod instances and  facilities.
? When you want to access information from portions of large files without having to load whole files into memory, you can use GridFS to recall sections of files without reading the entire file into memory.

Do not use GridFS if you need to update the content of the entire file atomically. As an alternative you can store multiple versions of each file and specify the current version of the file in the metadata. You can update the metadata field that indicates “latest” status in an atomic update after uploading the new version of the file, and later remove PRevious versions if needed.

Furthermore, if your files are all smaller the 16 MB BSON Document Size limit, consider storing the file manually within a single document. You may use the BinData data type to store the binary data. See your drivers documentation for details on using BinData.

數據庫主從同步

原理圖

mongodbre

上圖是MongoDB采用Replica Sets模式的同步流程

  • 紅色箭頭表示寫操作寫到Primary上,然后異步同步到多個Secondary上
  • 藍色箭頭表示讀操作可以從Primary或Secondary任意一個上讀
  • 各個Primary與Secondary之間一直保持心跳同步檢測,用于判斷Replica Sets的狀態

數據分片機制

wlqvf

  • MongoDB的分片是指定一個分片key來進行,數據按范圍分成不同的chunk,每個chunk的大小有限制
  • 有多個分片節點保存這些chunk,每個節點保存一部分的chunk
  • 每一個分片節點都是一個Replica Sets,這樣保證數據的安全性
  • 當一個chunk超過其限制的最大體積時,會分裂成兩個小的chunk
  • 當chunk在分片節點中分布不均衡時,會引發chunk遷移操作

分片時服務器角色

RArrX

上面講了分片的標準,下面是具體在分片時的幾種節點角色

  • 客戶端訪問路由節點mongos來進行數據讀寫
  • config服務器保存了兩個映射關系,一個是key值的區間對應哪一個chunk的映射關系,另一個是chunk存在哪一個分片節點的映射關系
  • 路由節點通過config服務器獲取數據信息,通過這些信息,找到真正存放數據的分片節點進行對應操作
  • 路由節點還會在寫操作時判斷當前chunk是否超出限定大小,如果超出,就分列成兩個chunk
  • 對于按分片key進行的查詢和update操作來說,路由節點會查到具體的chunk然后再進行相關的工作
  • 對于不按分片key進行的查詢和update操作來說,mongos會對所有下屬節點發送請求然后再對返回結果進行合并

其它關于mongodb 的一些小提示:

  • 不要使用32位版本

MongoDB的32位版本也是不建議被使用的,因為你只能處理2GB大小的數據。還記得第一個限制么?這是MongoDB關于該限制的說明。

  • 了解官方的限制

讓我感到驚訝的是,很少有人會查詢關于他們將要使用的工具的限制。幸好,MongoDB的開發人員發布了一篇MongoDB所有限制的博客,你可以提前了解相關信息,避免在使用過程中難堪。

  • 主從復制不會確保高可用性

盡管已經不建議被使用了,不過MongoDB還是提供了另外一種復制策略,即主從復制。它解決了12個節點限制問題,不過卻產生了新的問題:如果需要改變集群的主節點,那么你必須得手工完成,感到驚訝?看看這個鏈接吧。

  • 通過復制集實現的數據復制效果非常棒,不過也有限制

MongoDB中數據復制的復制集策略非常棒,很容易配置并且使用起來確實不錯。但如果集群的節點有12個以上,那么你就會遇到問題。MongoDB中的復制集有12個節點的限制,這里是問題的描述,你可以追蹤這個問題看看是否已經被解決了。

結論

        Gridfs最適合大文件存儲 ,特別是視頻,音頻,大型圖片超過16MB大小的文件。小型文件也可以存儲,不過需要付出2次查詢代價(metadata與file content) [Tip#18 50 Tips and Tricks for MongoDB Developers]。不要修改存儲文件的內容,而是更新文件元數據如版本,或上傳新版本的文件,刪除老版本的文件。對于大量文件存儲時,需要多個數據節點,復制,數據分片等。別基于nginx訪問圖片文件,瀏覽器沒有緩存。 從互聯網存儲圖片案例來看,圖片大都是jpg, png與縮略圖文件,分存式文件系統(DFS)會是更好的解決方案。

資源:

GridFS官方
Building MongoDB applications with Binary Files Using GridFS



希望對您軟件開發有幫助。 其它您可能感興趣的文章:
能力素質模型咨詢工具(Part1)
企業應用之性能實時度量系統演變
云計算參考架構幾例
智能移動導游解決方案簡介
人力資源管理系統的演化

如有想了解更多軟件,系統 IT,企業信息化 資訊,請關注我的微信訂閱號:

MegadotnetMicroMsg_thumb1_thumb1_thu[1]


作者:Petter Liu
出處:http://www.49028c.com/wintersun/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
該文章也同時發布在我的獨立博客中-Petter Liu Blog。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲自拍中文字幕| 精品激情国产视频| 国产偷国产偷亚洲清高网站| 欧美黑人性猛交| 国产精品视频一区国模私拍| 国产精品99久久久久久白浆小说| 亚洲人成亚洲人成在线观看| 久久亚洲成人精品| 91精品国产高清久久久久久| 久久久99久久精品女同性| 欧美日韩性视频在线| 自拍偷拍亚洲精品| 日韩中文字幕在线观看| 亚洲奶大毛多的老太婆| 奇米影视亚洲狠狠色| 91色琪琪电影亚洲精品久久| 欧美视频在线免费| 国产精品久久久久久亚洲调教| 国产精品第二页| 狠狠色狠狠色综合日日小说| 91成人在线视频| 国产精品成人va在线观看| 日韩国产高清视频在线| 日韩精品欧美激情| 久久久av电影| 97成人在线视频| 亚洲人成电影网站色…| 欧美午夜激情在线| 亚洲高清av在线| 亚洲高清免费观看高清完整版| 色偷偷av一区二区三区乱| 日韩精品小视频| 国产专区欧美专区| 伊人久久久久久久久久久| 国产精品高潮呻吟久久av无限| 欧美一级视频免费在线观看| 中文字幕在线视频日韩| 久久精品视频中文字幕| 成人欧美一区二区三区在线| 国产精品第三页| 亚洲精品福利在线| 欧美一级大胆视频| 亚洲午夜国产成人av电影男同| 欧美精品在线视频观看| 国产亚洲精品美女久久久| 成人国内精品久久久久一区| 欧美寡妇偷汉性猛交| 久久久亚洲影院你懂的| 国产精品午夜视频| 亚洲精品99久久久久中文字幕| 欧美大胆a视频| 久久久精品一区二区三区| 久久精品99久久香蕉国产色戒| 国产精品香蕉av| 欧美体内谢she精2性欧美| 亚洲丁香久久久| 国产在线视频欧美| 日韩欧美在线中文字幕| 中文字幕成人在线| 欧美极品少妇xxxxⅹ裸体艺术| www.日韩.com| 国产精品小说在线| 日韩av观看网址| 精品高清美女精品国产区| 久久av在线播放| 97免费中文视频在线观看| 成人97在线观看视频| 亚洲天堂日韩电影| 亚洲精品欧美一区二区三区| 国产美女精彩久久| 97视频在线观看视频免费视频| 中文字幕日韩在线播放| 国产成人a亚洲精品| 中文字幕久久久av一区| 中文欧美日本在线资源| 欧美激情久久久| 狠狠躁夜夜躁人人躁婷婷91| 国产美女精品免费电影| 中文字幕亚洲欧美一区二区三区| 亚洲精品一区二区网址| 91精品国产91| 久久久久久69| 亚洲成av人影院在线观看| 国产精品久久激情| 欧美性受xxxx白人性爽| 欧美在线一级va免费观看| 久久久久久久久久久成人| 日韩精品在线视频美女| 91精品国产91久久久久久吃药| 91香蕉亚洲精品| 亚洲色图日韩av| 欧美日韩福利电影| 日韩麻豆第一页| 久久久亚洲欧洲日产国码aⅴ| 国产精品久久久久久久久久尿| 国产欧美日韩综合精品| 精品免费在线视频| 国内精品在线一区| 81精品国产乱码久久久久久| 国产成人一区三区| 久久男人的天堂| 国产成人精品久久二区二区91| 日韩成人在线观看| 亚洲欧美www| 久久精品一本久久99精品| 亚洲国产三级网| 最近中文字幕mv在线一区二区三区四区| 欧美激情网站在线观看| 欧美日韩亚洲成人| 国产精品成熟老女人| 久久久国产精品一区| 精品免费在线视频| 久久国产精品久久久久| 81精品国产乱码久久久久久| 三级精品视频久久久久| 久久影视电视剧凤归四时歌| 国产精品极品美女在线观看免费| 久久久这里只有精品视频| 一区二区三区回区在观看免费视频| 欧美日韩国产va另类| 91国产精品视频在线| 国产精品91久久久| 久久视频精品在线| 九九热这里只有精品6| 欧美视频免费在线观看| 亚洲精品aⅴ中文字幕乱码| 海角国产乱辈乱精品视频| 欧美亚洲在线观看| 色婷婷**av毛片一区| 国产精品视频26uuu| 国产精品一区专区欧美日韩| 国产在线久久久| 亚洲国产精品久久久久秋霞不卡| 亚洲va国产va天堂va久久| 欧美国产视频日韩| 欧美激情视频三区| 国产精品美女久久久久av超清| 欧美精品久久久久久久久| 亚洲国产婷婷香蕉久久久久久| 日韩国产精品一区| 国产91网红主播在线观看| 欧美性xxxx极品hd欧美风情| 日韩在线视频网站| 国产精品国内视频| 欧美孕妇与黑人孕交| 久久精品成人动漫| 欧美成人在线影院| 伊人久久精品视频| 欧美日韩福利在线观看| 中文字幕无线精品亚洲乱码一区| 亚洲电影第1页| 精品久久久久久久久久久| 亚洲精品理论电影| 国产999视频| 久久久久久久成人| 国产精品99久久99久久久二8| 亚洲人成电影在线| 国产99视频在线观看| 亚洲精品美女在线观看播放| 668精品在线视频| 国产日韩欧美成人| 国产精品视频色| 国产精品久久久久久久久久久久久久| 国产视频精品xxxx|