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#/