mongodb分片+副本集总览

因为51cto的编辑不太好用,这是有道上的文档http://note.youdao.com/noteshare?id=aedd53c99b4a97aebbe9af136104113a前端

在 MongoDB 中,有两种数据冗余方式,一种 是 Master-Slave 模式(主从复制),一种是 Replica Sets 模式(副本集)。
三种集群:

一、 主从集群(目前已经不推荐使用)
二、 副本集
三、 分片集群
分片集群是三种模式中最复杂的一种,副本集其实一种互为主从的关系,可理解为主主。
副本集指将数据复制,多份保存,不一样服务器保存同一份数据,在出现故障时自动切换。对应的是数据冗余、备份、镜像、读写分离、高可用性等关键词;
而分片则指为处理大量数据,将数据分开存储,不一样服务器保存不一样的数据,它们的数据总和即为整个数据集。追求的是高性能。
在生产环境中,一般是这两种技术结合使用,分片+副本集。node

下面的内容将介绍mongodb副本集、分片集群、拆分gridfs上传的文件、利用nginx-gridfs结合mongodb分片集群,而且在浏览器显示拆分的文件,四大类。
第1章 Mongodb副本集集群介绍
1.1 简介
为何介绍副本集,由于在3.6版本后,分片集群搭建和副本集一块儿使用。
副本集实现了mongodb集群的高可用。
副本集是一种在多台机器同步数据的进程,副本集体提供了数据冗余,扩展了数据可用性。在多台服务器保存数据能够避免由于一台服务器致使的数据丢失。
也能够从硬件故障或服务中断解脱出来,利用额外的数据副本,能够从一台机器致力于灾难恢复或者备份。
在一些场景,可使用副本集来扩展读性能,客户端有能力发送读写操做给不一样的服务器。也能够在不一样的数据中心获取不一样的副原本扩展分布式应用的能力。
mongodb副本集是一组拥有相同数据的mongodb实例,主mongodb接受全部的写操做,全部的其余实例能够接受主实例的操做以保持数据同步。
主实例接受客户的写操做,副本集只能有一个主实例,由于为了维持数据一致性,只有一个实例可写,主实例的日志保存在oplog。
1.2 原理
MongoDB 的副本集不一样于以往的主从模式。
在集群Master故障的时候,副本集能够自动投票,选举出新的Master,并引导其他的Slave服务器链接新的Master,而这个过程对于应用是透明的。能够说MongoDB的副本集是自带故障转移功能的主从复制。
相对于传统主从模式的优点
传统的主从模式,须要手工指定集群中的 Master。若是 Master 发生故障,通常都是人工介入,指定新的 Master。 这个过程对于应用通常不是透明的,每每伴随着应用重
新修改配置文件,重启应用服务器等。而 MongoDB 副本集,集群中的任何节点均可能成为 Master 节点。一旦 Master 节点故障,则会在其他节点中选举出一个新的 Master 节点。 并引导剩余节点链接到新的 Master 节点。这个过程对于应用是透明的。
mongodb分片+副本集总览mysql

一个副本集即为服务于同一数据集的多个MongoDB实例,其中一个为主节点,其他的都为从节点。主节点上可以完成读写操做,从节点仅能用于读操做。主节点须要记录全部改变数据库状态的操做,这些记录保存在oplog中,这个文件存储在local数据库,各个从节点经过此oplog来复制数据并应用于本地,保持本地的数据与主节点的一致。oplog具备幂等性,即不管执行几回其结果一致,这个比mysql的二进制日志更好用。集群中的各节点还会经过传递心跳信息来检测各自的健康情况。
当主节点故障时,多个从节点会触发一次新的选举操做,并选举其中的一个成为新的主节点(一般谁的优先级更高,谁就是新的主节点),心跳信息默认每2秒传递一次。客户端链接到副本集后,不关心具体哪一台机器是否挂掉。主服务器负责整个副本集的读写,副本集按期同步数据备份。一旦主节点挂掉,副本节点就会选举一个新的主服务器。这一切对于应用服务器不须要关心。
mongodb分片+副本集总览
mongodb分片+副本集总览linux

副本集中的副本节点在主节点挂掉后经过心跳机制检测到后,就会在集群内发起主节点的选举机制,自动选举出一位新的主服务器。
mongodb分片+副本集总览nginx

1.3 节点
副本集拥有三种节点:主节点、从节点、仲裁节点
1)主节点负责处理客户端请求,读、写数据, 记录在其上全部操做的oplog;
2)从节点按期轮询主节点获取这些操做,而后对本身的数据副本执行这些操做,从而保证从节点的数据与主节点一致。默认状况下,从节点不支持外部读取,但能够设置;副本集的机制在于主节点出现故障的时候,余下的节点会选举出一个新的主节点,从而保证系统能够正常运行。
3)仲裁节点不复制数据,仅参与投票。因为它没有访问的压力,比较空闲,所以不容易出故障。因为副本集出现故障的时候,存活的节点必须大于副本集节点总数的一半,不然没法选举主节点,或者主节点会自动降级为从节点,整个副本集变为只读。所以,增长一个不容易出故障的仲裁节点,能够增长有效选票,下降整个副本集不可用的风险。仲裁节点可多于一个。也就是说只参与投票,不接收复制的数据,也不能成为活跃节点。
注意:
官方推荐MongoDB副本节点最少为3台,建议副本集成员为奇数,最多12个副本节点,最多7个节点参与选举。限制副本节点的数量,主要是由于一个集群中过多的副本节点,增长了复制的成本,反而拖累了集群的总体性能。太多的副本节点参与选举,也会增长选举的时间。而官方建议奇数的节点,是为了不脑裂 的发生。
1.4 工做流程
在MongoDB副本集中,主节点负责处理客户端的读写请求,备份节点则负责映射主节点的数据。备份节点的工做原理过程能够大体描述为,备份节点按期轮询主节点上的数据操做,从而保证跟主节点的数据同步。至于主节点上的全部数据库状态改变的操做,都会存放在一张特定的系统表中。备份节点则是根据这些数据进行本身的数据更新。
1.4.1 Oplog
上面提到的数据库状态改变的操做,称为 oplog(operationlog,主节点操做记录。oplog 存储在local数据库的"oplog.rs"表中。副本集中备份节点异步的从主节点同步oplog,而后从新执行它记录的操做,以此达到了数据同步的做用。
关于 oplog 有几个注意的地方:
1)oplog 只记录改变数据库状态的操做
2)存储在oplog 中的操做并非和主节点执行的操做彻底同样,例如"$inc"操做就会转化为"$set"操做
3)oplog 存储在固定集合中(capped collection),当oplog的数量超过oplogSize,新的操做就会覆盖旧的操做
1.4.2 数据同步
在副本集中,有两种数据同步的方式:
1)initial sync(初始化):这个过程发生在当副本集中建立一个新的数据库或其中某个节点刚从宕机中恢复,或者向副本集中添加新的成员的时候,默认的,副本集中的节点会从离它最近的节点复制oplog来同步数据,这个最近的节点能够是primary也能够是拥有最新oplog副本的 secondary节点。该操做通常会从新初始化备份节点,开销较大。
2)replication(复制):在初始化后这个操做会一直持续的进行着,以保持各个secondary节点之间的数据同步。
当遇到没法同步的问题时,只能使用如下两种方式进行initial sync了
1)第一种方式就是中止该节点,而后删除目录中的文件,从新启动该节点。这样,这个节点就会执行 initial sync
注意:经过这种方式,sync的时间是根据数据量大小的,若是数据量过大,sync时间就会很长同时会有不少网络传输,可能会影响其余节点的工做
2)第二种方式,中止该节点,而后删除目录中的文件,找一个比较新的节点,而后把该节点目录中的文件拷贝到要 sync 的节点目录中
1.5 副本集选举过程
Mongodb副本集选举采用的是Bully算法,这是一种协调者(主节点)竞选算法,主要思想是集群的每一个成员均可以声明它是主节点并通知其余节点。别的节点能够选择接受这个声称或是拒绝并进入主节点竞争,被其余全部节点接受的节点才能成为主节点。
节点按照一些属性来判断谁应该胜出,这个属性能够是一个静态ID,也能够是更新的度量像最近一次事务ID(最新的节点会胜出)
1.5.1 副本集的选举过程
1)获得每一个服务器节点的最后操做时间戳。每一个 mongodb 都有 oplog 机制会记录本机的操做,方便和主服 务器进行对比数据是否同步还能够用于错误恢复。
2)若是集群中大部分服务器 down 机了,保留活着的节点都为 secondary 状态并中止,不选举了。
3)若是集群中选举出来的主节点或者全部从节点最后一次同步时间看起来很旧了,中止选举等待人来操做。
4)若是上面都没有问题就选择最后操做时间戳最新(保证数据是最新的)的服务器节点做为主节点。
1.5.2 副本集选举的特色
选举还有个前提条件,参与选举的节点数量必须大于副本集总节点数量的一半(建议副本集成员为奇数。最多12个副本节点,最多7个节点参与选举)若是已经小于一半了全部节点保持只读状态。集合中的成员必定要有大部分红员(即超过一半数量)是保持正常在线状态,3个成员的副本集,须要至少2个从属节点是正常状态。
若是一个从属节点挂掉,那么当主节点down掉 产生故障切换时,因为副本集中只有一个节点是正常的,少于一半,则选举失败。
4个成员的副本集,则须要3个成员是正常状态(先关闭一个从属节点,而后再关闭主节点,产生故障切换,此时副本集中只有2个节点正常,则没法成功选举出新主节点)。
1.6 MongoDB 同步延迟问题
当你的用户抱怨修改过的信息不改变,删除掉的数据还在显示,你掐指一算,估计是数据库主从不一样步。与其余提供数据同步的数据库同样,MongoDB 也会遇到同步延迟的问题,在MongoDB的Replica Sets模式中,同步延迟也常常是困扰使用者的一个大问题。c++

1.6.1 什么是同步延迟
首先,要出现同步延迟,必然是在有数据同步的场合,在 MongoDB 中,有两种数据冗余方式,一种是Master-Slave 模式,一种是Replica Sets模式。这两个模式本质上都是在一个节点上执行写操做, 另外的节点将主节点上的写操做同步到本身这边再进行执行。在MongoDB中,全部写操做都会产生 oplog,oplog是每修改一条数据都会生成一条,若是你采用一个批量 update 命令更新了 N 多条数据, 那么,oplog会有不少条,而不是一条。因此同步延迟就是写操做在主节点上执行完后,从节点尚未把 oplog拿过来再执行一次。而这个写操做的量越大,主节点与从节点的差异也就越大,同步延迟也就越大了。
1.6.2 同步延迟带来的问题
首先,同步操做一般有两个效果,一是读写分离,将读操做放到从节点上来执行,从而减小主节点的 压力。对于大多数场景来讲,读多写少是基本特性,因此这一点是颇有用的。
另外一个做用是数据备份, 同一个写操做除了在主节点执行以外,在从节点上也一样执行,这样咱们就有多份一样的数据,一旦 主节点的数据由于各类天灾人祸没法恢复的时候,咱们至少还有从节点能够依赖。可是主从延迟问题 可能会对上面两个效果都产生很差的影响。
若是主从延迟过大,主节点上会有不少数据更改没有同步到从节点上。这时候若是主节点故障,就有 两种状况:
1)主节点故障而且没法恢复,若是应用上又没法忍受这部分数据的丢失,咱们就得想各类办法将这部 数据更改找回来,再写入到从节点中去。能够想象,即便是有可能,那这也绝对是一件很是恶心的活。
2)主节点可以恢复,可是须要花的时间比较长,这种状况若是应用能忍受,咱们能够直接让从节点提 供服务,只是对用户来讲,有一段时间的数据丢失了,而若是应用不能接受数据的不一致,那么就只能下线整个业务,等主节点恢复后再提供服务了。
若是你只有一个从节点,当主从延迟过大时,因为主节点只保存最近的一部分 oplog,可能会致使从 节点青黄不接,不得不进行 resync 操做,全量从主节点同步数据。
带来的问题是:当从节点全量同步的时候,实际只有主节点保存了完整的数据,这时候若是主节点故障,极可能所有数据都丢掉了。
1.7 副本集搭建过程
1.7.1 环境准备git

Centos7  64位系统
Mongodb 4.0版本
三台虚拟机
192.168.1.182:27017
192.168.1.186:27017
192.168.1.122:27017

安装包(三台同样)
下载地址github

https://www.mongodb.com/download-center?jmp=nav#community
https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.2.tgz

解压到/usr/local/mongodb/目录下
1.7.2 搭建过程
一、 建立数据目录(三台建立)
mkdir /data/mongodb/27017/ -p
二、 建立配置文件(三台配置同样)算法

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/27017/mongodb.log
storage:
  dbPath: /data/mongodb/27017/
  journal:
    enabled: true
processManagement:
  fork: true
net:
  port: 27017
  bindIp: 0.0.0.0

#副本集标志,三台name要同样,才能加入到副本集。sql

replication:
  replSetName: data

三、 启动
启动三台实例
/usr/local/mongodb/bin/mongod -f /data/mongodb/27017/mongodb.conf
四、 初始化
登陆任意一台实例,进行初始化sql语句,三大步sql。

config = { _id:"data", members:[
  {_id:0,host:"192.168.1.182:27017"},
  {_id:1,host:"192.168.1.186:27017"},
  {_id:2,host:"192.168.1.122:27017"}]
}

进入到admin,进行初始化
use admin
初始化须要时间
rs.initiate( config )
查看状态
rs.status() #副本集状态,一个primary,其它SECONDARY。primary是主,只有primary能写入。
注意:-id,为副本集配置文件里面的name一致。
1.7.3 优先级设置
primary的选举依赖于各个实例的优先权重,默认权重都是1
复本集的主挑选权重最高的,权重同样的没法控制谁为主
设置各个实例的优先权重,挑选本身想要的实例为主,只有primary能够更改权重配置

conf = rs.config()   #获取副本集的配置,默认权重都是1
conf.members[0].priority = 10 #索引号从0开始,每次递增1,相似数组
conf.members[1].priority = 5
conf.members[2].priority = 2
rs.reconfig(conf)   #更新mongodb副本集的配置,优先权重最高的提高为primary。

关闭启动后也为主
至此,副本集搭建介绍完成

第2章 Mongodb分片集群介绍
Sharding cluster是一种能够水平扩展的模式,在数据量很大时特给力,实际大规模应用通常会采用这种架构去构建。sharding分片很好的解决了单台服务器磁盘空间、内存、cpu等硬件资源的限制问题,把数据水平拆分出去,下降单节点的访问压力。每一个分片都是一个独立的数据库,全部的分片组合起来构成一个逻辑上的完整的数据库。所以,分片机制下降了每一个分片的数据操做量及须要存储的数据量,达到多台服务器来应对不断增长的负载和数据的效果。
2.1 Sharding分区概念
将数据分散到不一样的机器上,不须要功能强大的服务器就能够存储更多的数据和处理更大的负载。
2.1.1 分片的基本思想
将集合切成小块,这些块分散到若干片里,每一个片只负责总数据的一部分。经过一个名为mongos的路由进程进行操做,mongos知道数据和片的对应关系(经过配置服务器)。大部分使用场景都是解决磁盘空间的问题,对于写入有可能会变差(+++里面的说明+++),查 询则尽可能避免跨分片查询。
2.1.2 使用分片的时机
1)机器的磁盘不够用了。使用分片解决磁盘空间的问题。
2)单个mongod已经不能知足写数据的性能要求。经过分片让写压力分散到各个分片上面,使用分片服务器自身的资源。
3)想把大量数据放到内存里提升性能。和上面同样,经过分片使用分片服务器自身的资源。

2.1.3 三种角色
1)分片服务器(Shard Server)
mongod实例,用于存储实际的数据块,实际生产环境中一个 shard server 角色可由几台机器组个一个 relica set 承担,防止主机单点故障。
这是一个独立普通的mongod进程,保存数据信息。能够是一个副本集也能够是单独的一台服务器(生产环境都是副本集)。
2)配置服务器(Config Server)
mongod 实例,存储了整个 Cluster Metadata,其中包括 chunk 信息。
这是一个独立的mongod进程,保存集群和分片的元数据,即各分片包含了哪些数据的信息。最早开始创建,启用日志功能。像启动普通的 mongod 同样启动。
配置服务器,指定configsvr 选项。不须要太多的空间和资源,配置服务器的 1KB 空间至关于真是数据的 200MB。保存的只是数据的分布表。
3)路由服务器(Route Server)
mongos实例,前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用
起到一个路由的功能,供程序链接。自己不保存数据,在启动时从配置服务器加载集群信息,开启 mongos 进程须要知道配置服务器的地址,指定configdb选项。
2.1.4 片键的意义
一个好的片键对分片相当重要。片键必须是一个索引,经过sh.shardCollection 加会自动建立索引。一个自增的片键对写入和数据均匀分布就不是很好, 由于自增的片键总会在一个分片上写入,后续达到某个阀值可能会写到别的分片。可是按照片键查询会很是高效。随机片键对数据的均匀分布效果很好。注意尽可能避免在多个分片上进行查询。
在全部分片上查询,mongos 会对结果进行归并排序

mongodb分片+副本集总览
mongodb分片+副本集总览

2.1.5 分片的原理
分片,是指将数据拆分,将其分散到不一样的机器上。这样的好处就是,不须要功能强大的大型计算机也能够存储更多的数据,处理更大的负载。mongoDB 的分片,是将collection 的数据进行分割,而后将不一样的部分分别存储到不一样的机器上。当 collection 所占空间过大时,咱们须要增长一台新的机器,分片会自动将 collection 的数据分发到新的机器上。
2.1.6 分片集群的构造
mongodb分片+副本集总览
2.2 分片集群的搭建
2.2.1 环境准备
Centos7 64位系统
Mongodb 4.0版本
三台虚拟机

##三台路由服务器
192.168.1.182:20000
192.168.1.186:20000
192.168.1.122:20000
##三台配置服务器
192.168.1.182:21000
192.168.1.186:21000
192.168.1.122:21000
##九个分片数据服务器(测试复用三台),三组分片数据,各组为副本集。
192.168.1.182:27001
192.168.1.186:27001
192.168.1.122:27001
192.168.1.182:27002
192.168.1.186:27002
192.168.1.122:27002
192.168.1.182:27003
192.168.1.186:27003
192.168.1.122:27003

###建立数据目录

#三台服务器,建立路由配置目录
mkdir /data/mongodb/20000 –p
#三台服务器,建立配置服务器目录
mkdir /data/mongodb/21000 –p
#三台服务器,建立shard目录
mkdir /data/mongodb/27001 –p
mkdir /data/mongodb/27002 –p
mkdir /data/mongodb/27003 –p

安装包
三台服务下载安装包,解压到/usr/local/mongodb目录

https://www.mongodb.com/download-center?jmp=nav#community
https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.2.tgz

解压到/usr/local/mongodb/目录下
2.2.2 配置角色搭建(configsvr)
一、编辑文件vim /usr/local/mongodb/conf/config.conf,三台服务器配置同样。

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/21000/mongodb.log
storage:
  dbPath: /data/mongodb/21000/
  journal:
    enabled: true
processManagement:
  fork: true
net:
  port: 21000
  bindIp: 127.0.0.1
replication:
  replSetName: conf
sharding:
  clusterRole: configsvr

二、启动跟单例的启动方式一致,都是使用mongod
三、配置角色副本集搭建,配置角色也是副本集,达到高可用

config = { _id:"conf ", 
  configsvr: true,
  members:[
    {_id:0,host:"192.168.1.182:21000"},
    {_id:1,host:"192.168.1.186:21000"},
    {_id:2,host:"192.168.1.122:21000"}
  ]
}
rs.initiate(config)
rs.status() #查看状态

2.2.3 路由角色搭建(mongos)
一、 编辑配置文件vim /usr/local/mongodb/conf/mongos.conf,三台同样配置,配置多个router,任何一个都能正常的获取数据

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/20000/mongodb.log
processManagement:
  fork: true
net:
  port: 20000
  bindIp: 0.0.0.0
sharding:
  configDB: config/192.168.1.182:21000,192.168.1.186:21000,192.168.1.122:21000

##文件最后指定,配置角色的ip+端口。
二、 启动
/usr/local/mongodb/bin/mongos -f /usr/local/mongodb/conf/mongos.conf
#路由服务器的启动和其余角色不同。
2.2.4 数据角色搭建(shard)
三个shard,共有三个副本集。
##shard1
一、 编辑配置文件vim /usr/local/mongodb/conf/shard1.conf,三台shard1,配置同样。

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/27001/mongodb.log
storage:
  dbPath: /data/mongodb/27001/
  journal:
    enabled: true
processManagement:
  fork: true
net:
  port: 27001
  bindIp: 0.0.0.0
replication:
  replSetName: data1
#name三台一致,副本集。不一样的shard名称不一样,如:data二、data3
sharding:
  clusterRole: shardsvr
二、  启动

三、 配置副本集

config = { _id:"data1", 
  members:[
    {_id:0,host:"192.168.1.182:27001"},
    {_id:1,host:"192.168.1.186:27001"},
    {_id:2,host:"192.168.1.122:27001"}
  ]
}
#初始化
rs.initiate(config)
rs.status() #查看状态
至此搭建完成。

2.3 验证
2.3.1 分片集群添加数据角色

#链接路由角色
sh.addShard("data1/192.168.1.182:27001,192.168.1.186:27001,192.168.1.122:27001");
sh.addShard("data2/192.168.1.182:27002,192.168.1.186:27002,192.168.1.122:27002");
sh.addShard("data3/192.168.1.182:27003,192.168.1.186:27003,192.168.1.122:27003");
sh.status()

2.3.2 分片策略设置
默认添加数据没有分片存储,操做都是在路由角色里面
针对某个数据库的某个表使用hash分片存储,分片存储就会同一个colloection分配两个数据角色

use admin
db.runCommand( { enablesharding :"malin"});
db.runCommand( { shardcollection : "malin.myuser",key : {_id: "hashed"} } )

2.3.3 插入数据进行分片

use malin
for(i=1; i<=500;i++){
  db.myuser.insert( {name:'mytest'+i, age:i} )
}

查看三个shard是否有数据。
第3章 Mongodb gridfs介绍
GridFS是用于存储和检索超过 BSON -文档大小限制为16 MB的文件的规范。

GridFS不是将文件存储在单个文档中,而是将文件分红多个部分或块[1],并将每一个块存储为单独的文档。默认状况下,GridFS使用默认的块大小255 kB; 也就是说,GridFS将文件分红255 kB的块,但最后一个块除外。最后一个块只有必要的大小。一样,不大于块大小的文件只有最终的块,只使用所需的空间和一些额外的元数据。
GridFS使用两个集合来存储文件。一个集合存储文件块(chunks),另外一个存储文件元数据(files)。
GridFS不只可用于存储超过16 MB的文件,还可用于存储您想要访问的任何文件,而无需将整个文件加载到内存中。
3.1 使用时机
一、 若是文件系统限制目录中的文件数,则可使用GridFS根据须要存储任意数量的文件。
二、 若是要从大型文件的各个部分访问信息而无需将整个文件加载到内存中,可使用GridFS调用文件的各个部分,而无需将整个文件读入内存。
三、 若是要保持文件和元数据在多个系统和工具中自动同步和部署,可使用GridFS。使用地理位置分散的副本集时,MongoDB能够自动将文件及其元数据分发到多个 mongod实例和工具中。
3.2 Gridfs集合
chunks存储二进制块。默认是fs.chunks
#字段

{ 
  “  _ id ” : < ObjectId > ,
  “files_id”  : < ObjectId > ,
  “n”  : < num > ,
  “data”  : < binary > 
}

files存储文件的元数据。默认是fs.files
#字段
{
"_id" : <ObjectId>,
"length" : <num>,
"chunkSize" : <num>,
"uploadDate" : <timestamp>,
"md5" : <hash>,
"filename" : <string>,
"contentType" : <string>,
"aliases" : <string array>,
"metadata" : <any>,
}

3.3 拆分GridFS
3.3.1 拆分chunks
对chunks集合进行分片,使用files_id字段,利用哈希进行分片
3.3.2 拆分files
对files集合进行分片,使用_id字段,利用哈希进行分片
3.4 实例
一、配置分片策略

#进入到路由服务器
use admin
#指定拆分的数据库test
db.runCommand( { enablesharding :"test"});
#指定拆分的files,test数据库中的test-file.files集合,利用_id字段
db.runCommand( { shardcollection : "test.test-file.files",key : {_id: "hashed"} } )
#指定拆分的chunks,test数据库中的test.test-file.chunks集合,利用files_id,字段
db.runCommand( { shardcollection : "test.test-file.chunks",key : {files_id: "hashed"}})

二、 上传文件到test库中的test-file集合
命令行

mongofiles -d test1 -h 127.0.0.1 --port 20000 --prefix test-file put 1553.png
-d指定数据库
-h主机
--port端口(路由角色)
--prefix 指定集合
Put 上传

第4章 Nginx GridFS介绍
mongodb分片已经搭建完成,利用nginx的GridFS模块,实现nginx直接链接到mongodb数据库读取文件、图片。
4.1 下载nginx
一、安装 nginx 须要的依赖
yum install -y zlib zlib-devel gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel
注意:编译nginx过程当中,如在出现问题,自行安装依赖。
二、下载nginx
wget -c https://nginx.org/download/nginx-1.12.1.tar.gz
tar -zxvf nginx-1.12.1.tar.gz -C /usr/local/nginx
4.2 下载nginx-gridfs模块
nginx经过该模块和mongodb的gridfs进行整合
wget -c https://github.com/mdirolf/nginx-gridfs/archive/v0.8.tar.gz -O nginx-gridfs-0.8.tar.gz
tar -xzvf ./nginx-gridfs-0.8.tar.gz
4.3 下载nginx的mongodb驱动
将这个驱动下的全部移动到nginx-gridfs模块目录下的mongo-c-driver目录,为了后期编译
wget https://github.com/mongodb/mongo-c-driver/archive/v0.3.1.tar.gz
tar -zxvf v0.3.1.tar.gz
cd /root/mongo-c-driver-0.3.1
#将驱动下的全部移动到nginx-gridfs目录下的mongo-c-driver目录下。
mv ./* /root/nginx-gridfs-0.8/mongo-c-driver/
[root@hadoop-namenode mongo-c-driver]# ll
total 36
-rw-rw-r-- 1 root root 11358 May 13 2011 APACHE-2.0.txt
drwxrwxr-x 2 root root 40 May 13 2011 buildscripts
drwxrwxr-x 2 root root 41 May 13 2011 docs
-rw-rw-r-- 1 root root 10760 May 13 2011 doxygenConfig
-rw-rw-r-- 1 root root 363 May 13 2011 HISTORY.md
-rw-rw-r-- 1 root root 3024 May 13 2011 README.md
-rw-rw-r-- 1 root root 4090 May 13 2011 SConstruct
drwxrwxr-x 2 root root 185 May 13 2011 src
drwxrwxr-x 2 root root 282 May 13 2011 test
4.4 编译安装
#进入到nginx包目录下

cd nginx-1.12.0  
#开始编译,--add-module=/root/nginx-gridfs-0.8。这个目录就是nginx-gridfs模块的位置。
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx/ --with-http_v2_module --with-http_ssl_module --with-http_sub_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --add-module=/root/nginx-gridfs-0.8/
make && make install

4.5 问题处理
一、在make && make install的时候报错:
ngx_http_gridfs_module.c:684:16: 错误:变量‘chunksize’被设定但未被使用
处理方法:进入nginx包目录 vi nginx-1.12.0/objs/Makefile修改一个小错误,把第3行的-Werror错误去掉。
二、not exist /root/nginx-gridfs-0.8/mongo-c-driver/src/*.h,表示nginx的mongodb驱动没有安装。
处理方法:安装驱动,下载nginx的mongodb驱动。
至此nginx和nginx-gridfs模块编译成功,下面是配置文件的修改。
4.6 nginx-gridfs配置文件
#进入安装好的nginx配置文件conf目录下

server{
        listen       80;
        server_name  192.168.60.235;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        location /pics/ {
        gridfs  test
        field=_id
        type=objectid;
         mongo  192.168.xx.2x7:27017;
       }
     }

4.7 配置文件参数详解
gridfs:nginx识别插件的关键字
edusns: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 路由地址(集群中)
4.8 测试
一、上传文件到mongodb,而后进行浏览器测试。
#命令行mongodb上传文件
mongofiles put 1234.jpg --local ~/1234.jpg --host 172.0.0.1 --port 27017 --db testdb --type jpg
二、浏览器访问
ip/pics/1234.jpg
#nginx地址
第5章 总结
5.1 分片集群搭建
5.1.1 Config角色
配置文件(三台都配置)

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/21000/mongodb.log
storage:
  dbPath: /data/mongodb/21000/
  journal:
    enabled: true
processManagement:
  fork: true
net:
  port: 21000
  bindIp: 127.0.0.1
replication:
  replSetName: conf
sharding:
  clusterRole: configsvr
#只需修改端口便可,三台一致。

配置副本集
启动进入到任意一台实例进行配置

config = { _id:"conf ", 
  configsvr: true,
  members:[
    {_id:0,host:"192.168.1.182:21000"},
    {_id:1,host:"192.168.1.186:21000"},
    {_id:2,host:"192.168.1.122:21000"}
  ]
}
rs.initiate(config)
rs.status() #查看状态
#注意:_id为副本集名称

5.1.2 mongos角色
配置文件(三台同样配置文件)

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/20000/mongodb.log
processManagement:
  fork: true
net:
  port: 20000
  bindIp: 0.0.0.0
sharding:
  configDB: config/192.168.1.182:21000,192.168.1.186:21000,192.168.1.122:21000
#指定配置角色位置

5.1.3 shard角色
配置文件(九个实例,三个为一组副本集),只需修改端口和副本集名称

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/27001/mongodb.log
storage:
  dbPath: /data/mongodb/27001/
  journal:
    enabled: true
processManagement:
  fork: true
net:
  port: 27001
  bindIp: 0.0.0.0
replication:
  replSetName: data1
#name三台一致,副本集。不一样的shard名称不一样,如:data二、data3
sharding:
  clusterRole: shardsvr
#配置副本集
启动,进入到任意一台分片实例,进行副本集配置。
config = { _id:"data1", 
  members:[
    {_id:0,host:"192.168.1.182:27001"},
    {_id:1,host:"192.168.1.186:27001"},
    {_id:2,host:"192.168.1.122:27001"}
  ]
}
rs.initiate(config)
rs.status() #查看状态
#注意:_id为副本集名称

5.1.4 将数据角色添加到分片集群中
进入到路由角色实例

sh.addShard("data1/192.168.1.182:27001,192.168.1.186:27001,192.168.1.122:27001");
sh.addShard("data2/192.168.1.182:27002,192.168.1.186:27002,192.168.1.122:27002");
sh.addShard("data3/192.168.1.182:27003,192.168.1.186:27003,192.168.1.122:27003");
sh.status()
#三个shard分片。

5.1.5 拆分Gridfs上传的文件
#进入到路由服务器
use admin
#指定拆分的数据库test
db.runCommand( { enablesharding :"test"});
#指定拆分的files,test数据库中的test-file.files集合,利用_id字段
db.runCommand( { shardcollection : "test.test-file.files",key : {_id: "hashed"} } )
#指定拆分的chunks,test数据库中的test.test-file.chunks集合,利用files_id,字段
db.runCommand( { shardcollection : "test.test-file.chunks",key : {files_id: "hashed"}})
#命令行上传测试
mongofiles -d test1 -h 127.0.0.1 --port 20000 --prefix test-file put 1553.png
5.2 Nginx-gridfs搭建
5.2.1 下载nginx包及依赖
yum install -y zlib zlib-devel gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel
wget -c https://nginx.org/download/nginx-1.12.1.tar.gz
tar -zxvf nginx-1.12.1.tar.gz -C /usr/local/nginx
5.2.2 下载nginx-gridfs模块
wget -c https://github.com/mdirolf/nginx-gridfs/archive/v0.8.tar.gz -O nginx-gridfs-0.8.tar.gz
tar -xzvf ./nginx-gridfs-0.8.tar.gz
5.2.3 下载nginx的mongodb驱动,并移动到nginx-gridfs模块下
wget https://github.com/mongodb/mongo-c-driver/archive/v0.3.1.tar.gz
tar -zxvf v0.3.1.tar.gz
cd /root/mongo-c-driver-0.3.1
mv ./* /root/nginx-gridfs-0.8/mongo-c-driver/
5.2.4 编译安装nginx
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx/ --with-http_v2_module --with-http_ssl_module --with-http_sub_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --add-module=/root/nginx-gridfs-0.8/
5.2.5 配置文件

server{
        listen       80;
        server_name  192.168.60.235;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        location /pics/ {
        gridfs  test
        field=_id
        type=objectid;
         mongo  192.168.xx.2x7:27017;
       }
     }

5.2.6 命令行测试。上传文件mongofiles put 1234.jpg --local ~/1234.jpg --host 172.0.0.1 --port 27017 --db testdb --type jpg

相关文章
相关标签/搜索