MongoDB简介
- MongoDB是由C++语言编写的,是一个基于分布式文件存储的
非关系型
开源数据库系统。其优势在于可以存放海量数据,具备强大的查询功能,不适用于数据缓存,在高负载的情况下,添加更多的节点,可以保证服务器性能 - MongoDB旨在为WEB应用提供可扩展的高性能数据存储解决方案
- MongoDB将数据存储为一个文档,数据结构由键值(key=>value)对,及
BSON
组成。MongoDB文档类似于JSON对象。字段值可以包含其他文档,数组及文档数组 - 2007年10月,MongoDB由10gen团队所开发。2009年2月首度推出
- MongoDB支持Unix、Linux、windows等系统平台
- 在许多场景下用于代替传统的关系型数据库或键/值存储方式,几乎可以实现类似关系型数据库单表查询的绝大部分功能,而且还支持对数据建立索引。是一个面向集合的,模式自由的文档型数据库
MongoDB特点
- MongoDB的提供了一个面向文档存储,操作起来比较简单和容易,且安装简单。
- mongodb支持:索引来实现更快的排序。
- MongoDB有更强的扩展性,如果负载的增加,可以夯布在计算机网络中的其他i点E这就是所谓的分片。
- Mongo支持丰富的查询表达式。查询指令使用ISON形式的标记,可轻易查询文档中内嵌的对象及数组。
- Mongodb使用updatel)命令可以实现替换完成的文档(数据)或者一些指定的数据字段。
- Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作,Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。
- GridrFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
- 也可以把函数的定义存储在服务端,下次直接调用即可。
- MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言
MongoDB结构和数据类型
MongoDB适用领域:网站数据、分布式场景、缓存屋、文档格式存储
逻辑结构
:- 文档(document):是mongodb核心概念也是逻辑存储的最小单元,相当于行
需要注意的是- 文档中的键值对是有序的
- 文档中的值可以使双引号里面的字符串,也可以是其他几种数据类型(甚至可以使整个嵌入的文档)
- MongoDB区分类型大小写
- MongoDB的文档不能有重复的键
- 集合(collection):多个文档组成集合,相当于表,但不同于表的是无固定结构
- 当一个文档插入时,集合就会被创建
- 数据库(database);多个集合组成数据席
- test:默认数据库,该数据库存储在data目录中,要显示它,需要向数据库插入一些数据
- admin:从权限的角度来看,这是root数据库;如果将一个用户添加到这个数据库,这个用户将自动继承所有数据库的权限
- local:这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
- config:当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息
- 文档(document):是mongodb核心概念也是逻辑存储的最小单元,相当于行
物理结构
:- .ns文件:每个表或索引对应一个命图空间,数据量增加,文件数量增多;
- 数据文件:存放数据的实体;
- 预分配空间机制:mongodb在当前数据文件的基础上,公预分配文件(用0进行填充),数据文件每次新生成的文件,大小是上个文件的两倍,这样可以保证数据文件的可用性;内存映射机制:MMAP机制会将所有的数据文件映射到虚拟内存,访问到此块数据时,会将其数据交换到物理内存,加快访问速度;
日志存储结构
:- 系统日志文件
- journal日志文件:用于mongodb崩溃恢复的保障
- oplog复制操作日志文件(相当于mysal的binary log文件)
- 慢查询日志:需要在配置文件profile-1开启慢查询与slowms-200指定记录的老秒数
数据类型
:- BSON 是Binary ISON,是二进制的格式,能将mongdb的所有文档表示为字节字符串.
- ISON是一种轻量级的数据交换格式,它基于JavaScript的一个子集.
BSON的数据类型
:null,代表空或者不存在;布尔,只有true和false;数字,64位浮点数:字符串,utf8字符串:数组,值或者列表可表示为数组对象,对象的数据BSON的特点
:优点:简单,简洁,容易理解、解析、记忆mongodb的数据库、集合、文档命名规则
:- 支持UTF8的绝大多数字符
- 不支持如$开头;\0空字符;特殊^.等
- 集合名不能以“system.”开头,这是为系统保留的前缀
- 下划线‘_’开头的键是保留的(非严格要求)
搭建MongoDB数据库应用
YUM安装
-
搭建安装所需yum源
vim /etc/yum.repos.d/mongodb-org.repo [mongodb-org] name=MongoDB Repository baseurl=http://mirrors.aliyun.com/mongodb/yum/redhat/7Server/mongodb-org/3.4/x86_64/ gpgcheck=0 enabled=1
-
yum安装
yum update
yum -y install -y mongodb-org
- 设置内核参数
echo 0 > /proc/sys/vm/zone_reclaim_mode #当某个节点可用内存不足时,系统会从其他节点分配内存。
echo never > /sys/kernel/mm/transparent_hugepage/enabled #关闭大页内存
echo never > /sys/kernel/mm/transparent_hugepage/defrag #关闭大页内存
vi /etc/rc.local( 永久)
echo 0 > /proc/sys/vm/zone_reclaim_mode
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
sh /etc/rc.local
- 启动
systemctl start mongod
systemctl enable mongod
[root@localhost ~]# curl http://localhost:27017
It looks like you are trying to access MongoDB over HTTP on the native driver port. #代表安装成功
YUM方式安装MongoDB,其配置文件默认为/etc/mongod.conf
[root@localhost system]# cat /etc/mongod.conf | grep -v ^\#
systemLog: 日志相关配置
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
storage: 数据文件存储相关
dbPath: /var/lib/mongo
journal:
enabled: true
processManagement: PID进程号相关
fork: true # fork and run in background
pidFilePath: /var/run/mongodb/mongod.pid # location of pidfile
net: 端口、IP等配置
port: 27017
bindIp: 192.168.137.21 # Listen to local interface only, comment to listen on all interfaces.
- 连接并访问MongoDB
mongo 初始状态下的连接命令
> show dbs
test 默认进入test库
启动MongoDB多实例
在单台服务器资源充分的情况下,可以使用多实例,以便充分使用服务器资源
具体步骤
cp -p /etc/mongod.conf /etc/mongod1.conf
mkdir /var/lib/mongo1
chmod 777 /var/lib/mongo1
touch /var/lib/mongodb/mongod1.log
chmod 777 /var/lib/mongodb/mongod1.log
vim /etc/mongod1.conf
path: /var/log/mongodb/mongod1.log
dbPath: /var/lib/mongo1
pidFilePath: /var/run/mongodb/mongod1.pid
逻辑结构:
库 database
- test :默认库 ,只有往里面插入数据,才会看到。
- admin:系统认证相关的库,存放用户名,密码等。
- local:系统本地库,存放日志相关。
MongoDB的常用术语及说明
SQL术语 | MongoDB术语 | 说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB不支持 | |
primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
MongoDB中基本操作
基本操作
操作 | 描述 |
---|---|
show dbs | 查看当前实例下的数据库列表 |
show users | 显示用户 |
use db_name | 切换当前数据库 |
db.help() | 显示数据库操作命令 |
show collections | 显示当前数据库中的集合 |
db.foo.help() | 显示集合操作命令,foo是当前数据库下的集合 |
db.foo.find() | 对当前数据库中foo集合进行数据查找 |
> use kgc 切换数据库
> db.mytable.insert({id:1,'name':'sary'}) 插入文档
> db.mytable.find() 查看文档
> db.mytable.findOne() 查看文档中匹配的信息
>db.mytable.update({id:1,"name":"sary"},{"name":"lisi",age:17}) 修改记录
> db.mytable.remove({"name":"lisi"}) 删除记录
> db.dropDatabase() 删除数据库
> cls 清屏
[root@mongodb]# mongo --port 27017 --host 192.168.100.101
> help #查看帮助
>db.help
>show dbs #查看数据库
admin 0.000GB
config 0.000GB
local 0.000GB
>show databases admin 0.000GB config 0.000GB local 0.000GB
>use local #进入数据库,没有且创建
switched to db local
>show tables #查看集合
startup_log
> show collections #查看集合
startup_log
>db.user.insert({"id":1,"name":"zzq"}); #创建集合user,并添加数据
WriteResult({ "nInserted" : 1 })
> show dbs
admin 0.000GB
local 0.000GB
> show tables;
startup_log
user
>db.user.find(); #查看集合中的数据记录
{ "_id" : ObjectId("5f45d32f7e48f4a36a9cb7e0"), "id" : 1, "name" : "zzq" }
>db.user.count(); #统计集合的条目
1
>db.stats(); #查看集合状态
{
"db" : "local",
"collections" : 2,
"views" : 0,
"objects" : 2,
"avgObjSize" : 887,
"dataSize" : 1774,
"storageSize" : 32768,
"numExtents" : 0,
"indexes" : 2,
"indexSize" : 32768,
"ok" : 1
}
>db.user.insert({"id":2,"name":"zeng","isadmin":"true","gender":null,"favorite":["apple","banana","orange",1,2,3],"regtime":new Date()});
#集合中插入数据条目,并设置多种数据类型
WriteResult({ "nInserted" : 1 })
> db.user.find();
{ "_id" : ObjectId("5f45d32f7e48f4a36a9cb7e0"), "id" : 1, "name" : "zzq" }
{ "_id" : ObjectId("5f45d78e17e09ebe1d094426"), "id" : 2, "name" : "zeng", "isadmin" : "true", "gender" : null, "favorite" : [ "apple", "banana", "orange", 1, 2, 3 ], "regtime" : ISODate("2020-08-26T03:31:26.780Z") }
> db.user.findOne({"id":2}); #根据KEY值搜索集合中内容
{
"_id" : ObjectId("5f45d78e17e09ebe1d094426"),
"id" : 2,
"name" : "zeng",
"isadmin" : "true",
"gender" : null,
"favorite" : [
"apple",
"banana",
"orange",
1,
2,
3
],
"regtime" : ISODate("2020-08-26T03:31:26.780Z")
}
MongoDB常用数据类型
数据类型 | 描述 |
---|---|
string | 字符串;在MongoDB中UTF-8编码的字符串才是合法的 |
Integer | 整型数值,根据系统分为32位和64位 |
Boolean | 布尔值,用于存储布尔值(真/假) |
Double | 双精度浮点值 |
Arrays | 用于将数组或列表或多个值存储为一个键 |
Object | 用于内嵌文档 |
Null | 用于创建空值 |
Date | 日期时间,用户可以指定自己的日期时间,创建Date对象,传入年月日信息 |
Binary Data | 二进制数据,用于存储二进制数据 |
#查看MongoDB的数据类型>
> use zzq;
switched to db zzq
> show collections;
user
> a=db.user.findOne({"id":2});
{ "_id" : ObjectId("5f47562e544998aa19c58d86"), "id" : 2, "name" : "alice" }
> typeof(a.id);
number
> typeof(a.name)
string
MongoDB日常维护
备份与恢复管理
在MongoDB中备份管理包括导入导出、备份与恢复、复制数据库和克隆集合等操作
1.导入导出
可以使用mongoexport
和mongoimport
命令来导出导入MongoDB的数据
mongoexport命令可以把一个collection导出成JSON格式或CSV格式的文件;mongoimport命令可以把一个特定格式的文件的内容导入到指定的collection中,该工具可以导入JSON格式的数据,也可以导入CSV格式的数据
> for(var i=1;i<=1000;i++) db.user.insert({"id":i,"name":"ALICE"}); 批量插入
WriteResult({ "nInserted" : 1 })
> db.user.count(); 统计行数
1000
> db
zzq
> exit
bye
mongoexport -d zzq -c user -o ./user.json -h 192.168.137.21 --port 27017 导出数据
2020-08-28T09:06:47.984+0800 connected to: 192.168.137.21:27017
2020-08-28T09:06:48.000+0800 exported 1000 records
[root@localhost ~]# ll u*
-rw-r--r-- 1 root root 35001 8月 28 09:05 user.json
mongoimport -d zzq1 -c user --file user.json -h 192.168.137.21 --port 27018 导入到另一实例
2020-08-28T09:13:13.973+0800 connected to: 192.168.137.21:27018
2020-08-28T09:13:13.988+0800 imported 1000 documents
[root@localhost ~]# mongo 192.168.137.21:27018
> show dbs
admin 0.000GB
local 0.000GB
zzq1 0.000GB
> use zzq1
switched to db zzq1
> show collections
user
> db.user.find()
{ "_id" : ObjectId("5f48573ecf7246996e681138"), "id" : 1, "name" : "ALICE" }
{ "_id" : ObjectId("5f48573ecf7246996e681139"), "id" : 2, "name" : "ALICE" }
{ "_id" : ObjectId("5f48573ecf7246996e68113a"), "id" : 3, "name" : "ALICE" }
{ "_id" : ObjectId("5f48573ecf7246996e68113b"), "id" : 4, "name" : "ALICE" }
...
Type "it" for more
> db.user.count();
1000
>exit
bye
mongoexport -d zzq1 -c user -q '{"id":{"$gt":500}}' -o user2.json -h 192.168.137.21 --port 27018
2020-08-28T09:18:46.965+0800 connected to: 192.168.137.21:27018
2020-08-28T09:18:46.973+0800 exported 500 records
参数说明
-d:指定数据库的名字
-c:指定collection的名字
-f:指定要导出那些列
-o:指明要导出的文件名
-q:指明导出数据的过滤条件
备份与恢复
在MongoDB中可以使用mongodump命令来备份MongoDB数据,该命令可以导出所有的数据到指定目录中。mongodump命令可以通过参数指定导出的数据量及转存的服务器
mongodump语法:
>mongodump -h dbhost -d dbname -o dbdbdirectory
参数说明
- -h:MongoDB所在服务器地址,例如:127.0.0.1,也可以指定端口号,如:127.0.0.1:27017
- -d:需要备份的数据库实例,例如:test
- -o:备份的数据存放的位置,该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据
[root@localhost ~]# mongodump -d zzq -o ./backup/ -h 192.168.137.21:27017
2020-08-28T09:49:59.228+0800 writing zzq.user to
2020-08-28T09:49:59.230+0800 done dumping zzq.user (1000 documents)
[root@localhost ~]# ls -lth ./backup/zzq/
总用量 56K
-rw-r--r-- 1 root root 49K 8月 28 09:49 user.bson
-rw-r--r-- 1 root root 80 8月 28 09:49 user.metadata.json
MongoDB使用mongorestore命令来恢复备份的数据
语法mongorestore -h dbhost -d dbname --directoryperdb dbdirectory
[root@localhost ~]# mongorestore -d zzq1 --dir=./backup/zzq/ -h 192.168.137.21:27017
2020-08-28T09:54:37.961+0800 the --db and --collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use --nsInclude instead
2020-08-28T09:54:37.961+0800 building a list of collections to restore from backup/zzq dir
2020-08-28T09:54:37.961+0800 reading metadata for zzq1.user from backup/zzq/user.metadata.json
2020-08-28T09:54:37.967+0800 restoring zzq1.user from backup/zzq/user.bson
2020-08-28T09:54:37.977+0800 no indexes to restore
2020-08-28T09:54:37.977+0800 finished restoring zzq1.user (1000 documents)
2020-08-28T09:54:37.977+0800 done
[root@localhost ~]# mongo 192.168.137.21:27017
> show dbs
admin 0.000GB
kgc 0.000GB
kgc1 0.000GB
local 0.000GB
zzq 0.000GB
zzq1 0.000GB
> use zzq1
switched to db zzq1
> show collections
user
> db.user.count()
1000
> db.user.find();
{ "_id" : ObjectId("5f48573ecf7246996e681138"), "id" : 1, "name" : "ALICE" }
{ "_id" : ObjectId("5f48573ecf7246996e681139"), "id" : 2, "name" : "ALICE" }
{ "_id" : ObjectId("5f48573ecf7246996e68113a"), "id" : 3, "name" : "ALICE" }
{ "_id" : ObjectId("5f48573ecf7246996e68113b"), "id" : 4, "name" : "ALICE" }
{ "_id" : ObjectId("5f48573ecf7246996e68113c"), "id" : 5, "name" : "ALICE" }
{ "_id" : ObjectId("5f48573ecf7246996e68113d"), "id" : 6, "name" : "ALICE" }
{ "_id" : ObjectId("5f48573ecf7246996e68113e"), "id" : 7, "name" : "ALICE" }
{ "_id" : ObjectId("5f48573ecf7246996e68113f"), "id" : 8, "name" : "ALICE" }
{ "_id" : ObjectId("5f48573ecf7246996e681140"), "id" : 9, "name" : "ALICE" }
......
复制数据库
在MongoDB中可以使用db.copyDatabase命令复制数据库
> show dbs
admin 0.000GB
kgc 0.000GB
kgc1 0.000GB
local 0.000GB
zzq 0.000GB
zzq1 0.000GB
> db.copyDatabase("kgc","kgc2","192.168.137.21:27017");
{ "ok" : 1 }
> show dbs
admin 0.000GB
kgc 0.000GB
kgc1 0.000GB
kgc2 0.000GB
local 0.000GB
zzq 0.000GB
zzq1 0.000GB
>
克隆集合
在MongoDB中可以将数据库中的集合进行克隆,这里将kgc数据库中的user集合克隆岛另外一个实例
> use kgc
switched to db kgc
> show collections
user
>exit
bye
[root@localhost ~]# mongod -f /etc/mongod1.conf
about to fork child process, waiting until server is ready for connections.
forked process: 22924
child process started successfully, parent exiting
[root@localhost ~]# netstat -antp | grep mongod
tcp 0 0 192.168.137.21:27017 0.0.0.0:* LISTEN 13699/mongod
tcp 0 0 192.168.137.21:27018 0.0.0.0:* LISTEN 22924/mongod
[root@localhost ~]# mongo 192.168.137.21:27018
MongoDB shell version v3.4.24
connecting to: mongodb://192.168.137.21:27018/test
MongoDB server version: 3.4.24
......
> show dbs
admin 0.000GB
local 0.000GB
zzq1 0.000GB
> db.runCommand({"cloneCollection":"kgc.user","from":"192.168.137.21:27017"});
{ "ok" : 1 }
> show dbs
admin 0.000GB
kgc 0.000GB
local 0.000GB
zzq1 0.000GB
> show collections;
user
安全管理
MongoDB安全管理主要包括MongoDB的安全访问控制和用户权限分配
限定监听特定端口和IP地址
只绑定内网卡地址:bind_ip=192.168.127.21
只侦听指定的端口:port=27017
vim /etc/mongod.conf
net:
port: 27017
bindIp: 192.168.137.21
root@localhost system]# netstat -antp | grep 27017
tcp 0 0 192.168.137.21:27017 0.0.0.0:* LISTEN 13699/mongod
[root@localhost system]# mongo --host 192.168.137.21
MongoDB shell version v3.4.24
connecting to: mongodb://192.168.137.21:27017/
MongoDB server version: 3.4.24
授权启动
可以配置授权用户来访问MongoDB,需在配置文件宗指定authorization: enabled
mongo 192.168.137.21
MongoDB shell version v3.4.24
connecting to: mongodb://192.168.137.21:27017/test
MongoDB server version: 3.4.24
> db.createUser(
... {
... user: "root",
... pwd: "root",
... roles: [ { role: "root", db: "admin" } ]
... }
... )
Successfully added user: {
"user" : "root",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
> exit
bye
> exit
bye
security:
authorization: enabled
[root@localhost system]# mongo 192.168.137.21:27017
MongoDB shell version v3.4.24
connecting to: mongodb://192.168.137.21:27017/test
MongoDB server version: 3.4.24
> show dbs;
2020-08-28T11:34:11.756+0800 E QUERY [thread1] Error: listDatabases failed:{
"ok" : 0,
"errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }",
"code" : 13,
"codeName" : "Unauthorized"
} :
_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
> use admin
switched to db admin
> db.auth("root","root")
1
> show dbs
admin 0.000GB
kgc 0.000GB
kgc1 0.000GB
kgc2 0.000GB
local 0.000GB
zzq 0.000GB
zzq1 0.000GB
登录时可指定以授权的用户登录
[root@localhost ~]# mongo -uroot -proot 192.168.100.10:27017/admin
删除账号robin
> db.dropUser("robin");
false
> use kgc
switched to db kgc
> db.dropUser("robin");
true
进程管理
管理员可以对MongoDB进程进行管理和控制
查看当前正在运行的进程的命令为db.currentOp()
中止正在运行的高消耗资源的进程命令为db,killOp(opid)
> db.currentOp()
{
"inprog" : [
{
"desc" : "conn1",
"threadId" : "140550667011840",
"connectionId" : 1,
"client" : "192.168.137.21:53634",
"appName" : "MongoDB Shell",
"clientMetadata" : {
"application" : {
"name" : "MongoDB Shell"
},
"driver" : {
"name" : "MongoDB Internal Client",
"version" : "3.4.24"
},
"os" : {
"type" : "Linux",
"name" : "CentOS Linux release 7.8.2003 (Core)",
"architecture" : "x86_64",
"version" : "Kernel 3.10.0-1127.18.2.el7.x86_64"
}
},
"active" : true,
"opid" : 2027,
"secs_running" : 0,
"microsecs_running" : NumberLong(90),
"op" : "command",
"ns" : "admin.$cmd",
"query" : {
"currentOp" : 1
},
"numYields" : 0,
"locks" : {
},
"waitingForLock" : false,
"lockStats" : {
}
}
],
"ok" : 1
}
> db.killOp(2027)
{ "info" : "attempting to kill op", "ok" : 1 }
MongoDB监控
MongoDB提供一些内置工具可以监控数据库的状态
- 查看数据库实例的状态信息:
db.serverStatus()
- 查看当前数据库的统计信息:
db.status()
此外,还可以通过Web界面查看系统监控信息
第一步:修改配置文件
vim /etc/mongod.cong
bindIp: 192.168.137.21
第二步:停止进程
[root@localhost ~]# mongod -f /etc/mongod.conf --shutdown
第三步:开启监控
命令行开启,临时,下次重启失效
[root@localhost ~]# mongod -f /etc/mongod.conf --httpinterface
验证:在浏览器验证
http://192.168.137.21:28017/
一些问题
该环境为Centos7.5,使用的MongoDB为YUM安装的3.6版本,我在配置授权用户时,需要将系统服务脚本进行重写,如下:
vim /lib/systemd/system/mongod.service
[Unit]
Description=MongoDB
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/var/lib/mongo/mongod.lock
ExecStart=/usr/bin/mongod --auth -f /etc/mongod.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start mongod
开启监控时,如已开启用户授权,则访问web页面出现以下情况
输入了正确的用户名、密码但页面不能正常显示,只能将认证关闭