NoSQL(三)_MongoDB

部署环境

Name Version
CentOS 7 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
NoSQL  
MongoDB mongodb-org.x86_64 0:3.4.16-1.el7

mongodb介绍

官网www.mongodb.com, 当前最新版3.4

C++编写,基于分布式的,属于NoSQL的一种在NoSQL中是最像关系型数据库的

MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档、数组及文档数组。关于JSON http://www.w3school.com.cn/json/index.asp

因为基于分布式,所以很容易扩展

MongoDB安装

epel自带的mongodb版本为2.6,我们需要安装3.4版本

官方安装文档https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/

简单来说:就是创建一个新的mongo的epel源,再用yum安装最新的3.4版本

进入yum源目录# cd /etc/yum.repos.d
​
创建新文件,添加如下内容# vim mongo.repo
[mongodb-org-3.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc
​
搜索yum列表下是否出现3.4版本的源# yum list |grep mongo
Repository base is listed more than once in the configuration
Repository updates is listed more than once in the configuration
Repository extras is listed more than once in the configuration
Repository centosplus is listed more than once in the configuration
Repository epel is listed more than once in the configuration
Repository epel-debuginfo is listed more than once in the configuration
Repository epel-source is listed more than once in the configuration
almas-mongolian-title-fonts.noarch       1.0-4.el7                     epel     
collectd-write_mongodb.x86_64            5.8.0-4.el7                   epel     
google-noto-sans-mongolian-fonts.noarch  20141117-5.el7                base     
libmongo-client.x86_64                   0.1.8-1.el7                   epel     
libmongo-client-devel.x86_64             0.1.8-1.el7                   epel     
libmongo-client-doc.x86_64               0.1.8-1.el7                   epel     
mongo-c-driver.x86_64                    1.3.6-1.el7                   epel     
mongo-c-driver-devel.x86_64              1.3.6-1.el7                   epel     
mongo-c-driver-libs.x86_64               1.3.6-1.el7                   epel     
mongo-cxx-driver.x86_64                  1.0.5-1.el7                   epel     
mongo-cxx-driver-devel.x86_64            1.0.5-1.el7                   epel     
mongodb.x86_64                           2.6.12-6.el7                  epel     
mongodb-org.x86_64                       3.4.16-1.el7                  mongodb-org-3.4
mongodb-org-mongos.x86_64                3.4.16-1.el7                  mongodb-org-3.4
mongodb-org-server.x86_64                3.4.16-1.el7                  mongodb-org-3.4
mongodb-org-shell.x86_64                 3.4.16-1.el7                  mongodb-org-3.4
mongodb-org-tools.x86_64                 3.4.16-1.el7                  mongodb-org-3.4
mongodb-server.x86_64                    2.6.12-6.el7                  epel     
mongodb-test.x86_64                      2.6.12-6.el7                  epel     
nodejs-mongodb.noarch                    1.4.7-1.el7                   epel     
php-mongodb.noarch                       1.0.4-1.el7                   epel     
php-pecl-mongo.x86_64                    1.6.14-1.el7                  epel     
php-pecl-mongodb.x86_64                  1.1.10-1.el7                  epel     
poco-mongodb.x86_64                      1.6.1-3.el7                   epel     
python-mongoengine.noarch                0.8.8-1.el7                   epel     
python-pymongo.x86_64                    2.5.2-4.el7                   epel     
python-pymongo-gridfs.x86_64             2.5.2-4.el7                   epel     
syslog-ng-mongodb.x86_64                 3.5.6-3.el7                   epel
​
yum安装# yum install -y mongodb-org

MongoDB连接

systemctl start mongod //启动服务 在本机可以直接运行命令mongo进入到mongodb shell中 如果mongodb监听端口并不是默认的27017,则在连接的时候需要加--port 选项,例如 mongo --port 27018 连接远程mongodb,需要加--host,例如 mongo --host 127.0.0.1 如果设置了验证,则在连接的时候需要带用户名和密码 mongo -uusername -ppasswd --authenticationDatabase db //这个和MySQL挺像

MongoDB用户管理

use admin//需要切换到admin库db.createUser( { user: "admin", customData: {description: "superuser"}, pwd: "admin122", roles: [ { role: "root", db: "admin" } ] } )user指定用户,customData为说明字段,可以省略,pwd为密码,roles指定用户的角色,db指定库名 use admin //切换到admin库db.system.users.find() //列出所有用户,需要切换到admin库show users //查看当前库下所有的用户db.dropUser('admin') //删除用户若要用户生效,还需要编辑启动脚本vim /usr/lib/systemd/system/mongod.service,在OPTIONS=后面增--auth重启服务systemctl restart mongodmongo -u "admin" -p "admin122" --authenticationDatabase "admin"

use db1 db.createUser( { user: "test1", pwd: "123aaa", roles: [ { role: "readWrite", db: "db1" }, {role: "read", db: "db2" } ] } ) test1用户对db1库读写,对db2库只读。 之所以先use db1,表示用户在 db1 库中创建,就一定要db1库验证身份,即用户的信息跟随随数据库。比如上述 test1虽然有 db2 库的读取权限,但是一定要先在db1库进行身份验证,直接访问会提示验证失败。 use db2 db.auth("test1", "123aaa")

MongoDB用户角色

  • Read:允许用户读取指定数据库

  • readWrite:允许用户读写指定数据库

  • dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile

  • userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户

  • clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。

  • readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限

  • readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限

  • userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限

  • dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。

  • root:只在admin数据库中可用。超级账号,超级权限

MongoDB库管理

  • db.version() //查看版本

  • use userdb //如果库存在就切换,不存在就创建

  • show dbs //查看库,此时userdb并没有出现,这是因为该库是空的,还没有任何集合,只需要创建一个集合就能看到了

  • db.createCollection('clo1') //创建集合clo1,在当前库下面创建

  • db.dropDatabase() //删除当前库,要想删除某个库,必须切换到那个库下

  • db.stats() //查看当前库的信息

  • db.serverStatus() //查看mongodb服务器的状态

MongoDB创建集合

  • db.createCollection("mycol", { capped : true, size : 6142800, max : 10000 } ) //语法:db.createCollection(name,options)

  • name就是集合的名字,options可选,用来配置集合的参数,参数如下

  • capped true/false (可选)如果为true,则启用封顶集合。封顶集合是固定大小的集合,当它达到其最大大小,会自动覆盖最早的条目。如果指定true,则也需要指定尺寸参数。

  • autoindexID true/false (可选)如果为true,自动创建索引_id字段的默认值是false。

  • size (可选)指定最大大小字节封顶集合。如果封顶如果是 true,那么你还需要指定这个字段。单位B

  • max (可选)指定封顶集合允许在文件的最大数量。

MongoDB数据管理

  • show collections //查看集合,或者使用show tables

  • db.Account.insert({AccountID:1,UserName:"123",password:"123456"}) //如果集合不存在,直接插入数据,则mongodb会自动创建集合

  • db.Account.update({AccountID:1},{"$set":{"Age":20}}) //更新

  • db.Account.find() //查看所有文档

  • db.Account.find({AccountID:1}) //根据条件查询

  • db.Account.remove({AccountID:1}) //根据条件删除

  • db.Account.drop() //删除所有文档,即删除集合

  • use dbname //先进入对应的库

  • db.printCollectionStats() // 然后查看集合状态

PHP连接MongoDB-mongodb.so

 cd /usr/local/src/
 git clone https://github.com/mongodb/mongo-php-driver
 cd mongo-php-driver
 git submodule update --init
 /usr/local/php/bin/phpize
 ./configure --with-php-config=/usr/local/php/bin/php-config
 make && make install
 vi /usr/local/php/etc/php.ini //增加 extension = mongodb.so
 /usr/local/php/bin/php -m
 
  大家还可以到pecl官网上下载mongodb的扩展源码包
 cd /usr/local/src/
 wget https://pecl.php.net/get/mongodb-1.3.0.tgz 
 tar zxvf mongodb-1.3.0.tgz
 cd mongodb-1.3.0
 /usr/local/php/bin/phpize
 ./configure --with-php-config=/usr/local/php/bin/php-config
 make && make install
 vi /usr/local/php/etc/php.ini //增加 extension = mongodb.so
 /usr/local/php/bin/php -m
​

PHP连接MongoDB – mongo.so

 到pecl官网上下载mongo的扩展源码包
 cd /usr/local/src/
 wget https://pecl.php.net/get/mongo-1.6.16.tgz 
 tar zxvf mongodb-1.6.16.tgz
 cd mongodb-1.6.16
 /usr/local/php/bin/phpize
 ./configure --with-php-config=/usr/local/php/bin/php-config
 make && make install
 vi /usr/local/php/etc/php.ini //增加 extension = mongo.so
 /usr/local/php/bin/php -m
​

测试mongo扩展

 参考文档 https://docs.mongodb.com/ecosystem/drivers/php/
 http://www.runoob.com/mongodb/mongodb-php.html
 vi /usr/local/apache2/htdocs/1.php //增加•<?php
$m = new MongoClient(); // 连接
$db = $m->test; // 获取名称为 "test" 的数据库
$collection = $db->createCollection("runoob");
echo "集合创建成功";
?>
 curl  localhost/1.php
​

MongoDB副本集

早期版本使用master-slave,一主一从和MySQL类似,但slave在此架构中为只读,当主库宕机后,从库不能自动切换为主 目前已经淘汰master-slave模式,改为副本集,这种模式下有一个主(primary),和多个从(secondary),只读。支持给它们设置权重,当主宕掉后,权重最高的从切换为主 在此架构中还可以建立一个仲裁(arbiter)的角色,它只负责裁决,而不存储数据 再此架构中读写数据都是在主上,要想实现负载均衡的目的需要手动指定读库的目标server

MongoDB副本集搭建

三台机器: 192.168.133.130(primary) 192.168.133.132(secondary) 192.168.133.133(secondary) 编辑三台机器的配置文件,更改或增加: replication://把此行前面的#删除 ##oplog大小 oplogSizeMB: 20//前面有两个空格 ##复制集名称 replSetName: aminglinux//前面有两个空格 分别重启三台机器

 连接主,在主上运行命令mongo
>use admin
>config={_id:"aminglinux",members:[{_id:0,host:"192.168.133.130:27017"},{_id:1,host:"192.168.133.132:27017"},{_id:2,host:"192.168.133.133:27017"}]}
>rs.initiate(config)
 rs.status() //查看状态
 如果两个从上的状态为"stateStr" : "STARTUP", 则需要进行如下操作
> var config={_id:"aminglinux",members:[{_id:0,host:"192.168.133.130:27017"},{_id:1,host:"192.168.133.132:27017"},{_id:2,host:"192.168.133.133:27017"}]}
 >rs.reconfig(config)
 此时再次查看rs.status()会发现从的状态变为SECONDARY
​

MongoDB副本集测试

 主上建库,建集合
 >use mydb
 >db.acc.insert({AccountID:1,UserName:"123",password:"123456"})
 >show dbs
 从上查看
 >show dbs   
 若出现错误Error: listDatabases failed:{ "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" },需要执行
 >rs.slaveok() 
​

副本集更改权重模拟主宕机

 默认三台机器权重都为1,如果任何一个权重设置为比其他的高,则该台机器马上切换为primary角色,所以我们预设三台机器的权重分别为:130:3,132:2,133:1
 在主上执行
 cfg = rs.conf()
 cfg.members[0].priority = 3
 cfg.members[1].priority = 2
 cfg.members[2].priority = 1
 rs.reconfig(cfg)
 这样的话,第二个节点将会成为候选主节点。
 主上执行 iptables -I INPUT -p tcp --dport 27017 -j DROP
​

MongoDB分片介绍

  • 分片就是将数据库进行拆分,将大型集合分隔到不同服务器上。比如,本来100G的数据,可以分割成10份存储到10台服务器上,这样每台机器只有10G的数据。

  • 通过一个mongos的进程(路由)实现分片后的数据存储与访问,也就是说mongos是整个分片架构的核心,对客户端而言是不知道是否有分片的,客户端只需要把读写操作转达给mongos即可。

  • 虽然分片会把数据分隔到很多台服务器上,但是每一个节点都是需要有一个备用角色的,这样能保证数据的高可用。

  • 当系统需要更多空间或者资源的时候,分片可以让我们按需方便扩展,只需要把mongodb服务的机器加入到分片集群中即可

MongoDB分片相关概念

mongos: 数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的shard服务器上。在生产环境通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。 config server: 配置服务器,存储所有数据库元信息(路由、分片)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。mongos第一次启动或者关掉重启就会从 config server 加载配置信息,以后如果配置服务器信息变化会通知到所有的 mongos 更新自己的状态,这样 mongos 就能继续准确路由。在生产环境通常有多个 config server 配置服务器,因为它存储了分片路由的元数据,防止数据丢失! shard: 存储了一个集合部分数据的MongoDB实例,每个分片是单独的mongodb服务或者副本集,在生产环境中,所有的分片都应该是副本集。

分片搭建——服务器规划

  • 三台机器 A B C

  • A搭建:mongos、config server、副本集1主节点、副本集2仲裁、副本集3从节点

  • B搭建:mongos、config server、副本集1从节点、副本集2主节点、副本集3仲裁

  • C搭建:mongos、config server、副本集1仲裁、副本集2从节点、副本集3主节点

  • 端口分配:mongos 20000、config 21000、副本集1 27001、副本集2 27002、副本集3 27003

  • 三台机器全部关闭firewalld服务和selinux,或者增加对应端口的规则

分片搭建——创建目录

分别在三台机器上创建各个角色所需要的目录 mkdir -p /data/mongodb/mongos/log mkdir -p /data/mongodb/config/{data,log} mkdir -p /data/mongodb/shard1/{data,log} mkdir -p /data/mongodb/shard2/{data,log} mkdir -p /data/mongodb/shard3/{data,log}

分片搭建—— config server 配置

mongodb3.4版本以后需要对config server创建副本集
 添加配置文件(三台机器都操作)
 mkdir /etc/mongod/
 vim /etc/mongod/config.conf //加入如下内容
pidfilepath = /var/run/mongodb/configsrv.pid
dbpath = /data/mongodb/config/data
logpath = /data/mongodb/config/log/congigsrv.log
logappend = true
bind_ip = 0.0.0.0
port = 21000
fork = true
configsvr = true #declare this is a config db of a cluster;
replSet=configs #副本集名称
maxConns=20000 #设置最大连接数
启动三台机器的config server
 mongod -f /etc/mongod/config.conf  //三台机器都要操作
 登录任意一台机器的21000端口,初始化副本集
 mongo --port 21000
 config = { _id: "configs", members: [ {_id : 0, host : "192.168.133.130:21000"},{_id : 1, host : "192.168.133.132:21000"},{_id : 2, host : "192.168.133.133:21000"}] }
 rs.initiate(config)
{ "ok" : 1 }
​

分片搭建——分片配置

添加配置文件(三台机器都操作)
 vim /etc/mongod/shard1.conf //加入如下内容
pidfilepath = /var/run/mongodb/shard1.pid
dbpath = /data/mongodb/shard1/data
logpath = /data/mongodb/shard1/log/shard1.log
logappend = true
bind_ip = 0.0.0.0
port = 27001
fork = true
httpinterface=true #打开web监控
rest=true
replSet=shard1 #副本集名称
shardsvr = true #declare this is a shard db of a cluster;
maxConns=20000 #设置最大连接数
​
添加配置文件(三台机器都操作)
 vim /etc/mongod/shard2.conf //加入如下内容
pidfilepath = /var/run/mongodb/shard2.pid
dbpath = /data/mongodb/shard2/data
logpath = /data/mongodb/shard2/log/shard2.log
logappend = true
bind_ip = 0.0.0.0
port = 27002
fork = true
httpinterface=true #打开web监控
rest=true
replSet=shard2 #副本集名称
shardsvr = true #declare this is a shard db of a cluster;
maxConns=20000 #设置最大连接数
​
添加配置文件(三台机器都操作)
 vim /etc/mongod/shard3.conf //加入如下内容
pidfilepath = /var/run/mongodb/shard3.pid
dbpath = /data/mongodb/shard3/data
logpath = /data/mongodb/shard3/log/shard3.log
logappend = true
bind_ip = 0.0.0.0
port = 27003
fork = true
httpinterface=true #打开web监控
rest=true
replSet=shard3 #副本集名称
shardsvr = true #declare this is a shard db of a cluster;
maxConns=20000 #设置最大连接数
启动shard1
 mongod -f /etc/mongod/shard1.conf //三台机器都要操作
 登录130或者132任何一台机器的27001端口初始化副本集,133之所以不行,是因为shard1我们把133这台机器的27001端口作为了仲裁节点
 mongo --port 27001
 use admin
 config = { _id: "shard1", members: [ {_id : 0, host : "192.168.133.130:27001"}, {_id: 1,host : "192.168.133.132:27001"},{_id : 2, host : "192.168.133.133:27001",arbiterOnly:true}] }
 rs.initiate(config)
 
  启动shard2
 mongod -f /etc/mongod/shard2.conf //三台机器都要操作
 登录132或者133任何一台机器的27002端口初始化副本集,130之所以不行,是因为shard2我们把130这台机器的27002端口作为了仲裁节点
 mongo --port 27002
 use admin
 config = { _id: "shard2", members: [ {_id : 0, host : "192.168.133.130:27002" ,arbiterOnly:true},{_id : 1, host : "192.168.133.132:27002"},{_id : 2, host : "192.168.133.133:27002"}] }
 rs.initiate(config)
 
 启动shard3
 mongod -f /etc/mongod/shard3.conf //三台机器都要操作
 登录130或者133任何一台机器的27003端口初始化副本集,132之所以不行,是因为shard3我们把132这台机器的27003端口作为了仲裁节点
 mongo --port 27003
 use admin
 config = { _id: "shard3", members: [ {_id : 0, host : "192.168.133.130:27003"},  {_id : 1, host : "192.168.133.132:27003", arbiterOnly:true}, {_id : 2, host : "192.168.133.133:27003"}] }
 rs.initiate(config)

分片搭建——配置路由器服务器

 添加配置文件(三台机器都操作)
 vim /etc/mongod/mongos.conf //加入如下内容
pidfilepath = /var/run/mongodb/mongos.pid
logpath = /data/mongodb/mongos/log/mongos.log
logappend = true
bind_ip = 0.0.0.0
port = 20000
fork = true
configdb = configs/192.168.133.130:21000, 192.168.133.132:21000, 192.168.133.133:21000 #监听的配置服务器,只能有1个或者3个,configs为配置服务器的副本集名字
maxConns=20000 #设置最大连接数
启动mongos服务,注意命令,前面都是mongod,这里是mongos
 mongos -f /etc/mongod/mongos.conf
​

分片搭建——启用分片

 登录任何一台20000端口
 mongo --port 20000  
 把所有分片和路由器串联
sh.addShard("shard1/192.168.133.130:27001,192.168.133.132:27001,192.168.133.133:27001")
sh.addShard("shard2/192.168.133.130:27002,192.168.133.132:27002,192.168.133.133:27002")
sh.addShard("shard3/192.168.133.130:27003,192.168.133.132:27003,192.168.133.133:27003")
 查看集群状态
 sh.status()
​

分片搭建——测试

 登录任何一台20000端口
 mongo --port 20000  
 use admin
 db.runCommand({ enablesharding : "testdb"}) 或者
 sh.enableSharding("testdb") //指定要分片的数据库
 db.runCommand( { shardcollection : "testdb.table1",key : {id: 1} } ) 或者
 sh.shardCollection("testdb.table1",{"id":1} ) //#指定数据库里需要分片的集合和片键
 use  testdb
 for (var i = 1; i <= 10000; i++) db.table1.save({id:i,"test1":"testval1"})//插入测试数据
 db.table1.stats()//查看table1状态
​

MongoDB备份

 备份指定库
 mongodump --host 127.0.0.1 --port 20000  -d mydb -o /tmp/mongobak
 它会在/tmp/目录下面生成一个mydb的目录
 备份所有库
 mongodump --host 127.0.0.1 --port 20000 -o /tmp/mongobak/alldatabase
 指定备份集合
 mongodump --host 127.0.0.1 --port 20000 -d mydb -c c1 -o /tmp/mongobak/
 它依然会生成mydb目录,再在这目录下面生成两个文件
 导出集合为json文件
 mongoexport --host 127.0.0.1 --port 20000 -d mydb -c c1 -o /tmp/mydb2/1.json
​

MongoDB恢复

恢复所有库
 mongorestore -h 127.0.0.1 --port 20000 --drop dir/ //其中dir是备份所有库的目录名字,其中--drop可选,意思是当恢复之前先把之前的数据删除,不建议使用
 恢复指定库
 mongorestore -d mydb dir/  //-d跟要恢复的库名字,dir就是该库备份时所在的目录
 恢复集合
mongorestore -d mydb -c testc dir/mydb/testc.bson // -c后面跟要恢复的集合名字,dir是备份mydb库时生成文件所在路径,这里是一个bson文件的路径
 导入集合
 mongoimport -d mydb -c testc --file /tmp/testc.json
​

扩展阅读:

MongoDB经典面试题集锦https://blog.csdn.net/u014726937/article/details/53764226

mongodb安全设置 http://www.mongoing.com/archives/631

mongodb执行js脚本 http://www.jianshu.com/p/6bd8934bd1ca

猜你喜欢

转载自blog.csdn.net/zhengyshan/article/details/82086354
今日推荐