文章目录
- MongoDB介绍
- 主要用途和特点
- 对比关系型数据库
- 和关系型数据库最大的不同
- 什么时候使用MongoDB
- MongoDB数据结构
- MongoDB参考资料
- MongoDB部署和访问
- 二进制安装
- 脚本安装
- MongoDB后台管理shell
- mongodb数据库命令
- mongo的help
- db.mycoll.help()
- mongosh的help
- show dbs
- use dbname
- mongosh的安装
- 可视化管理工具
- Python访问MongoDB
- MongoDB管理
- 库的操作
- 集合(表)的操作
- 灵活的insert
- 记录(文档操作)
- 用户和权限管理
- 用户验证库
- 开启用户认证
- 用户管理说明
- 系统内置角色
- superuser用户
- 普通用户
- 查看所有用户信息
- MongoDB复制集
- 复制集架构
- 复制集实现
- 1.配置mongo.conf文件
- 2.初始化设置,
- 3.执行rs.initiate(初始化设置的函数名)
- 查看复制集状态
- slaveOk()
- secondary节点只能读,不能写
- 添加和删除节点
- 复制集角色说明
- 主要角色
- 主节点[Primary]
- 副本节点[Secondary]
- 仲裁者[Arbiter]
- Primary选举实现
- 其他角色
- rs.conf()查看优先级
- MongoDB备份恢复
- 备份恢复的两个工具
- 1.mongoexport/mongoimport
- 2.mongodump/mongorestore
- 两种工具的对比
- mongoexport/mongoimport
- 导出工具 mongoexport
- 导出json格式示例
- 导出csv格式示例
- 导入工具mongoimport
- 导入示例
MongoDB介绍
MongoDB并非芒果mango的意思,而是源于Humongous(巨大的)一词。
MongoDB是由总部位于美国纽约的上市公司MongoDB lnc(原名10gen)基于C++编写的分布式文档数据库。
之所以称为文档数据库,是因为MongoDB保存的是"JSON Document",并非一般的PDF,WORD文档。MongoDB内部使用类似于Json的bson格式。
内部执行引擎为JS解释器。把文档存储成bson结构,在查询时转换为JS对象,并可以通过熟悉的js语法来操作。
MongoDB被称为最像RDBMS的NoSQL,支持事务,锁,索引类似于MySQL。
官方网站:https://www.mongodb.com/
Github:https://github.com/mongodb
数据库排名
https://db-engines.com/en/ranking
https://db-engines.com/en/ranking_trend/system/MongoDB
主要用途和特点
主要用途
1.应用数据库,比如:存储银行,保险公司流水信息,类似于Oracle,MySQL海量数据处理,大数据分析
2.网站数据、缓存等大尺寸、低价值的数据
3.在高伸缩性的场景,用于对象及JSON数据的存储。
主要特点
1.灵活动态的文档建模
2.JSON数据模型比较适合开发者
3.支持高可用
4.水平扩展可以支撑很大数据量和并发
5.存储空间占用相对关系型数据库会小很多
缺点:
1.多表关联:仅仅支持Left Outer Join
2.SQL语句支持:查询为主,部分支持
3.多表原子事务:不支持
4.多文档原子事务:不支持
5.16MB文档大小限制,不支持中文排序
6.服务端Javascript性能欠佳
对比关系型数据库
和关系型数据库最大的不同
MongoDB和关系型数据库最大的不同:
1.传统型数据库:结构化数据,定好了表结构后,每一行的内容必须符合表结构,就是说一列的个数和类型都一样;
2.MongoDB文档型数据库:表中的每个文档都可以有自己独特的结构,即json对象都可以有自己独特的属性和值。
什么时候使用MongoDB
什么时候使用MongoDB
1.数据量是有亿万级或者需要不断扩容
2.需要2000-3000以上的读写每秒
3.新应用,需求会变,数据模型无法确定
4.需要整合多个外部数据源
5.系统需要99.999%高可用
6.系统需要大量的地理位置查询
7.系统需要提供最小的latency
8.管理的主要数据对象<10
MongoDB数据结构
MongoDB参考资料
官网帮助手册:https://www.mongodb.com/docs/manual/
博客:https://www.cnblogs.com/clsn/p/8214194.html
MongoDB中文社区:https://mongoing.com/
runoob.com教程:https://www.runoob.com/mongodb/mongodb-tutorial.html
MongoDB部署和访问
官方安装说明:https://www.mongodb.com/docs/manual/installation/
MongoDB支持各种系统安装
二进制安装
官方配置文件说明:https://www.mongodb.com/docs/manual/reference/configuration-options/
创建所需用户和组
useradd mongod
创建mongodb所需目录结构
mkdir -p /mongodb/{conf, data, log}
创建YAML格式的配置文件,早期3.0版本以前是普通文本格式
cat > /mongodb/conf/mongo.conf <<EOF
日志相关
systemLog:
destination: file
path: "/mongodb/log/mongodb.log" 日志位置
logAppend: true 追加日志
数据存储有关
storage:
dbPath: "/mongodb/data/" 数据路径的位置
进程控制
processManagement:
fork: true 后台守护进程
网络配置有关
net:
port: 27017 端口号,默认不配置端口号,是27017
bindIp: 0.0.0.0 监听地址自MongoDB 3.6版本后默认监听在localhost
#安全验证有关配置
security:
authorization: enabled 是否打开用户名密码验证,默认此项为关掉
EOF
cat /mongodb/conf/mongo.conf
systemLog:
destination: file
path: "/mongodb/log/mongodb.log"
logAppend : true
storage :
dbPath: "/mongodb/data/"
processManagement:
fork : true
net:
port: 27017
bindIp: 0.0.0.0
脚本安装
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#Date: 2021-02-19
#Filename: install_mongodb.sh
#URL: http://www.wangxiaochun.com
#Description: The test script
#Copyright (C): 2021 All rights reserved
#********************************************************************
MONGODB_VERSOIN=rhel80-5.0.4
#MONGODB_VERSOIN=rhel70-5.0.3
#MONGODB_VERSOIN=ubuntu1804-5.0.3
#MONGODB_VERSOIN=ubuntu1804-4.4.4
MONGODB_FILE=mongodb-linux-x86_64-${MONGODB_VERSOIN}.tgz
#MONGODB_FILE=mongodb-linux-x86_64-ubuntu1804-4.4.4.tgz
URL=https://fastdl.mongodb.org/linux/$MONGODB_FILE
MONGODB_DIR=/mongodb
INSTALL_DIR=/usr/local
PORT=27017
MY_IP=`hostname -I|awk '{print $1}'`
. /etc/os-release
color () {
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \E[0m"
echo -n "$1" && $MOVE_TO_COL
echo -n "["
if [ $2 = "success" -o $2 = "0" ] ;then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $2 = "failure" -o $2 = "1" ] ;then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}
system_prepare () {
[ -e $MONGODB_DIR -o -e $INSTALL_DIR/mongodb ] && { color "MongoDB 数据库已安装!" 1;exit; }
if [ $ID = "centos" -o $ID = "rocky" ];then
rpm -q curl &> /dev/null || yum install -y -q curl
elif [ $ID = "ubuntu" ];then
dpkg -l curl &> /dev/null || apt -y install curl
else
color '不支持当前操作系统!' 1
exit
fi
if [ -e /etc/rc.local ];then
echo "echo never > /sys/kernel/mm/transparent hugepage/enabled" >> /etc/rc.local
else
cat > /etc/rc.local <<EOF
#!/bin/bash
echo never > /sys/kernel/mm/transparent hugepage/enabled
EOF
fi
chmod +x /etc/rc.local
}
mongodb_file_prepare () {
if [ ! -e $MONGODB_FILE ];then
curl -O $URL || { color "MongoDB 数据库文件下载失败" 1; exit; }
fi
}
install_mongodb () {
id mongod &> /dev/null || useradd -m -s /bin/bash mongod
tar xf $MONGODB_FILE -C $INSTALL_DIR
ln -s $INSTALL_DIR/mongodb-linux-x86_64-${MONGODB_VERSOIN} $INSTALL_DIR/mongodb
#mongod --dbpath $db_dir --bind_ip_all --port $PORT --logpath $db_dir/mongod.log --fork
}
config_mongodb(){
echo PATH=$INSTALL_DIR/mongodb/bin/:'$PATH' > /etc/profile.d/mongodb.sh
. /etc/profile.d/mongodb.sh
mkdir -p $MONGODB_DIR/{conf,data,log}
cat > $MONGODB_DIR/conf/mongo.conf <<EOF
systemLog:
destination: file
path: "$MONGODB_DIR/log/mongodb.log"
logAppend: true
storage:
dbPath: "$MONGODB_DIR/data/"
journal:
enabled: true
processManagement:
fork: true
net:
port: 27017
bindIp: 0.0.0.0
EOF
chown -R mongod.mongod $MONGODB_DIR/
cat > /lib/systemd/system/mongod.service <<EOF
[Unit]
Description=mongodb
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
User=mongod
Group=mongod
ExecStart=$INSTALL_DIR/mongodb/bin/mongod --config $MONGODB_DIR/conf/mongo.conf
ExecReload=/bin/kill -s HUP \$MAINPID
ExecStop=$INSTALL_DIR/bin/mongod --config $MONGODB/conf/mongo.conf --shutdown
PrivateTmp=true
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for mongod as specified in
# https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now mongod &>/dev/null
}
start_mongodb() {
systemctl is-active mongod.service &>/dev/null
if [ $? -eq 0 ];then
echo
color "MongoDB 安装完成!" 0
else
color "MongoDB 安装失败!" 1
exit
fi
}
system_prepare
mongodb_file_prepare
install_mongodb
config_mongodb
start_mongodb
MongoDB后台管理shell
如果需要进入mongodb后台管理,可以先打开mongodb装目录的下的 bin目录,然后执行mongo命令文件。
MongoDB Shell是MongoDB自带的交互式Javascript shell,用来对MongoDB进行操作和管理的交互式环境。
mongo是MongoDB早期版本使用的shell工具,将来会被mongosh替代。
当mongo进入mongoDB后台后,它默认会链接到test数据库,使用db命令可以查看
mongodb数据库命令
mongo的help
db.mycoll.help()
mongosh的help
show dbs
use dbname
use命令后直接跟一个名称就可以创建这个名称的数据表(如下截图),不像mysql必须先创建数据表才能use
mongosh的安装
官方安装文档:https://www.mongodb.com/docs/mongodb-shell/install/
yum安装或者下载包安装
mongodb-mongosh-1.1.2.el8.x86_64.rpm
然后就可以使用mongosh
可视化管理工具
MongoDB Compass是MongoDB官网提供的一个可视化管理工具,可以实现创建数据库、管理集合和文档、运行临时查询、评估和优化查询、性能图表、构建地理查询等功能。
MongoDB Compass官网下载地址:https://www.mongodb.com/products/tools/compass
已经连接成功了
Python访问MongoDB
yum -y install python3
pip3 install pymongo
test_mongodb.py
#!/usr/bin/python3
from pymongo import MongoClient
# 客户端连接
#client = MongoClient(host='127.0.0.1', port=27017)
client = MongoClient('mongodb://127.0.0.1:27017')
print(client)
# 指定数据库 # Database类
#db = client.test
db = client['test']
print(db)
# 集合 # Collection类
#users = db['users']
users = db.users
print(users)
for i in range(10):
user = {'id':i, 'name':'wang' + str(i), 'age':20}
users.insert_one(user)
for x in users.find():
print(x)
client.close()
使用show tables查看新增的数据
test> show tables
users
MongoDB管理
官方帮助手册:https://www.mongodb.com/docs/manual/crud/
库的操作
use可以自动建库,如果库内没有数据,则不使用时会自动删除库
>use test
删除当前所在库
> db.dropDatabase()
{ ok: 1, dropped: 'test' }
可以直接切换至不存在的库
>use testdb1
>db
testdb1
可以使用Tab键查看有哪些支持的命令
test> db.drop
db.dropDatabase db.dropUser db.dropAllUsers db.dropRole db.dropAllRoles
集合(表)的操作
灵活的insert
建表方法1:直接创建表
>db.createco1lection ('student ')
建表方法2:当插入一个文档的时候,一个集合就会自动创建。
插入一条数据
db.students.insertOne({
item: 'canvas',
qty: 100,
tags: ['cotton'],
size: { h: 28, w: 35.5, uom: 'cm' }
});
插入多条数据
db.students.insertMany([
{
item: 'journal',
qty: 25,
tags: ['blank', 'red'],
size: { h: 14, w: 21, uom: 'cm' }
},
{
item: 'mat',
qty: 85,
tags: ['gray'],
size: { h: 27.9, w: 35.5, uom: 'cm' }
},
{
item: 'mousepad',
qty: 25,
tags: ['gel', 'blue'],
size: { h: 19, w: 22.85, uom: 'cm' }
}
]);
此时我的数据库中已经有user表了,且表中有只有id,name,age字段,那么此时我插入下面这个记录会成功吗?
db.users.insertOne({
item: 'canvas',
qty: 100,
tags: ['cotton'],
size: { h: 28, w: 35.5, uom: 'cm' }
});
看,插入成功了! mysql这么操作的话是会报错的哦!
查看库中的集合列表
show tables
show collections
查看集合的信息
db.students.stats()
删除集合
db.students.drop()
记录(文档操作)
数据录入:
for (i = 0; i < 10000; i++) {db.student.insertOne({ uid: i, name: "lei" + i, "age": 18, "date": new Date() });}
for(i=0;i<10000;i++){db.users.insertOne({uid: i, name: "lei"+i, "age": i, address: "shenzhen"})}
for(i=0;i<10000;i++){db.random.insertOne({num: Math.random()* 100000})
查询数据行数
db.student.countDocuments()
只显示前三条
db.student.find().limit(3)
跳过前面5条记录显示后面的
db.student.find().skip(5)
db.student.find({uid:18})
查询大于等于18并正序排序的users集合,-1则是倒序
db.users.find({age: { $gte: 18 }},{ name: 1, address: 1}).limit(5)
db.student.deleteOne({uid: 12})
用户和权限管理
MongoDB数据库默认是没有用户名及密码的,即无权限访问限制。为了方便数据库的管理和安全,应启用认证和创建数据库用户。
官方帮助手册:https://www.mongodb.com/docs/manual/tutorial/create-users/
用户验证库
关于用户验证库
1.创建用户时,use所在的库就是此用户的验证库
2.登录时,必须明确指定验证库才能登录
3.一个数据库可以成为多个用户的验证库,但一个用户只能使用一个验证库
4.对于管理员用户,必须在admin下创建,即管理员用的验证库是admin
5.普通用户的验证库一般是所管理的库
6.如果直接登录到数据库,不进行use,默认的验证库是test
7.从3.6版本开始,配置文件中不添加bindIp参数,默认不允许远程登录,只能本地管理员登录。
开启用户认证
#方法2,修改配置文件中,加入以下配置
cat >> /mongodb/conf/mongo.conf <<EOF
security:
authorization: enabled
EOF
systemctl restart mongod
用户管理说明
use test
db.createUser(
{
user: "myTester",
pwd: passwordPrompt(), // or cleartext password
roles: [ { role: "readWrite", db: "test" },
{ role: "read", db: "reporting" } ]
}
)
系统内置角色
官方帮助手册:https://www.mongodb.com/docs/manual/reference/built-in-roles/
superuser用户
创建超级管理员root(也可以是任意用户名)管理所有数据库(必须use admin再去创建,因为超级用户是存放在admin库中的)
db.createUser ( {user: "superuser", pwd: "123456", roles: [{role: "root", db: "admin"}]})
验证superuser用户是否可以登录
普通用户
创建一个普通用户myTester,对test数据库有读写权限,对test2只有读的权限
db.createUser(
{
user: "myTester",
pwd: passwordPrompt(),
roles: [ { role: "readWrite", db: "test" },
{ role: "read", db: "test2" } ]
}
)
验证myTester用户的登录
验证用户也可以不用去登录判断该用户是否生效,可以直接使用db.auth(‘用户名’,‘密码’)命令验证,返回ok:1则为用户创建成功。
db.auth('myTester', '123456')
验证myTester是否对test2有写权限
查看所有用户信息
db.system.users.find().pretty()
要使用超级管理员在admin库中查看
test> use admin
switched to db admin
admin> db.system.users.find().pretty()
[
{
_id: 'admin.superuser',
userId: UUID("61b779dd-f242-4f2c-af0c-ffa29381023e"),
user: 'superuser',
db: 'admin',
credentials: {
......
},
roles: [ { role: 'root', db: 'admin' } ]
},
{
_id: 'test.myTester',
userId: UUID("59dbc2ec-a171-4666-9f4a-ab8b49f97b04"),
user: 'myTester',
db: 'test',
credentials: {
......
},
roles: [
{ role: 'read', db: 'test2' },
{ role: 'readWrite', db: 'test' }
]
}
]
admin>
MongoDB复制集
MongDB像MySQL一样,支持类似的主从复制架构,但无法实现自动故障转移,所以官方推荐使用复制集。
MongoDB复制集是将数据同步在多个服务器的过程,复制集提供了数据的冗余备份,并在多个服务器上存储数据副本,保证数据的安全性。
复制集还允许从硬件故障和服务中断中恢复数据。当故障时,会自动选举新master节点实现集群的高可用。
官方帮助手册:https://www.mongodb.com/docs/manual/replication/
复制集架构
MongoDB的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,主节点接收所有写入操作。其余的都是从节点,负责复制主节点上的数据。
MongoDB各个节点常见的搭配方式为:一主一从、一主两从此方式最多。
主节点记录在其上的所有操作oplog(操作日志),从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
客户端写入数据到主节点时,主节点与从节点进行数据交互保障数据的一致性。
复制集特征:
1.N个奇数节点的集群
2.基于选举机制,任何节点可作为主节点
3.所有写入操作都在主节点上,所以增加节点不会提高系统写性能,可以提升读性能
4.主节点故障时,会自动选举出新节点代替,自动故障转移
复制集实现
复制集要求三个以上的MongoDB节点
我有三台机器154、155、156,都有安装好了MongoDB
1.配置mongo.conf文件
在三台主机的配置文件中分别加上以下配置
vim /mongodb/conf/mongo.conf
replication:
replSetName: myrepl
示例
systemLog:
destination: file
path: "/mongodb/log/mongodb.log"
logAppend: true
storage:
dbPath: "/mongodb/data/"
journal:
enabled: true
processManagement:
fork: true
net:
port: 27017
bindIp: 0.0.0.0
#security:
# authorization: enabled
replication:
replSetName: myrepl 制定复制集名称,所有复制集成员此名称要一致
2.初始化设置,
以下配置在三台主机中任意一台执行
config = { _id: 'myrepl', members: [
{_id: 0, host: '192.168.10.154:27017'},
{_id: 1, host: '192.168.10.155:27017'},
{_id: 2, host: '192.168.10.156:27017'}]
}
3.执行rs.initiate(初始化设置的函数名)
rs.initiate(config)
我在154这台机器上执行的
此时155和156上则显示SECONDARY
查看复制集状态
myrepl:PRIMARY> rs.isMaster()
{
"topologyVersion" : {
"processId" : ObjectId("66a78b7916704ef3521b7b5c"),
"counter" : NumberLong(10)
},
"hosts" : [
"192.168.10.154:27017",
"192.168.10.155:27017",
"192.168.10.156:27017"
],
"setName" : "myrepl",
"setVersion" : 1,
"ismaster" : true,
"secondary" : false,
"primary" : "192.168.10.154:27017",
"me" : "192.168.10.154:27017",
"electionId" : ObjectId("7fffffff0000000000000002"),
"lastWrite" : {
"opTime" : {
"ts" : Timestamp(1722257856, 1),
"t" : NumberLong(2)
},
"lastWriteDate" : ISODate("2024-07-29T12:57:36Z"),
"majorityOpTime" : {
"ts" : Timestamp(1722257856, 1),
"t" : NumberLong(2)
},
"majorityWriteDate" : ISODate("2024-07-29T12:57:36Z")
},
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 100000,
"localTime" : ISODate("2024-07-29T12:57:40.021Z"),
"logicalSessionTimeoutMinutes" : 30,
"connectionId" : 1,
"minWireVersion" : 0,
"maxWireVersion" : 13,
"readOnly" : false,
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1722257856, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1722257856, 1)
}
myrepl:PRIMARY>
slaveOk()
SECONDARY节点默认不提供访问,需要执行slaveOK()来打开访问设置
rs.slaveOk()将来会被rs.secondaryOk()取代
secondary节点只能读,不能写
添加和删除节点
删除一个节点
rs.remove ("ip: port")
新增从节点
rs.add ("ip: port")
#新增仲裁节点
rs.addArb ("ip: port")
示例
添加一个节点
myrepl:PRIMARY> rs.add ("192.168.10.157: 27017")
删除一个节点
myrepl:PRIMARY> rs.remove ("192.168.10.157: 27017")
{ "ok": 1 }
添加仲裁节点
myrepl:PRIMARY> rs.addArb ("192.168.10.158:27017")
myrepl:SECONDARY> db.isMaster()
{
"hosts" : [
"192.168.10.154:27017",
"192.168.10.155:27017",
"192.168.10.156:27017"
],
"arbiters" : [
"192.168.10.158:27017"
],
}
复制集角色说明
主要角色
主节点[Primary]
接收所有的写请求,然后把修改同步到所有Secondary。一个Replica Set只能有一个Primary节点,当Primary挂掉后,其他Secondary或者Arbiter节点会重新选举出来一个主节点。默认读请求也是发到Primary节点处理的,如果需要转发到Secondary,需要在客户端修改一下连接配置。
副本节点[Secondary]
与主节点保持同样的数据集。当主节点挂掉的时候,可以参与选举出新主节点。
仲裁者[Arbiter]
不保存数据,不参与选主,只进行选主投票。使用Arbiter可以减轻数据存储的硬件需求,Arbiter跑起来几乎没什么大的硬件资源需求,在生产环境下它和其他数据节点不要部署在同一台机器上。实际生产环境当前不推存使用Arbiter节点类型
MongoDB使用Raft选举机制,而MySQL MGR 用的是Paxos,而Raft本质是Paxos的变种
注意,一个自动failover的Replica Set节点数必须为奇数,目的是选主投票的时候要有一个大多数才能进行选主决策。
Primary选举实现
复制集通过replSetInitiate命令(或mongo shell的rs.initiate())进行初始化,初始化后各个成员间开始发送心跳消息,并发起Primary选举操作,获得大多数成员投票支持的节点,会成为Primary,其余节点成为Secondary。
选举实现
1.具有投票权的节点之间两两互相发送心跳
2.当5次心跳未收到时,判断为节点失联
3.如果失联的是主节点,从节点会发起选举,选出新的主节点
4·如果失联的是从节点则不会产生新的选举
5.选举基于RAFT一致性算法实现,选举成功的必要条件是大多数投票节点存活
6.复制集中最多可以有50个节点,但具有投票权的节点最多7个,且为奇数个投票成员
大多数的定义
假设复制集内投票成员(后续介绍)数量为N,则大多数为N/2+1,当复制集内存活成员数量不足大多数时,整个复制集将无法选举出Primary,复制集将无法提供写服务,处于只读状态。
通常建议将复制集成员数量设置为奇数,从上表可以看出3个节点和4个节点的复制集都只能容忍1个节点失效,从服务可用性的角度看,其效果是一样的。(但无疑4个节点能提供更可靠的数据存储)
被选举为主节点的节点必须:
1.能够与多数节点建立连接
2.具有较新的oplog
3.具有较高的优先级(如果有配置)
其他角色
rs.conf()查看优先级
MongoDB备份恢复
虽然有复制集的高可用性保证,数据丢失的可能很低,但仍然需要备份。
备份的目的:
1.防止硬件故障引起的数据丢失
2.防止人为错误误删数据
3.时间回溯
4.监管要求
备份恢复的两个工具
1.mongoexport/mongoimport
mongoexport/mongoimport可以实现逻辑备份,类似于mysqldump,可以导出json或csv格式文件
应用场景总结
1.异构平台迁移,比如:MySQL和MongoDB
2.同平台跨大版本的MongoDB数据导出导入:比如mongodb 2 ----> mongodb 3
2.mongodump/mongorestore
物理备份,日常备份恢复时使用,导出的二进制文件。
mongodump能够在Mongodb运行时进行备份,它的工作原理是对运行的Mongodb做查询,然后将所有查到的文档写入磁盘,但是存在的问题时使用mongodump产生的备份不一定是数据库的实时快照,如果我们在备份时对数据库进行了写入操作,则备份出来的文件可能不完全和Mongodb实时数据相等。另外在备份时可能会对其它客户端性能产生不利的影响。
使用mongodump备份最灵活,但速度上也是最慢的
mongodump出来的数据不能表示某个时间点,只是某个时间段
两种工具的对比
mongoexport/mongoimport导入/导出的是JSON格式
而mongodump/mongorestore导入/导出的是BSON格式。
JSON可读性强但体积较大,BSON则是二进制文件,体积小但对人类几乎没有可读性。
在一些mongodb版本之间,BSON格式可能会随版本不同而有所不同,所以不同版本之间用mongodump/mongorestore可能不会成功,具体要看版本之间的兼容性。
当无法使用BSON进行跨版本的数据迁移的时候,使用JSON格式即mongoexport/mongoimport是一个可选项。
跨版本的mongodump/mongorestore并不推荐,实在要做请先检查文档看两个版本是否兼容。
JSON虽然具有较好的跨版本通用性,但其只保留了数据部分,不保留索引,账户等其他基础信息。
mongoexport/mongoimport
导出工具 mongoexport
此工具只能针对单表,不支持整库的表导出
官方帮助手册:https://www.mongodb.com/docs/database-tools/mongoexport/
下载链接:https://www.mongodb.com/try/download/database-tools
我下载的是rpm包
yum -y install mongodb-database-tools-rhel80-x86_64-100.5.1.rpm
可以使用一下命令,查看导出导出工具
rpm -ql mongodb-database-tools
mongoexport具体用法使用"mongoexport --help"查看帮助,部分参数使用如下所示:
[root@rocky ~]# mongoexport --help
参数说明:
-h 指明数据库宿主机的IP
-u 指明数据库的用户名
-p 指明数据库的密码
-d 指明数据库的名字
-c 指明co1lection的名字
-f 指明要导出那些列
-o 指明到要导出的文件名
-q 指明导出数据的过滤条件
--type=Csv或--csv 指定导出为csv格式,默认json格式
--authenticationDatabase<验证库> 指定验证库
导出json格式示例
目前在test库中有一张users表,表中有一万条记录
mongoexport -d test -c users -o /backup/users.json
使用wc -l 查看下导出的文件有多少行
导出csv格式示例
导出test库中userStore表的一万条记录为csv格式
mongoexport -d test -c userStore --type=csv -f uid,name,age,address -o /backup/users.csv
导出成功了
查看一下导出的users.csv文件的样子
导入工具mongoimport
官方帮助手册:https://www.mongodb.com/docs/database-tools/mongoimport/
[root@rocky ~]# mongoimport --help
Usage:
mongoimport <options> <connection-string> <file>
Import CSV, TSV or JSON data into MongoDB. If no file is provided, mongoimport reads from stdin.
Connection strings must begin with mongodb:// or mongodb+srv://.
See http://docs.mongodb.com/database-tools/mongoimport/ for more information.
参数说明:
-h 指明数据库宿主机的IP
-u 指明数据库的用户名
-p 指明数据库的密码
-d 指明数据库的名字
-c 指明co1lection的名字-f#指明要导入那些列
--type=csv 指定导入cSv格式文件,默认json格式
-j,--numInsertionworkers=<number> 同时插入的数量,默认为
--headerline 指明第一行是列名,不需要导入
导入示例
1.删除users表
2.将/backup/users.json 数据导入到userStore表中,userStore表不存在会自动创建。
mongoimport -d test -c userStore /backup/users.json