一、MongoDB介绍
1.1 简介
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统,旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。
1.2 主要用途
- 网站数据(eg:银行、保险公司的流水信息)。MongoDB 非常适合实时的插入、更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性
- 缓存。由于性能很高,MongoDB 也适合作为信息基础设施的缓存层。在系统重启之后,由MongoDB 搭建的持久化缓存层可以避免下层的数据源过载。
- 高伸缩性。MongoDB 非常适合由数十或数百台服务器组成的数据库,MongoDB 的路线图中已经包含对MapReduce 引擎的内置支持。
- 用于对象及json数据的存储。MongoDB的bson数据格式非常适合文档化格式的存储及查询。
1.3 优缺点
(1)优点
- Json的数据格式本身就便于开发,而且支持多种编程语言(eg:Java、Python、C、C++、go等)
- 水平扩展可以应对高并发。通过增加服务器数量来对数据库扩容
- 支持高可用。MongoDB的复制工具称为副本集(replica set),它包含提供自动故障转移和数据同步。
- 灵活的数据模型。这意味着没有预定义的模式,并且文档可以基于任何键保存任何值集合。而Mysql需要事先建库建表、定义表结构、字段、数据类型等,数据结构是相对固定的。表结构一旦有调整,里面的数据就会受影响
(2)缺点
- 不支持事务操作
- 无法进行关联表查询
1.4 MongoDB与关系型数据库的对比
1.5 什么时候会用MongoDB(应用特征)
- 数据量有亿万级别或需要不断扩容
- 系统需要大量的地理位置查询或文本查询
- 应用需要99.999%高可用
- 新应用,需求会变,数据模型无法确定
- 需要2000~3000及以上的读写qps
1.6 MongoDB的实际应用案例
- 游戏场景。使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新
- 物流场景。使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。
- 社交场景。使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能
- 物联网场景。使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析
- 视频直播。使用 MongoDB 存储用户信息、礼物信息等
1.7 MongoDB与Mysql的逻辑结构对比
SQL术语/概念
MongoDB术语/概念
解释/说明
database
database
数据库
table
collection
数据库表/集合
row
document
数据记录行/文档
column
field/key
数据字段(列)/(域)键
index
index
索引
value
value
值
table joins
表连接,MongoDB不支持
primary key
primary key
主键,MongoDB自动将_id字段设置为主键
二、MongoDB部署
2.1 环境介绍
基于Ubuntu 20.04操作系统,采用软件包形式安装MongoDB
2.2 安装
#导入公钥
wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add -
#配置仓库文件
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list
#更新安装源
apt-get -y update
#安装
apt-get -y install mongodb-org
#将配置文件/etc/mongod.conf的绑定IP改为0.0.0.0,之后启动
systemctl enable --now mongod
#安装mongo客户端工具
apt-get -y install mongodb-clients
apt-get -y install mongodb-mongosh
2.3 mongod配置文件详解
#日志配置
systemLog:
destination: file
日志位置
path: "/var/log/mongodb/mongodb.log"
追加
logAppend: true
#存储配置
storage:
数据路径
dbPath: "/var/lib/mongodb"
#进程控制
processManagement:
后台守护进程
fork: true
#网络配置
net:
bindIp: 0.0.0.0
port: 27017
#安全验证配置
security:
#是否打开用户名密码验证,默认此项为关掉
authorization: enabled
三、客户端连接
- Mongo
- Mongosh。简单的理解为Mongo的加强版
3.还可以用可视化界面MongoDB Compass进行管理。默认端口27017可以不写
四、MongoDB管理
4.1 MongoDB数据库操作
- MongoDB默认存在的库
- admin库:系统预留库,MondoDB系统管理库
- local库:本地预留库,存储日志
- config库:MongoDB配置信息库
- test库:登录时默认存在的测试库
- 库的相关命令
#显示数据库
show dbs
#查看当前所在的数据库
db
#利用use自动建库。如果库内无数据,在不使用时会删除数据库
use xxx
#删除当前所在库,状态为1表示删除成功
db.dropDatabase()
3.表的相关命令
#当插入一个文档的时候,一个集合就会自动创建。这里people为集合名,也可以结合for循环做批量添加文档
use xxx
db.people.insert({name:”li”})
#查看库中的集合列表
show tables
show collections
#查看集合信息
db.people.stats()
#删除集合
db.people.drop()
4.数据相关命令
#数据录入
db.people.insert({name:”li”})
db.people.insertone({name:”zhang”})
#查询数据行数
db.people.count()
#全表查询,默认每页显示20行。按it继续显示后面的内容
db.people.find()
#只显示前n个数据
db.people.find.limit(n)
#跳过前面n个显示后面的数据
db.people.find.skip(n)
#删除集合中指定内容
db.people.remove({name:”wang”})
#删除集合内所有数据,但表还存在
db.people.remove({})
#设置每页显示n条记录
DBQuery.shllBatchsize=n
#按照条件查询
db.people.find({uid: 10})
#删除指定的文档
db.people.remove({uid: 10})
#修改文档,如果没有加multi: true,默认只修改第一个符合条件的文档
db.people.update({uid: 1},{$set:{age: 20}},{multi: true})
4.2 用户及权限管理
MongoDB默认无用户名和密码,即无权限访问限制。为了便于数据库的管理和对安全的考虑,宜启用认证和创建数据库用户
4.2.1 关于用户验证库
- 创建用户时,use所在的库即为用户的验证库
- 登录时必须指定验证库才能登录(即用户名+主机+密码+验证库)
- 一个数据库可成为多个用户的验证库,但一个用户只能使用一个验证库
- 对于管理员用户,必须在admin下创建,即管理员用的验证库是admin
- 普通用户的验证库一般是所管理的库
- 如果直接登录到数据库,不进行use,默认的验证库是test
- 从3.6版本开始,配置文件不添加bindIp参数时,默认不允许远程登录,只能本地管理员登录
4.2.2 开启用户认证
在mongod.conf做如下配置:
security:
authorization: enabled
之后重启mongod
4.2.3 用户管理
#先进入验证库,创建用户的同时完成授权
use test
db.createUser(
{
user: "myTester",
pwd: passwordPrompt(), // or cleartext password
roles: [ { role: "readWrite", db: "test" },
{ role: "read", db: "reporting" } ]
}
)
以上操作的含义是创建一个myTester用户,需要交互输入密码,针对test数据库有读写权限,针对reporting数据库只有读权限
另外使用passwordPrompt()可避免密码在屏幕中显示。
创建超级管理员可以管理数据库,需要进入admin库再创建。因为超级用户的信息存放于admin库。命令如下:
use admin
db.createUser({user: "root",pwd: passwordPrompt(),roles: [{role: "root",db: "admin"}]})
#验证用户
#交互式验证
use admin
db.auth("root","xxxxxx")
#非交互式验证,不写验证库则登录后在test库而非admin
mongosh -u root -p xxx admin
mongosh -u root -p xxx 192.168.1.103/admin
#查看当前库中用户
use test
db.getUsers()
#用超级管理员查询所有用户信息
use admin
db.system.users.find()
#删除用户。以管理员身份登录,需要进入被删除用户的验证库
use test
db.dropUser("xxx")
注意:如果创建用户有问题,就先注释掉mongod.conf的security的相关配置,重启服务后再去创建用户。创建成功再将配置文件的验证功能打开
4.2.4 用户权限说明
常用角色
权限说明
Read
允许用户读取指定数据库
readWrite
允许用户读写指定数据库
dbAdmin
允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin
允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
clusterAdmin
只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
readAnyDatabase
只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase
只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase
只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase
只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
root
只在admin数据库中可用。超级账号,超级权限
五、MongoDB复制集
5.1 介绍
类似于Redis的主从+哨兵,它也是一个主从+高可用的实现方案。MongoDB复制集是将数据同步在多个服务器的过程。它在多个服务器上存储数据副本,保证数据的安全性。
5.2 复制集架构
一主两从,主节点负责处理客户端请求,从节点复制主节点的数据。由于写入操作都在主节点上,因此增加节点不会提升写的性能,只会提升读性能。当主节点发生故障时,自动选举出新的从节点,实现故障转移。
5.3 复制集中的成员说明
成员
说明
Secondary
正常情况下,复制集的Secondary会参与Primary选举(自身也可能会被选为Primary),并从Primary同步最新写入的数据,以保证与Primary存储相同的数据。Secondary可以提供读服务,增加Secondary节点可以提供复制集的读服务能力,同时提升复制集的可用性。另外,Mongodb支持对复制集的Secondary节点进行灵活的配置,以适应多种场景的需求。
Arbiter
Arbiter节点只参与投票,不能被选为Primary,并且不从Primary同步数据。比如你部署了一个2个节点的复制集,1个Primary,1个Secondary,任意节点宕机,复制集将不能提供服务了(无法选出Primary),这时可以给复制集添加一个Arbiter节点,即使有节点宕机,仍能选出Primary。Arbiter本身不存储数据,是非常轻量级的服务,当复制集成员为偶数时,最好加入一个Arbiter节点,以提升复制集可用性。
Priority0
默认Priority为1,值越大优先级越高。设置Priority0节点的选举优先级为0,则不会被选举为Primary,只能投票。比如你跨机房A、B部署了一个复制集,并且想指定Primary必须在A机房,这时可以将B机房的复制集成员Priority设置为0,这样Primary就一定会是A机房的成员。(注意:如果这样部署,最好将『大多数』节点部署在A机房,否则网络分区时可能无法选出Primary)
Vote0
Mongodb 3.0里,复制集成员最多50个,参与Primary选举投票的成员最多7个,其他成员(Vote0)的vote属性必须设置为0,即不参与投票。
Hidden
Hidden节点不能被选为主(Priority为0),并且对Driver不可见。因Hidden节点不会接受Driver的请求,可使用Hidden节点做一些数据备份、离线计算的任务,不会影响复制集的服务。
Delayed
Delayed节点必须是Hidden节点,并且其数据落后与Primary一段时间(可配置,比如1个小时)。因Delayed节点的数据比Primary落后一段时间,当错误或者无效的数据写入Primary时,可通过Delayed节点的数据来恢复到之前的时间点。
5.4 复制集成员的配置参数
参数字段
类型说明
取值
说明
_id
整数
_id:0
复制集中的标识
host
字符串
host:"主机:端口"
节点主机名
arbiterOnly
布尔值
arbiterOnly:true
是否为仲裁(裁判)节点
priority(权重)
整数
priority=0|1
默认1,是否有资格变成主节点,取值范围0~1000,0永远不会变成主节点
hidden
布尔值
hidden=true|false,0|1
隐藏,权重必须为0,才可以设置
votes
整数
votes= 0|1
投票,是否为投票节点。0 不投票,1投票
slaveDelay
整数
slaveDelay=3600
从库的延迟多少秒
buildIndexes
布尔值
buildIndexes=true|false,0|1
主库的索引,从库也创建,_id索引无效
5.5 复制集的读写设置
读写模式
说明
primary
主节点,默认模式,读操作只在主节点。主节点不可用则报错
primaryPreferred
首选主节点,大多数情况下读操作在主节点。如果主节点不可用(如故障转移),读操作在从节点
secondary
从节点,读操作只在从节点。从节点不可用则报错
secondaryPreferred
首选从节点,大多数情况下读操作在从节点。特殊情况(如单主架构)读操作在主节点
nearest
通过ping探测出最邻近节点。读请求发送到最近的可达节点,可能是主节点或从节点
5.6 复制集部署
使用三台机器(基于Ubuntu20.04)部署mongod,在配置文件中添加如下内容:
replication:
replSetName: myrepl
#指定复制集名称,三台机器保持一致
之后重启Mongod
5.7 配置复制集:一主两从
进入任意一台机器的mongo客户端执行如下操作:
#指定复制集的所有成员信息
config={_id: 'myrepl', members: [{_id: 0, host: '192.168.1.103:27017'}, {_id: 1, host: '192.168.1.104:27017'}, {_id: 2, host: '192.168.1.105:27017'}]}
#初始化并启动复制集
rs.initiate(config)
用rs.status()查看复制集状态。如果health的值为0说明该节点服务异常,否则节点服务正常。
用rs.isMaster()检查谁是主节点,如果isMaster为true则表示此节点为主节点。
5.8 配置复制集:一主一从一Arbiter
config={_id: 'myrepl', members: [{_id: 0, host: '192.168.1.103:27017'}, {_id: 1, host: '192.168.1.104:27017'}, {_id: 2, host: '192.168.1.105:27017', "arbiterOnly": true}]}
rs.initiate(config)
5.9 修改已有集群为一主一从一Arbiter
#进入当前主节点,先删除节点再添加仲裁节点
rs.remove("192.168.1.105:27017")
rs.addArb("192.168.1.105:27017")
六、MongoDB备份恢复
6.1 备份恢复工具介绍
6.1.1 mongoexport/mongoimport说明
它可以实现逻辑备份,类似于mysqldump,可以导出json或csv格式的文件。只针对单表导出/导入,不支持库的导出/导入。
应用场景:
- 异构平台迁移,比如Mysql和MongoDB
- MongoDB跨版本的数据导入导出,比如MongoDB 5 à MongoDB 6
6.1.2 mongodump/mongorestore说明
它可以实现物理备份,日常备份使用。导出的是二进制文件(bson格式)。
Mongodump可以在mongodb运行时进行备份。其工作原理是对运行的mongodb作查询,将所有查到的文档写入磁盘,但是产生的备份不一定是实时快照
6.2 备份命令
Mongodump/mongorestore做备份和恢复操作如下:
mongodump --collection students --db test
mongorestore -d test dump/test/students.bson
Mongoexport/mongoimport做备份和恢复操作如下:
mongoexport -d test -c students -o backup.json
mongoimport -d test -c students backup.json