第三十六课预习任务

1.mongodb介绍

2.mongodb安装

3.连接mongodb

4.mongodb用户管理

4.2 MongoDB用户角色

4.3 MongoDB库管理

5.mongodb创建集合、数据管理

6.php的mongodb扩展

7.php的mongo扩展

8.mongodb副本集介绍

9.mongodb副本集搭建

10. mongodb副本集测试

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

11.mongodb分片介绍

13.MongoDB备份

MongoDB恢复



1.mongodb介绍

MongoDB是基于文档的存储的(而非表),是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。模式自由(schema-free),意味着对于存储在MongoDB数据库中的文件,我们不需要知道它的任何结构定义。如果需要的话,你完全可以把不同结构的文件存储在同一个数据库里。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

    Mongo主要解决的是海量数据的访问效率问题。因为Mongo主要是支持海量数据存储的,所以Mongo还自带了一个出色的分布式文件系统GridFS,可以支持海量的数据存储。由于Mongo可以支持复杂的数据结构,而且带有强大的数据查询功能,因此非常受到欢迎。

1.2、适用场景

    1、网站数据:适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。

    2、缓存:由于性能很高,也适合作为信息基础设施的缓存层。在系统重启之后,搭建的持久化缓存可以避免下层的数据源过载。   

    3、大尺寸、低价值的数据:使用传统的关系数据库存储一些数据时可能会比较贵,在此之前,很多程序员往往会选择传统的文件进行存储。

    4、高伸缩性的场景:非常适合由数十或者数百台服务器组成的数据库。

    5、用于对象及JSON数据的存储:MongoDB的BSON数据格式非常适合文档格式化的存储及查询。

1.3 MongoDB和关系型数据库对比

2.mongodb安装

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


[root@knightlai02 ~]# cd /etc/yum.repos.d/
[root@knightlai02 yum.repos.d]# vim mongodb-org-3.4.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


[root@knightlai02 yum.repos.d]# yum install -y mongodb-org
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
epel/x86_64/metalink                                                     | 8.9 kB  00:00:00     
 * base: centos.01link.hk
 * epel: mirrors.ustc.edu.cn
 * extras: centos.01link.hk
 * updates: centos.01link.hk
........................................................................................



2.2 启动mongod

[root@knightlai02 yum.repos.d]# systemctl start mongod
[root@knightlai02 yum.repos.d]# ps aux |grep mongod
mongod    33450  0.6  3.9 972844 39592 ?        Sl   09:16   0:00 /usr/bin/mongod -f /etc/mongo.conf
root      33471  0.0  0.0 112704   960 pts/1    S+   09:17   0:00 grep --color=auto mongod
[root@knightlai02 yum.repos.d]# netstat -lnp |grep mongod
tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN      33450/mongod        
unix  2      [ ACC ]     STREAM     LISTENING     494210   33450/mongod         /tmp/mongodb-27017.sock

3.连接mongodb

  • 如果mongodb监听端口并不是默认的27017,则在连接的时候需要加--port 选项,
  • 例如  mongo --port 27018  
  • 连接远程mongodb,需要加--host,例如  mongo --host  127.0.0.1
  •  如果设置了验证,则在连接的时候需要带用户名和密码  mongo -uusername -ppasswd --authenticationDatabase db //这个和MySQL挺像
[root@knightlai02 ~]# mongo
MongoDB shell version v3.4.18
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.18
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
	http://docs.mongodb.org/
Questions? Try the support group
	http://groups.google.com/group/mongodb-user
Server has startup warnings: 
2018-10-28T09:16:08.502-0400 I CONTROL  [initandlisten] 
2018-10-28T09:16:08.502-0400 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-10-28T09:16:08.502-0400 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2018-10-28T09:16:08.502-0400 I CONTROL  [initandlisten] 
2018-10-28T09:16:08.503-0400 I CONTROL  [initandlisten] 
2018-10-28T09:16:08.503-0400 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2018-10-28T09:16:08.503-0400 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2018-10-28T09:16:08.503-0400 I CONTROL  [initandlisten] 
2018-10-28T09:16:08.503-0400 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2018-10-28T09:16:08.503-0400 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2018-10-28T09:16:08.503-0400 I CONTROL  [initandlisten] 
> 

4.mongodb用户管理

//切换到admin库
> use admin
switched to db admin
//创建一个用户:user指定用户,customData为说明字段,可以省略,pwd为密码,roles指定用户的角色,db指定库名 
> db.createUser( { user: "admin", customData: {description: "superuser"}, pwd: "admin122", roles: [ { role: "root", db: "admin" } ] } )
Successfully added user: {
	"user" : "admin",
	"customData" : {
		"description" : "superuser"
	},
	"roles" : [
		{
			"role" : "root",
			"db" : "admin"
		}
	]
}

use admin //切换到admin库
db.system.users.find()  //列出所有用户,需要切换到admin库
show users  //查看当前库下所有的用户
db.dropUser('admin') //删除用户


若要用户生效,还需要编辑启动脚本vim /usr/lib/systemd/system/mongod.service,在OPTIONS=后面增--auth
重启服务systemctl restart mongod
mongo -u "admin" -p "admin122" --authenticationDatabase "admin"

4.2 MongoDB用户角色

  • Read:允许用户读取指定数据库  
  • readWrite:允许用户读写指定数据库  
  • dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问
  • system.profile  userAdmin:允许用户向
  • system.users集合写入,可以找指定数据库里创建、删除和管理用户  
  • clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。  
  • readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限  
  • readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限  
  • userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限  
  • dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。  
  • root:只在admin数据库中可用。超级账号,超级权限

4.3 MongoDB库管理

  • db.version()  //查看版本  
  • use userdb  //如果库存在就切换,不存在就创建  
  • show dbs //查看库,此时userdb并没有出现,这是因为该库是空的,还没有任何集合,只需要创建一个集合就能看到了  db.createCollection('clo1') //创建集合clo1,在当前库下面创建  
  • db.dropDatabase() //删除当前库,要想删除某个库,必须切换到那个库下  
  • db.stats()  //查看当前库的信息  
  • db.serverStatus()   //查看mongodb服务器的状态

5.mongodb创建集合、数据管理

> db.createCollection("TT", { size : 6142800, max : 10000 } )
{ "ok" : 1 }

 //语法:db.createCollection(name,options)
 name就是集合的名字,options可选,用来配置集合的参数,参数如下

  •  capped true/false (可选)如果为true,则启用封顶集合。封顶集合是固定大小的集合,当它达到其最大大小,会自动覆盖最早    的条目。如果指定true,则也需要指定尺寸参数。
  •  autoindexID  true/false (可选)如果为true,自动创建索引_id字段的默认值是false。
  •  size (可选)指定最大大小字节封顶集合。如果封顶如果是 true,那么你还需要指定这个字段。单位B
  •  max (可选)指定封顶集合允许在文件的最大数量。
//查看集合,或者使用show  tables
> show collections
TT
system.users
system.version

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

//查找集合中的数据
>  db.Account.find()
{ "_id" : ObjectId("5bd5bbc4f0d6f1b379870358"), "AccountID" : 1, "UserName" : "123", "password" : "123456" }

  • db.Account.find({AccountID:1})   //根据条件查询  
  • db.Account.remove({AccountID:1})  //根据条件删除  
  • db.Account.drop() //删除所有文档,即删除集合  
  • use dbname  //先进入对应的库  
  • db.printCollectionStats()  // 然后查看集合状态

6.php的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  
  • //检查php加载模块是否有mongodb.so
  • /usr/local/php/bin/php -m

7.php的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

8.mongodb副本集介绍

副本集中数据同步过程Primary节点写入数据,Secondary通过读取Primary的oplog得到复制信息,开始复制数据并且将复制信息写入到自己的oplog。如果某个操作失败,则备份节点停止从当前数据源复制数据。如果某个备份节点由于某些原因挂掉了,当重新启动后,就会自动从oplog的最后一个操作开始同步,同步完成后,将信息写入自己的oplog,由于复制操作是先复制数据,复制完成后再写入oplog,有可能相同的操作会同步两份,不过MongoDB在设计之初就考虑到这个问题,将oplog的同一个操作执行多次,与执行一次的效果是一样的。简单的说就是:

当Primary节点完成数据操作后,Secondary会做出一系列的动作保证数据的同步:
1:检查自己local库的oplog.rs集合找出最近的时间戳。
2:检查Primary节点local库oplog.rs集合,找出大于此时间戳的记录。
3:将找到的记录插入到自己的oplog.rs集合中,并执行这些操作。

       副本集的同步和主从同步一样,都是异步同步的过程,不同的是副本集有个自动故障转移的功能。其原理是:slave端从primary端获取日志,然后在自己身上完全顺序的执行日志所记录的各种操作(该日志是不记录查询操作的),这个日志就是local数据 库中的oplog.rs表,默认在64位机器上这个表是比较大的,占磁盘大小的5%,oplog.rs的大小可以在启动参数中设 定:--oplogSize 1000,单位是M。

      注意:在副本集的环境中,要是所有的Secondary都宕机了,只剩下Primary。最后Primary会变成Secondary,不能提供服务。

9.mongodb副本集搭建

9.1 MongoDB副本集搭建

//编辑配置文件
[root@knightlai02 ~]# vim /etc/mongod.conf 
net:
  port: 27017
  bindIp: 127.0.0.1,192.168.139.132

replication:
  oplogSizeMB: 20
  replSetName: knightlai

//在主上面操作
> config={_id:"knightlai",members:[{_id:0,host:"192.168.139.132:27017"},{_id:1,host:"192.168.139.133:27017"}]}
{
	"_id" : "knightlai",
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.139.132:27017"
		},
		{
			"_id" : 1,
			"host" : "192.168.139.133:27017"
		}
	]
}
> rs.initiate(config)
{ "ok" : 1 }

//查看副本集状态
knightlai:OTHER> rs.status()
{
	"set" : "knightlai",
	"date" : ISODate("2018-10-28T14:32:07.554Z"),
	"myState" : 2,
	"term" : NumberLong(1),
	"syncingTo" : "",
	"syncSourceHost" : "",
	"syncSourceId" : -1,
	"heartbeatIntervalMillis" : NumberLong(2000),
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp(0, 0),
			"t" : NumberLong(-1)
		},
		"appliedOpTime" : {
			"ts" : Timestamp(1540737115, 1),
			"t" : NumberLong(-1)
		},
		"durableOpTime" : {
			"ts" : Timestamp(1540737115, 1),
			"t" : NumberLong(-1)
		}
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "192.168.139.132:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 120,
			"optime" : {
				"ts" : Timestamp(1540737115, 1),
				"t" : NumberLong(-1)
			},
			"optimeDate" : ISODate("2018-10-28T14:31:55Z"),
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "could not find member to sync from",
			"configVersion" : 1,
			"self" : true,
			"lastHeartbeatMessage" : ""
		},
		{
			"_id" : 1,
			"name" : "192.168.139.133:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 11,
			"optime" : {
				"ts" : Timestamp(1540737115, 1),
				"t" : NumberLong(-1)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1540737115, 1),
				"t" : NumberLong(-1)
			},
			"optimeDate" : ISODate("2018-10-28T14:31:55Z"),
			"optimeDurableDate" : ISODate("2018-10-28T14:31:55Z"),
			"lastHeartbeat" : ISODate("2018-10-28T14:32:05.799Z"),
			"lastHeartbeatRecv" : ISODate("2018-10-28T14:32:06.708Z"),
			"pingMs" : NumberLong(8),
			"lastHeartbeatMessage" : "",
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "",
			"configVersion" : 1
		}
	],
	"ok" : 1
}

10. mongodb副本集测试

//在主上操作,
knightlai:PRIMARY> use mydb
switched to db mydb
knightlai:PRIMARY> db.acc.insert({AccountID:1,UserName:"123",password:"123456"})
WriteResult({ "nInserted" : 1 })
knightlai:PRIMARY> show dbs
admin  0.000GB
local  0.000GB
mydb   0.000GB

//在从上操作
knightlai:SECONDARY> rs.slaveOk();

knightlai:SECONDARY> show dbs
admin  0.000GB
local  0.000GB
mydb   0.000GB

注意:如果出现以下错误只要执行 :knightlai:SECONDARY> rs.slaveOk();

  • knightlai:SECONDARY> show dbs
  • 2018-10-28T10:44:34.725-0400 E QUERY    [thread1] Error: listDatabases failed:{
  •     "ok" : 0,
  •     "errmsg" : "not master and slaveOk=false",
  •     "code" : 13435,
  •     "codeName" : "NotMasterNoSlaveOk"
  • } :
  • _getErrorWithCode@src/mongo/shell/utils.js:25:13
  • Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
  • shellHelper.show@src/mongo/shell/utils.js:814:19
  • shellHelper@src/mongo/shell/utils.js:704:15
  • @(shellhelp2):1:1
     

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

  • 在主上执行  cfg = rs.conf()  
  • cfg.members[0].priority = 3  
  • cfg.members[1].priority = 2  
  •  rs.reconfig(cfg)
knightlai:PRIMARY> cfg = rs.conf()
{
	"_id" : "knightlai",
	"version" : 3,
	"protocolVersion" : NumberLong(1),
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.139.132:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 2,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		},
		{
			"_id" : 1,
			"host" : "192.168.139.133:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 3,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		}
	],
	"settings" : {
		"chainingAllowed" : true,
		"heartbeatIntervalMillis" : 2000,
		"heartbeatTimeoutSecs" : 10,
		"electionTimeoutMillis" : 10000,
		"catchUpTimeoutMillis" : 60000,
		"getLastErrorModes" : {
			
		},
		"getLastErrorDefaults" : {
			"w" : 1,
			"wtimeout" : 0
		},
		"replicaSetId" : ObjectId("5bd5c85b9b98966a0ba3dafe")
	}
}

11.mongodb分片介绍

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

13.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

扩展链接

https://note.youdao.com/share/?token=0EED380D933E4F7ABA0C6BB4A3FCA4CD&gid=31981530#/

猜你喜欢

转载自blog.csdn.net/a1779078902/article/details/84230549