mogodb基础与副本集(精简)

Mogodb概述

在这里插入图片描述

MongoDB 将数据存储为一个文档。MongoDB是一个基于分布式文件存储的数据库。

 FirstName="Arun", Address="St. Xavier's Road", Spouse=[{Name:"Kiran"}], Children=[{Name:"Rihit", Age:8}]. 
 FirstName="Sameer",Address="8 Gandhi Road". 
 
注意:以上数据有两个不同的文档(以"."分隔)。以这种方式存储数据即为文件存储的数据库。 MongoDB是一个面向文档的数据库。

mongo特点


1.快,分布式,高可用,大数据量
高性能: Mongodb 提供高性能的数据持久性,尤其是支持嵌入式数据模型减少数据库系统上的
I/O 操作,索引支持能快的查询,并且可以包括来嵌入式文档和数组中的键

丰富的语言查询: Mongodb支持丰富的查询语言来支持读写操作(CRUD)以及数据汇总,文本
搜索和地理空间索引

高可用性: Mongodb的复制工具,成为副本集,提供自动故障转移和数据冗余,
水平可扩展性: Mongodb提供了可扩展性,作为其核心功能的一部分,分片是将数据分,在一组
计算机上。

支持多种存储引擎: WiredTiger存储引擎和、MMAPv1存储引擎和InMemory 存储引擎


2.和mysql对比
mysql   mongo
库		库
表		集合
字段	文档

mysql存储一条数据:
id   name  age
1    xxx   28  

mongo存储一条数据:
{  
   id: 1,
   name: xxx,
   age: 28
}

{  
   id: 1,
   name: xxx,
   age: 28,
   vip: baoji 
}

{"FirstName":"ke","LastName":"me","email":"hikeme@aa"}
#(易企秀)

mongodb应用场景

https://www.zhihu.com/question/32071167

游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新

物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。

社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能

物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析

视频直播,使用 MongoDB 存储用户信息、礼物信息等

电商场景,使用 MongoDB
商城上衣和裤子两种商品,除了有共同属性,如产地、价格、材质、颜色等外,还有各自有不同的属性集,如上衣的独有属性是肩宽、胸围、袖长等,裤子的独有属性是臀围、脚口和裤长等

安装部署

 
1.安装命令
yum install libcurl openssl -y
mkdir /opt/mongo_cluster/ -p
mkdir /data/soft -p
cd /data/soft/
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.13.tgz
tar zxvf mongodb-linux-x86_64-3.6.13.tgz -C /opt/mongo_cluster/
cd /opt/mongo_cluster/
ln -s mongodb-linux-x86_64-3.6.13 mongodb
cp /opt/mongo_cluster/mongodb/bin/* /usr/local/bin/
mkdir /opt/mongo_cluster/mongo_27017/{conf,logs,pid} -p
mkdir /data/mongo_cluster/mongo_27017 -p

2.配置文件
cat > /opt/mongo_cluster/mongo_27017/conf/monogdb.conf <<EOF
systemLog:
  destination: file 
  logAppend: true 
  path: /opt/mongo_cluster/mongo_27017/logs/mongodb.log

storage:
  journal:
    enabled: true
  dbPath: /data/mongo_cluster/mongo_27017
  directoryPerDB: true

  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true

processManagement:
  fork: true
  pidFilePath: /opt/mongo_cluster/mongo_27017/pid/mongod.pid

net:
  port: 27017
  bindIp: 127.0.0.1,10.0.0.51
EOF

3.启动
mongod -f /opt/mongo_cluster/mongo_27017/conf/monogdb.conf

4.检查
ps -ef|grep mongod
netstat -lntup|grep mongod

5.登录测试
mongo db01:27017

6.关闭
2种关闭方式:
1.mongod -f /opt/mongo_cluster/mongo_27017/conf/monogdb.conf --shutdown
2.登录后操作,注意,必须使用本地IP登录
mongo localhost:27017
use admin
db.shutdownServer()

解决告警

默认启动后有很多警告:

问题1:
** WARNING: Access control is not enabled for the database.
Read and write access to data and configuration is unrestricted.

问题解决: 配置文件里添加相关参数
security: 
  authorization: enabled

问题2:
** WARNING: You are running this process as the root user, which is not recommended.
解决方法:1
useradd mongo 
chown -R mongo:mongo 
chown -R mongo:mongo /opt/mongo_cluster/
chown -R mongo:mongo /data/mongo_cluster/
su - mongo
mongod -f /opt/mongo_cluster/mongo_27017/conf/monogdb.conf
解决方法:2
解决方法2:创建systemcd启动文件
cat >/lib/systemd/system/mongod.service<<EOF
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=-f /opt/mongo_27017/conf/mongodb.conf"
ExecStart=/opt/mongodb/bin/mongod \$OPTIONS
ExecStartPre=/usr/bin/chown -R mongod:mongod /opt/mongo_27017
ExecStartPre=/usr/bin/chown -R mongod:mongod /data/mongo_27017
PermissionsStartOnly=true
PIDFile=/opt/mongo_27017/pid/mongod.pid
Type=forking
# 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 for mongod as specified in
# http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings

[Install]
WantedBy=multi-user.target
EOF

useradd mongod -M -s /sbin/nologin
systemctl daemon-reload
systemctl start mongod

问题3:
** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
We suggest setting it to 'never'
** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
We suggest setting it to 'never'

问题解决:
方法一:
https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/
方法: 
echo "never"  > /sys/kernel/mm/transparent_hugepage/enabled
echo "never"  > /sys/kernel/mm/transparent_hugepage/defrag
检查:
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag

报错小结:
1.配置文件里IP写错了
2.配置文件缩进不对
3.数据目录或配置目录权限不对
4.压缩包上传不完整,导致解压文件缺失
5.在root模式下启动的进程,然后切换到普通用户就启动不了了,因为权限不对
6.内存不足可能也起不来

基础查看命令

1.查看
db   #查看当前库在哪
show databases/show dbs
show tables/show collections
use admin  #切换库
db/select database()


2.帮助命令
Help: 显示帮助。
db.help() 显示数据库方法的帮助。
db.<collection>.help() 显示收集方法的帮助, <collection>可以是现有的集合或不存在的集合的名称。
show dbs 打印服务器上所有数据库的列表。
use <db> 将当前数据库切换到<db>。该 mongoshell 变量 db 被设置为当前数据库。
show collections 打印当前数据库的所有集合的列表
show users 打印当前数据库的用户列表。
show roles 打印用于当前数据库的用户定义和内置的所有角色的列表。
show profile 打印需要 1 毫秒或更多的五个最近的操作。有关详细信息,请参阅数据库分析器上的文档。
show databases 打印所有可用数据库的列表。
load() 执行一个 JavaScript 文件。

基本操作命令

插入命令:
1.插入单行数据
db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.test.insert({"name":"yazhang","age":28,"ad":"北京市朝阳区"})
db.test.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区"})
db.test.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区","sex":"boy"})

2.插入多行数据
db.inventory.insertMany( [
{ "item": "journal", "qty": 25, "size": { "h": 14, "w": 21, "uom": "cm" }, "status": "A" },
{ "item": "notebook", "qty": 50, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "A" },
{ "item": "paper", "qty": 100, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "D" },
{ "item": "planner", "qty": 75, "size": { "h": 22.85, "w": 30, "uom": "cm" }, "status": "D" },
{ "item": "postcard", "qty": 45, "size": { "h": 10, "w": 15.25, "uom": "cm" }, "status": "A" }
]);

查询命令:
1.查询所有数据
db.test.find()

2.查询单条数据
db.inventory.findOne()

3.按照条件查询
db.inventory.find( { status: "D" } )
db.inventory.find( {"size.uom": "in"} )
db.inventory.find( { status: "A", qty: { $lt: 30 } } )
db.inventory.find( 
	{ 
		status: "A", 
		qty: { $gt: 20 }, 
		"size.w" : { $gt: 10 }
	} 
)

db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )
db.inventory.find( 
	{ 
		$or: [ 
				{ status: "A" }, 
				{ qty: { $lt: 30 } } 
			 ] 		
	} 
)

db.inventory.find( {status: "A",$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]} )
db.inventory.find( 
	{
		status: "A",
		$or: 
			[ 
				{ qty: { $lt: 30 } }, 
				{ item: /^p/ } 
			]
	} 
)


单条更新命令:
db.inventory.updateOne(
	{ "item" : "paper" }, 
	{
		$set: { "size.uom" : "cm", "status" : "P" },
		$currentDate: { "lastModified": true }
	} 
)


多条更新命令:
db.inventory.updateMany(
		{ "qty" : { $lt: 50 } },
		{
			$set: { "size.uom" : "cm", "status": "P" },
			$currentDate : { "lastModified": true }
		} 
)

索引

普通的查询
db.test.find({"age":{ $lt: 30 }})

查看执行计划
db.test.find({"age":{ $lt: 30 }}).explain()

创建索引 
db.test.createIndex({ age: 1 }) 

查看索引
db.test.getIndexes()

再次查看执行计划
db.test.find({"age":{ $lt: 30 }}).explain()

出现IXSCAN表示走索引了

删除数据

查看数据
db.inventory.find( { "status": "D" } )

删除复合条件的一条数据
db.inventory.deleteOne({ "status": "D" })

删除复合条件的多条数据
db.inventory.deleteMany({ "status": "P" })


第八章: mongo常用工具
mongotop

mongostat
insert:每秒插入数(带*的表示复制集的从库,下同)
query:每秒查询数
update:每秒更新数
delete:每秒删除数
getmore:每秒返回的游标数
command:每秒的命令数(其中从库用管道符|将本地数据和复制数据隔开) 。
dirty: wiredtiger特有的参数,记录wiredtiger缓存中脏数据的比例。
used: wiredtiger特有的参数,记录wiredtiger缓存使用百分比。
flusher: 每个查询间隔之间的checkpoint触发次数。
Vsize:虚拟内存使用量。
res:物理内存使用量。
qrw: 客户端等待从MongoDB实例读写数据的队列长度,|隔开。
arw:执行读写操作的活跃客户端数量,|隔开。
netIn:MongoDB实例的网络进流量。
netOut:MongoDB实例的网络出流量。
conn: 连接数。
set:复制集名称。
repl:复制集中的状态。

用户认证

mongo默认存在的库
test:登录时默认存在的库

管理MongoDB有关的系统库
admin库:系统预留库,MongoDB系统管理库
local库:本地预留库,存储关键日志
config库:MongoDB配置信息库

验证库: 建立用户时use到的库,在使用用户时,要加上验证库才能登陆。
对于管理员用户,必须在admin下创建.
1. 建用户时,use到的库,就是此用户的验证库
2. 登录时,必须明确指定验证库才能登录
3. 通常,管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库
4. 如果直接登录到数据库,不进行use,默认的验证库是test,不是我们生产建议的.
5. 从3.6 版本开始,不添加bindIp参数,默认不让远程登录,只能本地管理员登录。


1.创建管理用户
use admin
db.createUser(
	{
		user: "admin",
		pwd: "123456",
		roles:[ 
					{ 
						role: "root", 
						db:"admin"
					}
			  ]
	}
)
db.getUsers()

2.修改配置文件
security: 
  authorization: enabled

3.登录测试
mongo db01:27017 -u admin -p --authenticationDatabase admin
show dbs 

4.创建普通用户
use test
db.createUser(
	{
		user: "myTester",
		pwd: "xyz123",
		roles: [ 
					{ role: "readWrite", db: "test" },
					{ role: "read", db: "test2" } 
			   ]
	} 
)

5.测试访问

5.1.先使用admin用户去创建test2的数据:
mongo db01:27017 -u admin -p 123456 --authenticationDatabase admin
use test2 
db.test2.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.test2.find() 

5.2.使用test用户去验证
切换到test库,发现可以写入和查看
mongo db01:27017 -u myTester -p xyz123 --authenticationDatabase test
use test 
db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.test.find()

切换到test2库,发现只能查看,但是不能写入
use test2 
db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.test.find()

mongo副本集

1.创建目录
mkdir -p /opt/mongo_cluster/mongo_2801{7,8,9}/{conf,logs,pid}
 
2.创建配置文件
cat>/opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf<<EOF 
systemLog:
  destination: file 
  logAppend: true 
  path: /opt/mongo_cluster/mongo_28017/logs/mongodb.log

storage:
  journal:
    enabled: true
  dbPath: /data/mongo_cluster/mongo_28017
  directoryPerDB: true

  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true

processManagement:
  fork: true
  pidFilePath: /opt/mongo_cluster/mongo_28017/pid/mongod.pid

net:
  port: 28017
  bindIp: 127.0.0.1,10.0.0.51

replication:
  oplogSizeMB: 1024 
  replSetName: linux4  
EOF 

3.复制修改其他实例的配置文件
cd /opt/mongo_cluster/
cp mongo_28017/conf/mongo_28017.conf mongo_28018/conf/mongo_28018.conf
cp mongo_28017/conf/mongo_28017.conf mongo_28019/conf/mongo_28019.conf
sed -i 's#28017#28018#g' mongo_28018/conf/mongo_28018.conf
sed -i 's#28017#28019#g' mongo_28019/conf/mongo_28019.conf

4.创建数据目录
mkdir /data/mongo_cluster/mongo_2801{7,8,9}

5.启动多实例
mongod -f /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf 
mongod -f /opt/mongo_cluster/mongo_28018/conf/mongo_28018.conf 
mongod -f /opt/mongo_cluster/mongo_28019/conf/mongo_28019.conf

6.初始化集群配置
config = {
	_id : "linux4", 
	members : [
		{_id : 0, host : " db01:28017"},
		{_id : 1, host : " db01:28018"},
		{_id : 2, host : " db01:28019"},
	] 
}
rs.initiate(config)


7.主库插入数据
db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.test.insert({"name":"yazhang","age":28,"ad":"北京市朝阳区"})
db.test.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区"})
db.test.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区","sex":"boy"})


8.从库登录验证是否可以读写
注意! 默认shell登录mongo副本集,副本是不可以读取的,提示报错如下:
linux4:SECONDARY> db.test.find()
Error: error: {
	"operationTime" : Timestamp(1567674072, 1),
	"ok" : 0,
	"errmsg" : "not master and slaveOk=false",
	"code" : 13435,
	"codeName" : "NotMasterNoSlaveOk",
	"$clusterTime" : {
		"clusterTime" : Timestamp(1567674072, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
}

解决方法:
1.登录后执行命令临时生效,退出终端后失效
rs.slaveOk()

2.写入隐藏的配置文件,每次登录都生效
[mongo@db-01 ~]$ cat .mongorc.js 
rs.slaveOk()


9.副本集常用命令
rs.status();    //查看整体复制集状态
rs.isMaster(); // 查看当前是否是主节点
rs.conf();  //查看复制集配置信息

模拟故障转移

mongod -f /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf --shutdown

故障恢复

mongod -f /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf 

副本集权重调整

1.查看当前副本集的配置信息,会发现,默认所有结点的权重都为1
rs.conf()

2.修改当前配置并且热更新
config = rs.conf()
config.members[0].priority=100
rs.reconfig(config)

3.主节点主动降级
rs.stepDown()  #只能在主节点执行

4.检查是否切换成功
rs.status()

5.恢复原始的权重
config = rs.conf()
config.members[0].priority=1
rs.reconfig(config)

添加节点

1.先创建新节点的目录
mkdir /opt/mongo_cluster/mongo_28010/{conf,logs,pid} -p
mkdir /data/mongo_cluster/mongo_28010
cd /opt/mongo_cluster/
cp mongo_28017/conf/mongo_28017.conf mongo_28010/conf/mongo_28010.conf
sed -i 's#28017#28010#g' mongo_28010/conf/mongo_28010.conf
mongod -f /opt/mongo_cluster/mongo_28010/conf/mongo_28010.conf
mongo db01:28010

2.集群配置添加新节点
rs.add("db01:28010") #在主节点操作,不能在28010本身操作

剔除节点

rs.remove("db01:28010")

增加仲裁节点

rs.addArb(("db01:28010")
#保持奇数个节点(包括主节点在内),如果是偶数个,再增加个(仲裁节点(Arb),仲裁节点可以放在任一台中,只要能与集群通信就行,因为占有资源少。

备份与恢复

两种备份工具:
1.mongoexport/mongoimport:json csv
异构平台迁移 mysql <---> mongodb
同平台,跨大版本:mongodb 2 ----> mongodb 3

2.mongodump/mongorestore
日常备份恢复时使用.

3.备份命令
mongoexport和mongoimport:
导出成json(默认导出为json格式)
mongoexport --port 28017 -d(库) test -c(表) inventory -o inventory.json

导出成csv
mongoexport --port 28017 -d test -c inventory --type=csv -f _id,item,qty,size,status -o inventory.csv

导入json命令
mongoimport --port 28017 -d test -c inventory inventory.json 

导入csv命令
mongoimport --port 28017 -d test -c inventory --type=csv --headerline --file inventory.csv


mongodump和mongorestore
备份:
mkdir backup
mongodump --port 28017 -o backup
mongodump --port 28017 -o backup --gzip 

恢复: 
mongorestore --port 28017 -d test backup/test/
mongorestore --port 28017 -d test backup/test/ --gzip 

模拟误删除恢复

操作场景:
1点:
全备 
oldzhang
mongodump --port 28017 --oplog -o backup

6点:
创建了数据库
oldzhang1 

use oldzhang1
db.test.insert({"name":"zhangya1"})

7点:
创建了数据库
oldzhang2

use oldzhang2
db.test.insert({"name":"zhangya2"})

10点:
oldzhang1被删除了
use oldzhang1
db.dropDatabase()

11点: 
写入了新的数据
use oldzhang3

11点:
停掉了负载均衡,此时没有新数据写入了

模拟恢复:
1.查找误删除的时间点并记录下来
db.oplog.rs.find({ns:"oldzhang1.$cmd"}).pretty();

时间点:
1567684132

2.备份local库
mongodump --port 28017 -d local -c oplog.rs -o backup

3.把local库里的oplog.rs替换到全备的里面
cd backup/local/
cp oplog.rs.bson ../oplog.bson
rm -rf backup/local

4.恢复到删除以前的时间点的数据
mongorestore --port 28017 --oplogReplay --oplogLimit "1567684132:1" --drop backup

5.查看数据是否被恢复
show dbs





7 --oplog -o backup

6点:
创建了数据库
oldzhang1 

use oldzhang1
db.test.insert({"name":"zhangya1"})

7点:
创建了数据库
oldzhang2

use oldzhang2
db.test.insert({"name":"zhangya2"})

10点:
oldzhang1被删除了
use oldzhang1
db.dropDatabase()

11点: 
写入了新的数据
use oldzhang3

11点:
停掉了负载均衡,此时没有新数据写入了

模拟恢复:
1.查找误删除的时间点并记录下来
db.oplog.rs.find({ns:"oldzhang1.$cmd"}).pretty();

时间点:
1567684132

2.备份local库
mongodump --port 28017 -d local -c oplog.rs -o backup

3.把local库里的oplog.rs替换到全备的里面
cd backup/local/
cp oplog.rs.bson ../oplog.bson
rm -rf backup/local

4.恢复到删除以前的时间点的数据
mongorestore --port 28017 --oplogReplay --oplogLimit "1567684132:1" --drop backup

5.查看数据是否被恢复
show dbs
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值