设为首页收藏本站

追梦Linux

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 743|回复: 0

MongoDB nginx-gridfs文件存储方案

[复制链接]

482

主题

485

帖子

16万

积分

CEO

Rank: 9Rank: 9Rank: 9

积分
168047

最佳新人活跃会员热心会员推广达人宣传达人灌水之王突出贡献优秀版主荣誉管理论坛元老

QQ
发表于 2017-7-6 18:12:25 | 显示全部楼层 |阅读模式
一、介绍   
nginx-gridfs是一个 Nginx 的扩展模块,用于支持直接访问 MongoDB 的 GridFS 文件系统上的文件并提供 HTTP 访问。
nginx-gridfs源码:https://github.com/barakav/gridfs-nginx-plugin
mongo-c-driver源码:https://github.com/eagleas/mongo-c-driver   
    在各类系统应用服务端开发中,我们经常会遇到文件存储的问题。 常见的磁盘文件系统,DBMS传统文件流存储。今天我们看一下基于NoSQL数据库MongoDb的存储方案。笔者环境 以CentOS 6.5,MongoDb 2.6.3,  Nginx-1.4.7 为例,您需要了解Linux常用命令。

先来看一下MongoDb的内部文件结构

    1、MongoDB在数据存储上按命名空间来划分,一个collection是一个命名空间,一个索引也是一个命名空间
    2、同一个命名空间的数据被分成很多个Extent,Extent之间使用双向链表连接
    3、在每一个Extent中,保存了具体每一行的数据,这些数据也是通过双向链接连接的
    4、每一行数据存储空间不仅包括数据占用空间,还可能包含一部分附加空间,这使得在数据update变大后可以不移动位置
    5、索引以BTree结构实现
然后是GridFs的结构

GridFS在数据库中,默认使用fs.chunks和fs.files来存储文件。
其中fs.files集合存放文件的信息,fs.chunks存放文件数据。
一个fs.files集合中的一条记录内容如下,即一个file的信息如下:
[Bash shell] 纯文本查看 复制代码
{ 
"_id" : ObjectId("4f4608844f9b855c6c35e298"),       //唯一id,可以是用户自定义的类型
"filename" : "CPU.txt",      //文件名
"length" : 778,      //文件长度
"chunkSize" : 262144,    //chunk的大小
"uploadDate" : ISODate("2017-07-03T09:36:04.593Z"), //上传时间
"md5" : "e2c789b036cfb3b848ae39a24e795ca6",      //文件的md5值
"contentType" : "text/plain"     //文件的MIME类型
"meta" : null    //文件的其它信息,默认是没有”meta”这个key,用户可以自己定义为任意BSON对象
}
对应的fs.chunks中的chunk如下:
[Bash shell] 纯文本查看 复制代码
{ 
"_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”对象的内容,还原成原来的文件。
二、安装配置
1、安装依赖并下载所需包
[Bash shell] 纯文本查看 复制代码
yum -y install vim wget make  pcre-devel openssl-devel zlib-devel gcc gcc-c++
wget [url=http://nginx.org/download/nginx-1.13.2.tar.gz]http://nginx.org/download/nginx-1.13.2.tar.gz[/url]
wget [url=https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.4.5.tgz]https://fastdl.mongodb.org/linux ... 64-rhel62-3.4.5.tgz[/url]
git clone [url=https://github.com/mdirolf/nginx-gridfs.git]https://github.com/mdirolf/nginx-gridfs.git[/url]
2、安装配置mongodb
安装mongodb
[Bash shell] 纯文本查看 复制代码
tar xf  mongodb-linux-x86_64-rhel62-3.4.5.tgz
mv mongodb-linux-x86_64-rhel62-3.4.5 /usr/local/mongodb
cd /usr/local/mongodb
mkdir etc data logs

配置mongodb
[Bash shell] 纯文本查看 复制代码
#start as daemon and need authentication
port=27017
fork=true
dbpath=/usr/local/mongodb/data/
pidfilepath=/usr/local/mongodb/data/mongodb.pid
logpath=/usr/local/mongodb/logs/mongodb.log
logappend=true
rest=true
#master=true
#bind_ip=0.0.0.0
#auth=true
shardsvr=true
maxConns=600

oplogSize=2048

启动mongodb
[Bash shell] 纯文本查看 复制代码
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/etc/mongodb.conf
3、安装配置nginx
[Bash shell] 纯文本查看 复制代码
tar xf nginx-1.13.2.tar.gz
cd nginx-1.13.2
./configure --with-openssl=/usr/include/openssl --add-module=/root/nginx-gridfs/
make && make install

配置nginx,server下添加以下
[Bash shell] 纯文本查看 复制代码
        location /img1/ {
               gridfs testdb
        #        root_collection=pics
               field=filename
                type=string;
                mongo 127.0.0.1:27018;
        }
        location /files1/ {
                gridfs testdb1
                #field=_id
                field=filename
                #type=objectid;
                type=string;
                mongo 127.0.0.1:27018;
        }[/size][/font][/backcolor][/color][/align][align=left][color=rgb(35, 35, 35)][backcolor=rgb(255, 255, 255)][font=Verdana, Arial, helvetica, sans-seriff][size=14px]

这里我们的mongo服务在本机,也可以写IP。
如果不指定 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
注意我们没有指定collection,默认是fs
PS:这里多说一句,我看github上说是支持user/pass的,但是实际测试发现不行,是否跟当前nginx版本有关有待研究。
https://ruby-china.org/topics/2102
启动nginx
[Bash shell] 纯文本查看 复制代码
/usr/local/nginx/sbin/nginx
简单测试上传
[Bash shell] 纯文本查看 复制代码
上传图片
mongofiles put  0002.png  --local /img/0002.png  --host 127.0.0.1 --port 27018 --db testdb --type png

上传附件
mongofiles put  devops.pdf   --local /img/devops.pdf  --host 127.0.0.1 --port 27018 --db testdb1 --type pdf

最后我们在浏览器访问,如果看到图片和附件就OK了
附数据库主从同步 原理图:
上图是MongoDB采用Replica Sets模式的同步流程
  • 红色箭头表示写操作写到Primary上,然后异步同步到多个Secondary上
  • 蓝色箭头表示读操作可以从Primary或Secondary任意一个上读
  • 各个Primary与Secondary之间一直保持心跳同步检测,用于判断Replica Sets的状态

  • MongoDB的分片是指定一个分片key来进行,数据按范围分成不同的chunk,每个chunk的大小有限制
  • 有多个分片节点保存这些chunk,每个节点保存一部分的chunk
  • 每一个分片节点都是一个Replica Sets,这样保证数据的安全性
  • 当一个chunk超过其限制的最大体积时,会分裂成两个小的chunk
  • 当chunk在分片节点中分布不均衡时,会引发chunk迁移操作


上面讲了分片的标准,下面是具体在分片时的几种节点角色
  • 客户端访问路由节点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) 。不要修改存储文件的内容,而是更新文件元数据如版本,或上传新版本的文件,删除老版本的文件。对于大量文件存储时,需要多个数据节点,复制,数据分片等。别基于nginx访问图片文件,浏览器没有缓存。 从互联网存储图片案例来看,图片大都是jpg, png与缩略图文件,分存式文件系统(DFS)会是更好的解决方案。

参考文献:


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

QQ|小黑屋|手机版|Archiver|追梦Linux ( 粤ICP备14096197号  点击这里给我发消息

GMT+8, 2019-1-23 01:00 , Processed in 0.300597 second(s), 35 queries .

Powered by 追梦Linux! X3.3 Licensed

© 2015-2017 追梦Linux!.

快速回复 返回顶部 返回列表