NoSQL-MongoDB
NoSQL的优势
- 高扩展性
- 分布式计算
- 没有复杂的关系
- 低成本
- 架构灵活
- 半结构化数据
MongoDB的逻辑结构
MongoDB | MySQL |
---|---|
库database | 库 |
集合(collection) | 表 |
文档(document) | 数据行 |
安装部署
- 下载MongoDB
官网下载网址:https://www.mongodb.com/try/download
- 关闭大页内存机制
########################################################################
root用户下
在vi /etc/rc.local最后添加如下代码
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
----------------------------------------------------------
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
----------------------------------------------------------
其他系统关闭参照官方文档:
https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/
---------------
为什么要关闭?
You should disable THP on Linux machines to ensure best performance with MongoDB.
############################################################################
- 创建所需用户和组
useradd mongod
echo 'mongod'|passwd --stdin mongod
- 创建mongodb所需目录结构
mkdir -p /mongodb/conf
mkdir -p /mongodb/log
mkdir -p /mongodb/data
- 上传并解压软件到指定位置
tar -xzvf mongodb-linux-x86_64-rhel70-3.6.23.tgz
cp -r mongodb-linux-x86_64-rhel70-3.6.23/bin /mongodb/
- 设置目录结构权限
chown -R mongod:mongod /mongodb
- 设置用户环境变量
su - mongod
echo 'export PATH=/mongodb/bin:$PATH' >> .bash_profile
source .bash_profile
- 启动mongodb
[mongod@localhost ~]$ mongod --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --port=27017 --logappend --fork
about to fork child process, waiting until server is ready for connections.
forked process: 5591
child process started successfully, parent exiting
#出现successfully启动成功
mongodb配置
配置文件介绍
YAML模式
NOTE:
YAML does not support tab characters for indentation: use spaces instead.
--系统日志有关
systemLog:
destination: file
path: "/mongodb/log/mongodb.log" --日志位置
logAppend: true --日志以追加模式记录
--数据存储有关
storage:
journal:
enabled: true
dbPath: "/mongodb/data" --数据路径的位置
-- 进程控制
processManagement:
fork: true --后台守护进程
pidFilePath: <string> --pid文件的位置,一般不用配置,可以去掉这行,自动生成到data中
--网络配置有关
net:
bindIp: <ip> -- 监听地址
port: <port> -- 端口号,默认不配置端口号,是27017
-- 安全验证有关配置
security:
authorization: enabled --是否打开用户名密码验证
配置文件实例
- 编写配置文件
vim /mongodb/conf/mongo.conf
systemLog:
destination: file
path: "/mongodb/log/mongodb.log"
logAppend: true
storage:
journal:
enabled: true
dbPath: "/mongodb/data/"
processManagement:
fork: true
net:
port: 27017
bindIp: 192.168.184.128,127.0.0.1
- 重启mongodb
mongod -f /mongodb/conf/mongo.conf --shutdown
mongod -f /mongodb/conf/mongo.conf
mongodb 使用systemd管理
[root@localhost ~]# cat > /etc/systemd/system/mongod.service <<EOF
[Unit]
Description=mongodb
After=network.target remote-fs.target nss-lookup.target
[Service]
User=mongod
Type=forking
ExecStart=/mongodb/bin/mongod --config /mongodb/conf/mongo.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/mongodb/bin/mongod --config /mongodb/conf/mongo.conf --shutdown
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
[root@localhost ~]# pkill mongod
[root@localhost ~]# systemctl restart mongod
[root@localhost ~]# systemctl stop mongod
[root@localhost ~]# systemctl start mongod
连接mongodb
[mongod@localhost ~]$ mongo
MongoDB shell version v3.6.23
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("a7264847-b452-42d7-b8ab-624170cc3b74") }
MongoDB server version: 3.6.23
Server has startup warnings:
2021-12-17T17:13:51.198+0800 I CONTROL [initandlisten]
2021-12-17T17:13:51.198+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2021-12-17T17:13:51.198+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2021-12-17T17:13:51.198+0800 I CONTROL [initandlisten]
> show databases;
admin 0.000GB
config 0.000GB
local 0.000GB
> quit()
MongoDB基础操作介绍
db.命令
- DB级别命令
db:查看当前所在的库
db.help():查看你db命令的帮助
db.[tab]:类似于linux中的tab补齐命令
- collection级别操作
db.createCollection(“xxyy”):创建一个xxyy表
- document级别操作
db.xxyy.insert():在xxyy表中插入数据
常用操作
--查看当前DB版本
db.version()
--显示当前数据库
db
--查询所有数据库
show dbs
--切换数据库
use xxyy
--查看所有collection
show tables;
--查看当前数据库的状态
db.stats()
--查看当前数据库连接机器地址
db.getMongo()
对于逻辑对象的操作
库的操作
- 创建数据库:
当use的时候,系统会自动创建一个数据库。
如果use之后没有创建任何合集
系统就会删除这个数据库- 删除数据库
如果没有选择任何数据库,系统会删除默认的test库
集合的操作
- 方法1:
app> db.createCollection(‘a’)
{ “ok” : 1 }
app> db.createCollection(‘b’)- 方法2:当插入一个文档的时候,一个集合就会自动创建。
use oldboy
db.test.insert({name:“zhangsan”})
db.stu.insert({id:101,name:“zhangsan”,age:20,gender:“m”})
show tables;
db.stu.insert({id:102,name:“lisi”})
db.stu.insert({a:“b”,c:“d”})
db.stu.insert({a:1,c:2})
查询数据
> db.xxyy.find()
{ "_id" : ObjectId("61bea4147e7dcbf699f60bec"), "id" : "1", "name" : "xiao" }
{ "_id" : ObjectId("61bea4c47e7dcbf699f60bed"), "id" : "2", "name" : "yun", "age" : "18" }
> db.xxyy.find({"name":"xiao"})
{ "_id" : ObjectId("61bea4147e7dcbf699f60bec"), "id" : "1", "name" : "xiao" }
> db.xxyy.find({"name":"xiao"}).pretty()
{
"_id" : ObjectId("61bea4147e7dcbf699f60bec"),
"id" : "1",
"name" : "xiao"
}
#批量插入数
for(i=0;i<10000;i++){db.log.insert({"uid":i,"name":"mongodb","age":6,"date":new
Date()})}
db.log.find() //查询表中所有的记录
默认显示20条记录
DBQuery.shellBatchSize=50; //每页显示50条记录
db.log.findOne() //查看看第一条记录
db.log.count() //查询总的记录数
用户管理
注意:
验证库,建立用户时use到的库,在使用用户时,要加上验证库才能登陆。
对于管理员用户必须在admin下创建。
1、将用户时,use到的库,就是此用户的验证库
2、登录时,必须明确指定验证库才能登录
3、通常,管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库
4、如果直接登录到数据库,不进行use,默认的验证库是test,不是我们生产建议的
用户创建语法
use admin
db.createUser
{
user: "<name>",
pwd: "<cleartext password>",
roles: [
{ role: "<role>",
db: "<database>" } | "<role>",
...
]
}
基本语法说明:
user:用户名
pwd:密码
roles:
role:角色名
db:作用对象
role:root, readWrite,read
用户管理例子
- 创建超级管理员:管理所有数据库(必须use admin再去创建)
[mongod@test01 ~]$ mongo
MongoDB shell version v3.6.23
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("5cf26849-2363-46ff-b059-46d13660f229") }
MongoDB server version: 3.6.23
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:
2021-12-19T21:14:39.159+0800 I CONTROL [initandlisten]
2021-12-19T21:14:39.159+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2021-12-19T21:14:39.159+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2021-12-19T21:14:39.159+0800 I CONTROL [initandlisten]
> use admin
switched to db admin
> db.createUser(
... {
... user: "root",
... pwd: "root123",
... roles: [ { role: "root", db: "admin" } ]
... }
... )
Successfully added user: {
"user" : "root",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
#验证用户
> db.auth('root','root123')
1
- 配置文件中,加入以下配置
[mongod@test01 ~]$ vim /mongodb/conf/mongo.conf
systemLog:
destination: file
path: "/mongodb/log/mongodb.log"
logAppend: true
storage:
journal:
enabled: true
dbPath: "/mongodb/data/"
processManagement:
fork: true
net:
port: 27017
bindIp: 192.168.184.128,127.0.0.1
#加入下面两行配置
security:
authorization: enabled
[root@test01 ~]# systemctl restart mongod.service
- 登录验证
[mongod@test01 ~]$ mongo -uroot -proot123 192.168.184.128/admin
MongoDB shell version v3.6.23
connecting to: mongodb://192.168.184.128:27017/admin?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("687bb1bb-ce42-49c5-872b-93b5121058ca") }
MongoDB server version: 3.6.23
> db
admin
#查看用户
> db.system.users.find().pretty()
{
"_id" : "admin.root",
"userId" : UUID("c1657d41-29e1-4b0f-a300-51074e5b24c2"),
"user" : "root",
"db" : "admin",
"credentials" : {
"SCRAM-SHA-1" : {
"iterationCount" : 10000,
"salt" : "93+zx54hy1VtC+lryTRnQQ==",
"storedKey" : "Q+YIp+cqzben/3j+HDORcyvNEE0=",
"serverKey" : "9ZKB1sB81uQtCiTffMGpdlN4Heg="
}
},
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
- 创建应用用户
> use xcn
switched to db xcn
> db.createUser(
... {
... user: "app01",
... pwd: "app01",
... roles: [ { role: "readWrite" , db: "xcn" } ]
... }
... )
Successfully added user: {
"user" : "app01",
"roles" : [
{
"role" : "readWrite",
"db" : "xcn"
}
]
}
[mongod@test01 ~]$ mongo -uapp01 -papp01 xcn
MongoDB shell version v3.6.23
connecting to: mongodb://127.0.0.1:27017/xcn?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("0ed592f1-bbc4-4ccf-8a18-dd66778d1811") }
MongoDB server version: 3.6.23
> db
xcn
- 创建一个用户对于xcn库可读可写,对于test库可读
use xcn
db.createUser(
{
user: "app02",
pwd: "app02",
roles: [ { role: "readWrite" , db: "xcn" } ,
{ role: "read" , db: "test" }
]
}
)
- 删除用户
[mongod@test01 ~]$ mongo -uroot -proot123 192.168.184.128/admin
> use xcn
switched to db xcn
> db.dropUser("app02")
true
MongoDB复制集RS
基本原理
6.1 基本原理
基本构成是1主2从的结构,自带互相监控投票机制(Raft(MongoDB) Paxos(mysql MGR 用的是变种))
如果发生主库宕机,复制集内部会进行投票选举,选择一个新的主库替代原有主库对外提供服务。同时复制集会自动通知
客户端程序,主库已经发生切换了。应用就会连接到新的主库。
Replication Set配置过程
规划
三个以上的mongodb节点(或多实例)
端口是28017、28018、28019、28020
环境准备
- 创建mongodb目录
[root@localhost ~]# su - mongod
8020/data /mongodb/28020/logLast login: Mon Dec 20 04:57:32 CST 2021 on pts/0
[mongod@localhost ~]$ mkdir -p /mongodb/28017/conf /mongodb/28017/data /mongodb/28017/log
[mongod@localhost ~]$ mkdir -p /mongodb/28018/conf /mongodb/28018/data /mongodb/28018/log
[mongod@localhost ~]$ mkdir -p /mongodb/28019/conf /mongodb/28019/data /mongodb/28019/log
[mongod@localhost ~]$ mkdir -p /mongodb/28020/conf /mongodb/28020/data /mongodb/28020/log
- 编写配置文件
cat > /mongodb/28017/conf/mongod.conf <<EOF
systemLog:
destination: file
path: /mongodb/28017/log/mongodb.log
logAppend: true
storage:
journal:
enabled: true
dbPath: /mongodb/28017/data
directoryPerDB: true
#engine: wiredTiger
wiredTiger: #存储引擎
engineConfig:
cacheSizeGB: 1 #缓冲区域大小
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
net:
bindIp: 10.0.0.51,127.0.0.1
port: 28017
replication:
oplogSizeMB: 2048
replSetName: my_repl #复制集的名字,和生成的复制集名字一致
EOF
\cp /mongodb/28017/conf/mongod.conf /mongodb/28018/conf/
\cp /mongodb/28017/conf/mongod.conf /mongodb/28019/conf/
\cp /mongodb/28017/conf/mongod.conf /mongodb/28020/conf/
sed 's#28017#28018#g' /mongodb/28018/conf/mongod.conf -i
sed 's#28017#28019#g' /mongodb/28019/conf/mongod.conf -i
sed 's#28017#28020#g' /mongodb/28020/conf/mongod.conf -i
- 启动多实例
mongod -f /mongodb/28017/conf/mongod.conf
mongod -f /mongodb/28018/conf/mongod.conf
mongod -f /mongodb/28019/conf/mongod.conf
mongod -f /mongodb/28020/conf/mongod.conf
配置普通复制集
1主2从,从库普通从库
mongo --port 28017 admin
config = {_id: 'my_repl', members: [
{_id: 0, host: '192.168.168.132:28017'},
{_id: 1, host: '192.168.168.132:28018'},
{_id: 2, host: '192.168.168.132:28019'}]
}
rs.initiate(config)
查询复制集状态
rs.status();
1主1从1个arbiter
mongo -port 28017 admin
config = {_id: 'my_repl', members: [
{_id: 0, host: '192.168.168.132:28017'},
{_id: 1, host: '192.168.168.132:28018'},
{_id: 2, host: '192.168.168.132:28019',"arbiterOnly":true}]
}
rs.initiate(config)
复制集管理操作
查看复制集状态
rs.status(); //查看整体复制集状态
rs.isMaster(); // 查看当前是否是主节点
rs.conf(); //查看复制集配置信息
添加删除节点
rs.remove("ip:port"); // 删除一个节点
rs.add("ip:port"); // 新增从节点
rs.addArb("ip:port"); // 新增仲裁节点
操作实例,添加arbiter节点
- 连接到主节点
mongo -port 28017 admin
- 添加仲裁节点
my_repl:PRIMARY> rs.addArb("192.168.168.132:28020")
- 查看节点状态
my_repl:PRIMARY> rs.isMaster()
{
"hosts" : [
"192.168.168.132:28017",
"192.168.168.132:28018",
"192.168.168.132:28019"
],
"arbiters" : [
"192.168.168.132:28020"
],
- 删除一个子节点
my_repl:PRIMARY> rs.remove("192.168.168.132:28019")
特殊从节点
介绍
arbiter节点:主要负责选主过程中的投票,但是不存储任何数据,也不提供任何服务
hidden节点:隐藏节点,不参与选主,也不对外提供服务。
delay节点:延时节点,数据落后于主库一段时间,因为数据是延时的,也不应该提供服务或参与选主,所以通常会配合hidden(隐藏)
一般情况下会将delay+hidden一起配置使用
配置延时节点
- 添加一个节点
my_repl:PRIMARY> rs.add("192.168.168.132:28019")
- 配置延时节点
my_repl:PRIMARY> cfg=rs.conf()
my_repl:PRIMARY> cfg.members[3].priority=0
my_repl:PRIMARY> cfg.members[3].hidden=true
my_repl:PRIMARY> cfg.members[3].slaveDelay=120
my_repl:PRIMARY> rs.reconfig(cfg)
#备注:
#cfg.members[3]:3是需要修改哪个节点,rs.conf() 查看从上到下数是第一个就填几,从0开始数
- 取消以上配置
cfg=rs.conf()
cfg.members[3].priority=1
cfg.members[3].hidden=false
cfg.members[3].slaveDelay=0
rs.reconfig(cfg)
MongoDB Sharding Cluster 分片集群
规划
10个实例:38017-38026
(1)configserver:38018-38020
3台构成的复制集(1主两从,不支持arbiter)38018-38020(复制集名字configsvr)
(2)shard节点:
sh1:38021-23 (1主两从,其中一个节点为arbiter,复制集名字sh1)
sh2:38024-26 (1主两从,其中一个节点为arbiter,复制集名字sh2)
(3) mongos:
38017
Shard节点配置
- 创建目录
mkdir -p /mongodb/38021/conf /mongodb/38021/log /mongodb/38021/data
mkdir -p /mongodb/38022/conf /mongodb/38022/log /mongodb/38022/data
mkdir -p /mongodb/38023/conf /mongodb/38023/log /mongodb/38023/data
mkdir -p /mongodb/38024/conf /mongodb/38024/log /mongodb/38024/data
mkdir -p /mongodb/38025/conf /mongodb/38025/log /mongodb/38025/data
mkdir -p /mongodb/38026/conf /mongodb/38026/log /mongodb/38026/data
- 修改配置文件
- 第一组复制集搭建:21-23(1主 1从 1Arb)
cat > /mongodb/38021/conf/mongodb.conf <<EOF
systemLog:
destination: file
path: /mongodb/38021/log/mongodb.log
logAppend: true
storage:
journal:
enabled: true
dbPath: /mongodb/38021/data
directoryPerDB: true
#engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
net:
bindIp: 192.168.168.132,127.0.0.1
port: 38021
replication:
oplogSizeMB: 2048
replSetName: sh1
sharding:
clusterRole: shardsvr #配置集群当中的角色
processManagement:
fork: true
EOF
[mongod@localhost ~]$ cp /mongodb/38021/conf/mongodb.conf /mongodb/38022/conf/
[mongod@localhost ~]$ cp /mongodb/38021/conf/mongodb.conf /mongodb/38023/conf/
[mongod@localhost ~]$ sed 's#38021#38022#g' /mongodb/38022/conf/mongodb.conf -i
[mongod@localhost ~]$ sed 's#38021#38023#g' /mongodb/38023/conf/mongodb.conf -i
- 第二组节点:24-26(1主1从1Arb)
cat > /mongodb/38024/conf/mongodb.conf <<EOF
systemLog:
destination: file
path: /mongodb/38024/log/mongodb.log
logAppend: true
storage:
journal:
enabled: true
dbPath: /mongodb/38024/data
directoryPerDB: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
net:
bindIp: 192.168.168.132,127.0.0.1
port: 38024
replication:
oplogSizeMB: 2048
replSetName: sh2
sharding:
clusterRole: shardsvr
processManagement:
fork: true
EOF
[mongod@localhost ~]$ cp /mongodb/38024/conf/mongodb.conf /mongodb/38025/conf/
[mongod@localhost ~]$ cp /mongodb/38024/conf/mongodb.conf /mongodb/38026/conf/
[mongod@localhost ~]$ sed 's#38024#38025#g' /mongodb/38025/conf/mongodb.conf -i
[mongod@localhost ~]$ sed 's#38024#38026#g' /mongodb/38026/conf/mongodb.conf -i
- 启动所有节点,并搭建复制集
mongod -f /mongodb/38021/conf/mongodb.conf
mongod -f /mongodb/38022/conf/mongodb.conf
mongod -f /mongodb/38023/conf/mongodb.conf
mongod -f /mongodb/38024/conf/mongodb.conf
mongod -f /mongodb/38025/conf/mongodb.conf
mongod -f /mongodb/38026/conf/mongodb.conf
mongo --port 38021 admin
config = {_id: 'sh1', members: [
{_id: 0, host: '192.168.168.132:38021'},
{_id: 1, host: '192.168.168.132:38022'},
{_id: 2, host: '192.168.168.132:38023',"arbiterOnly":true}]
}
rs.initiate(config)
mongo --port 38024 admin
config = {_id: 'sh2', members: [
{_id: 0, host: '192.168.168.132:38024'},
{_id: 1, host: '192.168.168.132:38025'},
{_id: 2, host: '192.168.168.132:38026',"arbiterOnly":true}]
}
rs.initiate(config)
config节点配置
- 目录创建
mkdir -p /mongodb/38018/conf /mongodb/38018/log /mongodb/38018/data
mkdir -p /mongodb/38019/conf /mongodb/38019/log /mongodb/38019/data
mkdir -p /mongodb/38020/conf /mongodb/38020/log /mongodb/38020/data
- 修改配置文件
cat > /mongodb/38018/conf/mongodb.conf <<EOF
systemLog:
destination: file
path: /mongodb/38018/log/mongodb.conf
logAppend: true
storage:
journal:
enabled: true
dbPath: /mongodb/38018/data
directoryPerDB: true
#engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
net:
bindIp: 192.168.168.132,127.0.0.1
port: 38018
replication:
oplogSizeMB: 2048
replSetName: configReplSet
sharding:
clusterRole: configsvr
processManagement:
fork: true
EOF
[mongod@localhost ~]$ cp /mongodb/38018/conf/mongodb.conf /mongodb/38019/conf/
[mongod@localhost ~]$ cp /mongodb/38018/conf/mongodb.conf /mongodb/38020/conf/
[mongod@localhost ~]$ sed 's#38018#38019#g' /mongodb/38019/conf/mongodb.conf -i
[mongod@localhost ~]$ sed 's#38018#38020#g' /mongodb/38020/conf/mongodb.conf -i
- 启动节点,并配置复制集
mongod -f /mongodb/38018/conf/mongodb.conf
mongod -f /mongodb/38019/conf/mongodb.conf
mongod -f /mongodb/38020/conf/mongodb.conf
mongo --port 38018 admin
config = {_id: 'configReplSet', members: [
{_id: 0, host: '192.168.168.132:38018'},
{_id: 1, host: '192.168.168.132:38019'},
{_id: 2, host: '192.168.168.132:38020'}]
}
rs.initiate(config)
注:configserver不能有arbiter。
mongos节点配置
- 创建目录
mkdir -p /mongodb/38017/conf /mongodb/38017/log
- 配置文件
cat > /mongodb/38017/conf/mongos.conf <<EOF
systemLog:
destination: file
path: /mongodb/38017/log/mongos.log
logAppend: true
net:
bindIp: 192.168.168.132,127.0.0.1
port: 38017
sharding:
configDB: configReplSet/192.168.168.132:38018,192.168.168.132:38019,192.168.168.132:38020 #配置confserver
processManagement:
fork: true
EOF
- 启动mongos
mongos -f /mongodb/38017/conf/mongos.conf
分片集群添加节点
- 连接到mongs的admin数据库
mongo 192.168.168.132:38017/admin
- 添加分片
db.runCommand( { addshard : "sh1/192.168.168.132:38021,192.168.168.132:38022,192.168.168.132:38023",name:"shard1"} )
db.runCommand( { addshard : "sh2/192.168.168.132:38024,192.168.168.132:38025,192.168.168.132:38026",name:"shard2"} )
- 列出分片
db.runCommand( { listshards : 1 } )
- 整体状态查看
sh.status();
使用分片集群
RANGE分片配置及测试
- 激活数据库分片功能
db.runCommand( { enablesharding : "test" } )
- 指定分片键对集合分片
### 创建索引
use test
> db.vast.ensureIndex( { id: 1 } )
### 开启分片
use admin
> db.runCommand( { shardcollection : "test.vast",key : {id: 1} } )
- 集合分片验证
#插入数据
for(i=1;i<1000000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); }
- 分片结果测试
shard1:
mongo --port 38021
sh1:PRIMARY> db.vast.count();
shard2:
mongo --port 38024
sh2:PRIMARY> db.vast.count();
Hash分片
- 对于xcn开启分片功能
use admin
db.runCommand( { enablesharding : "xcn" } )
- 对于oldboy库下的vast表建立hash索引
use xcn
db.vast.ensureIndex( { id: "hashed" } )
- 开启分片
use admin
sh.shardCollection( "xcn.vast", { id: "hashed" } )
- 录入10w行数据测试
for(i=1;i<100000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); }
- hash分片结果测试
[mongod@localhost ~]$ mongo --port 38021
sh1:PRIMARY> use xcn
sh1:PRIMARY> db.vast.count();
10497
[mongod@localhost ~]$ mongo --port 38024
sh2:PRIMARY> use xcn
sh2:PRIMARY> db.vast.count();
16708
分片集群的查询及管理
- 判断是否Shard集群
db.runCommand({ isdbgrid : 1})
- 列出所有分片信息
db.runCommand({ listshards : 1})
- 列出开启分片的数据库
use config
db.databases.find( { "partitioned": true } )
或者
db.databases.find() //列出所有数据库分片情况
- 查看分片的片键
mongos> db.collections.find().pretty()
{
"_id" : "config.system.sessions",
"lastmodEpoch" : ObjectId("61c09ebb5e170d6cb97a9782"),
"lastmod" : ISODate("1970-02-19T17:02:47.296Z"),
"dropped" : false,
"key" : {
"_id" : 1
},
"unique" : false,
"uuid" : UUID("39841e0c-392b-4a0a-86c4-a31a5f917c73")
}
{
"_id" : "xcn.vast",
"lastmodEpoch" : ObjectId("61c0b8475e170d6cb97c0705"),
"lastmod" : ISODate("1970-02-19T17:02:47.297Z"),
"dropped" : false,
"key" : {
"id" : "hashed"
},
"unique" : false,
"uuid" : UUID("20d0cb91-befb-4223-afdf-c694ff8caad1")
}
- 查看分片的详细信息
sh.status()
- 删除分片节点
(1)确认blance是否在工作
sh.getBalancerState()
(2)删除shard2节点(谨慎)
mongos> db.runCommand( { removeShard: "shard2" } )
注意:删除操作一定会立即触发blancer(数据迁移)。
balancer操作
介绍
mongos的一个重要功能,自动巡查所有shard节点上的chunk的情况,自动做chunk迁移。
什么时候工作?
1、自动运行,会检测系统不繁忙的时候做迁移
2、在做节点删除的时候,立即开始迁移工作
3、balancer只能在预设定的时间窗口内运行
有需要时可以关闭和开启blancer(备份的时候)
mongos> sh.stopBalancer()
mongos> sh.startBalancer()
自定义 自动平衡进行的时间段
use config
sh.setBalancerState( true )
db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "3:00", stop : "5:00" } } }, true )
#检查
sh.getBalancerWindow()
sh.status()
备份恢复
备份恢复工具
(1)** mongoexport/mongoimport
(2)***** mongodump/mongorestore
备份工具区别在哪里?
mongoexport/mongoimport
导入/导出的是JSON格式或者CSV格式
1、异构平台迁移 mysql <—> mongodb
2、同平台,跨大版本:mongodb 2 ----> mongodb 3
mongodump/mongorestore
导出/导入的是BSON格式
日常备份恢复时使用.
导出工具mongoexport
mongoexport具体用法如下所示:
$ mongoexport --help
参数说明:
-h:指明数据库宿主机的IP
-u:指明数据库的用户名
-p:指明数据库的密码
-d:指明数据库的名字
-c:指明collection的名字
-f:指明要导出那些列
-o:指明到要导出的文件名
-q:指明导出数据的过滤条件
–authenticationDatabase admin
- 单表备份至json格式
[mongod@localhost ~]$ mongoexport -uroot -proot123 --port 27017 --authenticationDatabase admin -d xcn -c xxyy -o /mongodb/xxyy.json
2021-12-21T02:19:47.727+0800 connected to: localhost:27017
2021-12-21T02:19:47.728+0800 exported 2 records
[mongod@localhost ~]$ cd /mongodb/
[mongod@localhost mongodb]$ cat xxyy.json
{"_id":{"$oid":"61bea4147e7dcbf699f60bec"},"id":"1","name":"xiao"}
{"_id":{"$oid":"61bea4c47e7dcbf699f60bed"},"id":"2","name":"yun","age":"18"}
注:备份文件的名字可以自定义,默认导出了JSON格式的数据。
- 单表备份至csv格式
如果我们需要导出CSV格式的数据,则需要使用- -type=csv参数,还需要用-f指定列名
[mongod@localhost mongodb]$ mongoexport -uroot -proot123 --port 27017 --type=csv -f id,name,age --authenticationDatabase admin -d xcn -c xxyy -o /mongodb/xxyy.csv
2021-12-21T02:24:49.628+0800 connected to: localhost:27017
2021-12-21T02:24:49.630+0800 exported 2 records
[mongod@localhost mongodb]$ cat /mongodb/xxyy.csv
id,name,age
1,xiao,
2,yun,18
导入工具mongoimport
$ mongoimport --help
参数说明:
-h:指明数据库宿主机的IP
-u:指明数据库的用户名
-p:指明数据库的密码
-d:指明数据库的名字
-c:指明collection的名字
-f:指明要导入那些列
-j, --numInsertionWorkers=<number> number of insert operations to run concurrently 并发
- 恢复json格式表数据到log1
[mongod@localhost mongodb]$ mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d xcn -c xxyy1 /mongodb/xxyy.json
2021-12-21T02:29:40.830+0800 connected to: localhost:27017
2021-12-21T02:29:40.845+0800 imported 2 documents
- 恢复csv格式的文件到log2
上面演示的是导入JSON格式的文件中的内容,如果要导入CSV格式文件中的内容,则需要通过–type参数指定导入格式,具体如下所示:
#csv格式的文件头行,有列名字
mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d xcn -c xxyy2 --type=csv --headerline /mongodb/xxyy.csv
#csv格式的文件头行,没有列名字
mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d xcn -c xxyy3 --type=csv -f id,name,age /mongodb/xxyy.csv
#--headerline:指明第一行是列名,不需要导入。
异构平台迁移案例
mysql -----> mongodb
world数据库下city表进行导出,导入到mongodb
- mysql开启安全路径
echo 'secure-file-priv=/tmp' >> /etc/my.cnf
/etc/init.d/mysqld restart
- 导出mysql的city表数据
select * from world.city into outfile '/tmp/city1.csv' fields terminated by ',';
- 在mongodb中导入备份
mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d world -c city --type=csv -f ID,Name,CountryCode,District,Population /tmp/city1.csv
- 检查
[mongod@localhost ~]$ mongo -uroot -proot123 --port 27017
MongoDB shell version v3.6.23
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("5dad4f0c-162a-416c-9e6e-9f1d903b17a4") }
MongoDB server version: 3.6.23
Server has startup warnings:
2021-12-21T02:18:23.497+0800 I CONTROL [initandlisten]
2021-12-21T02:18:23.497+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2021-12-21T02:18:23.497+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2021-12-21T02:18:23.497+0800 I CONTROL [initandlisten]
2021-12-21T02:18:23.497+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2021-12-21T02:18:23.497+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2021-12-21T02:18:23.497+0800 I CONTROL [initandlisten]
> use admin
switched to db admin
> show dbs;
admin 0.000GB
config 0.000GB
local 0.000GB
world 0.000GB
xcn 0.000GB
> use world
switched to db world
> show tables;
city
> db.city.find()
{ "_id" : ObjectId("61c0d041934bd76fc66997d3"), "ID" : 1, "Name" : "Kabul", "CountryCode" : "AFG", "District" : "Kabol", "Population" : 1780000 }
{ "_id" : ObjectId("61c0d041934bd76fc66997d4"), "ID" : 2, "Name" : "Qandahar", "CountryCode" : "AFG", "District" : "Qandahar", "Population" : 237500 }
{ "_id" : ObjectId("61c0d041934bd76fc66997d5"), "ID" : 3, "Name" : "Herat", "CountryCode" : "AFG", "District" : "Herat", "Population" : 186800 }
{ "_id" : ObjectId("61c0d041934bd76fc66997d6"), "ID" : 4, "Name" : "Mazar-e-Sharif", "CountryCode" : "AFG", "District" : "Balkh", "Population" : 127800 }
{ "_id" : ObjectId("61c0d041934bd76fc66997d7"), "ID" : 5, "Name" : "Amsterdam", "CountryCode" : "NLD", "District" : "Noord-Holland", "Population" : 731200 }
{ "_id" : ObjectId("61c0d041934bd76fc66997d8"), "ID" : 6, "Name" : "Rotterdam", "CountryCode" : "NLD", "District" : "Zuid-Holland", "Population" : 593321 }
{ "_id" : ObjectId("61c0d041934bd76fc66997d9"), "ID" : 7, "Name" : "Haag", "CountryCode" : "NLD", "District" : "Zuid-Holland", "Population" : 440900 }
{ "_id" : ObjectId("61c0d041934bd76fc66997da"), "ID" : 8, "Name" : "Utrecht", "CountryCode" : "NLD", "District" : "Utrecht", "Population" : 234323 }
{ "_id" : ObjectId("61c0d041934bd76fc66997db"), "ID" : 9, "Name" : "Eindhoven", "CountryCode" : "NLD", "District" : "Noord-Brabant", "Population" : 201843 }
{ "_id" : ObjectId("61c0d041934bd76fc66997dc"), "ID" : 10, "Name" : "Tilburg", "CountryCode" : "NLD", "District" : "Noord-Brabant", "Population" : 193238 }
{ "_id" : ObjectId("61c0d041934bd76fc66997dd"), "ID" : 11, "Name" : "Groningen", "CountryCode" : "NLD", "District" : "Groningen", "Population" : 172701 }
{ "_id" : ObjectId("61c0d041934bd76fc66997de"), "ID" : 12, "Name" : "Breda", "CountryCode" : "NLD", "District" : "Noord-Brabant", "Population" : 160398 }
{ "_id" : ObjectId("61c0d041934bd76fc66997df"), "ID" : 13, "Name" : "Apeldoorn", "CountryCode" : "NLD", "District" : "Gelderland", "Population" : 153491 }
{ "_id" : ObjectId("61c0d041934bd76fc66997e0"), "ID" : 14, "Name" : "Nijmegen", "CountryCode" : "NLD", "District" : "Gelderland", "Population" : 152463 }
{ "_id" : ObjectId("61c0d041934bd76fc66997e1"), "ID" : 15, "Name" : "Enschede", "CountryCode" : "NLD", "District" : "Overijssel", "Population" : 149544 }
{ "_id" : ObjectId("61c0d041934bd76fc66997e2"), "ID" : 16, "Name" : "Haarlem", "CountryCode" : "NLD", "District" : "Noord-Holland", "Population" : 148772 }
{ "_id" : ObjectId("61c0d041934bd76fc66997e3"), "ID" : 17, "Name" : "Almere", "CountryCode" : "NLD", "District" : "Flevoland", "Population" : 142465 }
{ "_id" : ObjectId("61c0d041934bd76fc66997e4"), "ID" : 18, "Name" : "Arnhem", "CountryCode" : "NLD", "District" : "Gelderland", "Population" : 138020 }
{ "_id" : ObjectId("61c0d041934bd76fc66997e5"), "ID" : 19, "Name" : "Zaanstad", "CountryCode" : "NLD", "District" : "Noord-Holland", "Population" : 135621 }
{ "_id" : ObjectId("61c0d041934bd76fc66997e6"), "ID" : 20, "Name" : "´s-Hertogenbosch", "CountryCode" : "NLD", "District" : "Noord-Brabant", "Population" : 129170 }
Type "it" for more
mongodump和mongorestore
介绍
mongodump能够在Mongodb运行时进行备份,它的工作原理是对运行的Mongodb做查询,然后将所有查到的文档写入磁盘。
但是存在的问题时使用mongodump产生的备份不一定是数据库的实时快照,如果我们在备份时对数据库进行了写入操作,
则备份出来的文件可能不完全和Mongodb实时数据相等。另外在备份时可能会对其它客户端性能产生不利的影响。
mongodump用法
$ mongodump --help
参数说明:
-h:指明数据库宿主机的IP
-u:指明数据库的用户名
-p:指明数据库的密码
-d:指明数据库的名字
-c:指明collection的名字
-o:指明到要导出的文件名
-q:指明导出数据的过滤条件
-j, --numParallelCollections= number of collections to dump in parallel (4 by default)
–oplog 备份的同时备份oplog,这是replica set或者master/slave模式专用
mongodump和mongorestore基本使用
- 全库备份
mongodump -uroot -proot123 --port 27017 --authenticationDatabase admin -o /mongodb/backup
- 备份world库
mongodump -uroot -proot123 --port 27017 --authenticationDatabase admin -d world -o /mongodb/backup/
- 备份xcn库下的xxyy集合
mongodump -uroot -proot123 --port 27017 --authenticationDatabase admin -d xcn -c xxyy -o /mongodb/backup/
- 压缩备份
mongodump -uroot -proot123 --port 27017 --authenticationDatabase admin -o /mongodb/backup --gzip
- 恢复world库
mongorestore -uroot -proot123 --port 27017 --authenticationDatabase admin -d world1 --gzip /mongodb/backup/world
- 恢复xcn库下的xxyy集合
mongorestore -uroot -proot123 --port 27017 --authenticationDatabase admin -d xcn -c xxyy6 --gzip /mongodb/backup/xcn/xxyy.bson.gz
mongodump和mongorestore高级应用(- -oplog)
oplog介绍
在replica set中oplog是一个定容集合(capped collection),它的默认大小是磁盘空间的5%(可以通过–oplogSizeMB参数修改).
位于local库的db.oplog.rs。
其中记录的是整个mongod实例一段时间内数据库的所有变更(插入/更新/删除)操作。
当空间用完时新记录自动覆盖最老的记录。
其覆盖范围被称作oplog时间窗口。需要注意的是,因为oplog是一个定容集合,
所以时间窗口能覆盖的范围会因为你单位时间内的更新次数不同而变化。
use local
db.oplog.rs.find().pretty()
“ts” : Timestamp(1553597844, 1),
“op” : “n”
“o” :
op列后面字母的意思:
“i”: insert
“u”: update
“d”: delete
“c”: db cmd
my_repl:PRIMARY> rs.printReplicationInfo()
configured oplog size: 2048MB <–集合大小
log length start to end: 30059secs (8.35hrs) <–预计窗口覆盖时间
oplog first event time: Mon Dec 20 2021 19:08:40 GMT+0800 (CST)
oplog last event time: Tue Dec 21 2021 03:29:39 GMT+0800 (CST)
now: Tue Dec 21 2021 03:29:49 GMT+0800 (CST)
oplog应用
#oplog 配合mongodump实现热备
mongodump --port 28017 --oplog -o /mongodb/backup
#作用介绍:--oplog 会记录备份过程中的数据变化。会以oplog.bson保存下来
#恢复
mongorestore --port 28017 --oplogReplay /mongodb/backup
oplog高级应用
背景:每天0点全备,oplog恢复窗口为48小时
某天,上午10点wo.ci 业务表被误删除。
恢复思路:
0、停应用
2、找测试库
3、恢复昨天晚上全备
4、截取全备之后到wo.ci误删除时间点的oplog,并恢复到测试库
5、将误删除表导出,恢复到生产库
- 全备数据库
- 模拟原始数据
[mongod@localhost ~]$ mongo --port 28017
MongoDB shell version v3.6.23
connecting to: mongodb://127.0.0.1:28017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("e682282b-3c06-4bdc-aa15-e8d6e17916a2") }
MongoDB server version: 3.6.23
Server has startup warnings:
2021-12-20T18:47:23.935+0800 I CONTROL [initandlisten]
2021-12-20T18:47:23.935+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2021-12-20T18:47:23.935+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2021-12-20T18:47:23.935+0800 I CONTROL [initandlisten]
2021-12-20T18:47:23.935+0800 I CONTROL [initandlisten]
2021-12-20T18:47:23.935+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2021-12-20T18:47:23.935+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2021-12-20T18:47:23.935+0800 I CONTROL [initandlisten]
2021-12-20T18:47:23.935+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2021-12-20T18:47:23.935+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2021-12-20T18:47:23.935+0800 I CONTROL [initandlisten]
my_repl:PRIMARY> use wo
switched to db wo
my_repl:PRIMARY> for(var i = 1 ;i < 20; i++) {
... db.ci.insert({a: i});
... }
WriteResult({ "nInserted" : 1 })
my_repl:PRIMARY>
my_repl:PRIMARY> show tables;
ci
- 全备
mongodump --port 28017 --oplog -o /mongodb/backup
- 再次模拟数据
db.ci1.insert({id:1})
db.ci2.insert({id:2})
- 上午10点:删除wo库下的ci表
my_repl:PRIMARY> use wo
switched to db wo
my_repl:PRIMARY> show tables;
ci
my_repl:PRIMARY> db.ci.drop()
true
my_repl:PRIMARY> show tables;
my_repl:PRIMARY>
- 备份现有的oplog.rs表
mongodump --port 28018 -d local -c oplog.rs -o /mongodb/backup
- 截取oplog并恢复到drop之前的位置
[mongod@localhost backup]$ mongo --port 28017
my_repl:PRIMARY> use local
switched to db local
my_repl:PRIMARY> db
local
my_repl:PRIMARY> db.oplog.rs.find({op:"c"}).pretty();
{
"ts" : Timestamp(1640030994, 1),
"t" : NumberLong(1),
"h" : NumberLong("-5357792803882917529"),
"v" : 2,
"op" : "c",
"ns" : "wo.$cmd",
"ui" : UUID("30d02d03-e7e6-44bb-8eb0-a1f1e7ec60cb"),
"wall" : ISODate("2021-12-20T20:09:54.422Z"),
"o" : {
"drop" : "ci"
}
}
#获取到oplog误删除时间点位置:
"ts" : Timestamp(1640030994, 1),
- 恢复备份+应用oplog
[mongod@localhost backup]$ cd /mongodb/backup/local/
[mongod@localhost local]$ ll
total 376
-rw-rw-r--. 1 mongod mongod 379076 Dec 21 04:11 oplog.rs.bson
-rw-rw-r--. 1 mongod mongod 125 Dec 21 04:11 oplog.rs.metadata.json
[mongod@localhost local]$ cp oplog.rs.bson ../oplog.bson
[mongod@localhost local]$ rm -rf /mongodb/backup/local/
[mongod@localhost local]$ mongorestore --port 28017 --oplogReplay --oplogLimit "1640030994:1" --drop /mongodb/backup/