参考:
- https://www.mongodb.org.cn/
- https://www.runoob.com/mongodb/mongodb-tutorial.html
- https://www.cnblogs.com/chenmh/p/8681867.html
MongoDB的基本操作
MongoDB的简介和安装启动
简介
- mongodb是个非关系型数据库,但操作跟关系型数据最类似(mysql是关系型数据库)
- mongodb是面向文档存储的非关系型数据库,数据以json的格式进行存储
- mongodb可用来永久存储,也可用来缓存数据
- mongodb提供副本集和分片集群功能,操作简单
安装
方法一:基于yum源
- 配置yum源
vim /etc/yum.repos.d/mongo.repo
# 社区版
[mongodb-org-4.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.2/x86_64/
gpgcheck=0
enabled=1
# gpgkey=https://www.mongodb.org/static/pgp/server-4.2.asc
# 企业版
[mongodb-enterprise-4.2]
name=MongoDB Enterprise Repository
baseurl=https://repo.mongodb.com/yum/redhat/$releasever/mongodb-enterprise/4.2/$basearch/
gpgcheck=0
enabled=1
# gpgkey=https://www.mongodb.org/static/pgp/server-4.2.asc
- 安装
# 社区版和企业版,二选一,这里选择社区版
yum install -y mongodb-org*
# 如果指定版本和组件包,则使用如下命令
# yum install -y mongodb-org-4.2.6 mongodb-org-server-4.2.6 mongodb-org-shell-4.2.6 mongodb-org-mongos-4.2.6 mongodb-org-tools-4.2.6
# 企业版安装:
# yum install -y mongodb-enterprise
# yum install -y mongodb-enterprise-4.2.6 mongodb-enterprise-server-4.2.6 mongodb-enterprise-shell-4.2.6 mongodb-enterprise-mongos-4.2.6 mongodb-enterprise-tools-4.2.6
可以指定任何可用的MongoDB版本。但是yum
,当有新版本可用时,将升级软件包。为防止意外升级,请固定包装。要固定包,exclude
请在/etc/yum.conf
文件中添加以下指令:exclude=mongodb-org,mongodb-org-server,mongodb-org-shell,mongodb-org-mongos,mongodb-org-tools
方法二:基于文件
- 如果是局域网环境,可以下载指定版本的rpm文件进行安装
- 下载压缩包进行解压运行,社区版地址:https://www.mongodb.com/try/download/community和https://www.mongodb.com/download-center/community/releases,企业版地址:https://www.mongodb.com/try/download/enterprise和https://www.mongodb.com/download-center/enterprise/releases,选择自己想要的版本和安装方式,然后进行下载安装
# 以安装二进制文件为例(解压即运行)
cd /usr/local/src
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.1.tgz
tar -zxvf mongodb-linux-x86_64-rhel70-4.4.1.tgz
mv mongodb-linux-x86_64-rhel70-4.4.1/bin/* /usr/bin
# 验证是否安装成功
ll -h /usr/bin | grep mongo
mongod --help
mongod --version
配置
最简单的单例配置文件
# 创建数据和日志目录
mkdir -p /data/mongodb/27017/
vim /data/mongodb/27017/mongodb.conf
# 日志
systemLog:
destination: file
logAppend: true
path: /data/mongodb/27017/mongodb.log
# 存储
storage:
dbPath: /data/mongodb/27017/
journal:
enabled: true
# 进程
processManagement:
fork: true
# 网络
net:
port: 27017
bindIp: 0.0.0.0
【注意事项】:如果是公网服务器,建议监听在127.0.0.1
启动
- 启动mongodb服务器:
/usr/local/mongodb/bin/mongod -f /data/mongodb/27017/mongodb.conf
- mongodb的启动验证:
ll -h /data/mongodb/27017/ #数据文件查看
ps auxf | grep mongo #进程查看
netstat -tulnp|grep mongo #端口查看
- mongodb的关闭:
kill 关闭 #不建议,后续介绍正确的关闭方法
kill -9和突然断电可能会导致mongodb数据的丢失
bin目录下的几个文件说明
- mongo:客户端程序,连接MongoDB
- mongod:服务端程序,启动MongoDB
- mongodump:备份程序
- mongoexport:数据导出程序
- mongofiles:GridFS工具,内建的分布式文件系统
- mongoimport:数据导入程序
- mongorestore:数据恢复程序
- mongos:数据分片程序,支持数据的横向扩展
- mongostat:监视程序
从4.4版本开始,mongostat等相关工具不再随着数据库安装包一起发布了,将单独作为一个安装包发布MongoDB Database Tools project,涉及工具如下:mongoimport、mongoexport、mongodump、mongorestore、mongotop、mongostat、bsondump。如需要使用,需要单独下载安装,有rpm包和tar包两种。安装也很简单,就是复制文件到bin目录下就行了。
工具的安装命令如下:
cd /usr/local/src
wget https://repo.mongodb.org/yum/redhat/7/mongodb-org/4.2/x86_64/RPMS/mongodb-org-tools-4.2.9-1.el7.x86_64.rpm
yum localinstall -y mongodb-org-tools-4.2.9-1.el7.x86_64.rpm
MongoDB服务器的启动优化
mongodb提供一个mongo客户端,类似于mysql提供的客户端命令
mongo 127.0.0.1:27017
mongo #默认连接到127.0.0.1:27017
mongodb启动优化说明
- WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine --->
建议使用xfs的文件系统
- WARNING: Access control is not enabled for the database.Read and write access to data and configuration is unrestricted. --->
建议进行用户权限设置
- WARNING: You are running this process as the root user, which is not recommended. --->
不建议以root用户运行(此建议可以不理)
- WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.We suggest setting it to 'never' --->
建议禁止Linux的最大内存页
- WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.We suggest setting it to 'never' --->
建议禁止Linux的最大内存页
- WARNING: soft rlimits too low. rlimits set to 3895 processes, 65535 files. Number of processes should be at least 32767.5 : 0.5 times number of files.--->
建议将用户进程数修改为65535
优化
具体的系统内核参数设置可以通过命令ulimit -a
进行查看
- 打开文件数和内核进程数限制放开方式如下:
vim /etc/security/limits.conf
* - nofile 102400
* - nproc 65536
# 需要重新登录
- 禁止内存巨大页
vim /etc/rc.local
echo 'never' >/sys/kernel/mm/transparent_hugepage/enabled
echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag
chmod +x /etc/rc.d/rc.local #centos7默认rc.local没有执行权限,需要支持执行权限
# /etc/rc.d/rc.local 用于添加开机启动命令,/etc/rc.local是/etc/rc.d/rc.local的软连接
- 修改centos7默认的进程数限制
vim /etc/security/limits.d/20-nproc.conf
* soft nproc 65536 # 修改为65536
- 使用普通用户启动mongodb
useradd mongodb -s /sbin/nologin
chown -R mongodb:mongodb /data/mongodb/ /usr/local/mongodb/
su - mongodb -s /bin/bash # - 改变工作目录为mongodb的用户目录;-s 指定要执行的 shell
mongod -f /data/mongodb/27017/mongodb.conf
# 检查是否启动成功
logout # 回到root环境
ps auxf | grep mongo
MongoDB客户端基础使用
mongodb的基础概念介绍
- database:数据库
- collection:集合,类似于mysql中的表
- filed:类似于mysql中字段
- document:每行的记录
客户端
mongo客户端的命令自动提示功能(使用tab键)
查询所有的库,默认自带三个库
show dbs
show databases
mongo客户端提供一个正确关闭mongodb服务器的方法
use admin
db.shutdownServer()
数据操作
# mongodb创建库、创建集合、插入数据(key value的字典方式插入)
use shijiange #use即可,无需显式创建数据库
db.myuser.insert({ name: 'shijiange1', age:28 }) #无需显示创建collection
db.myuser.insert( {'name': 'shijiange2', age: 27} )
db.myuser.insert( {'name': 'shijiange3', age: 26} )
show dbs
# admin 0.000GB
# config 0.000GB
# local 0.000GB
# shijiange 0.000GB
show collections
# myuser
show tables
# myuser
#---------------------------------------------------------------------------
# 查询集合数据,默认有个_id
use shijiange
db.myuser.find() #查询所有数据
# { "_id" : ObjectId("5f5b33842e21a0f61eddeef6"), "name" : "shijiange1", "age" : 28 }
# { "_id" : ObjectId("5f5b341c4bffd59d8b427d3a"), "name" : "shijiange2", "age" : 27 }
# { "_id" : ObjectId("5f5b34234bffd59d8b427d3b"), "name" : "shijiange3", "age" : 26 }
db.myuser.find( { name: 'shijiange1' } )
# { "_id" : ObjectId("5f5b33842e21a0f61eddeef6"), "name" : "shijiange1", "age" : 28 }
db.myuser.find( { age: 26 } )
# { "_id" : ObjectId("5f5b34234bffd59d8b427d3b"), "name" : "shijiange3", "age" : 26 }
#---------------------------------------------------------------------------
# 删除集合数据
use shijiange
db.myuser.remove({ name: 'shijiange2' }) #有条件的删除
db.myuser.find()
# { "_id" : ObjectId("5f5b33842e21a0f61eddeef6"), "name" : "shijiange1", "age" : 28 }
# { "_id" : ObjectId("5f5b34234bffd59d8b427d3b"), "name" : "shijiange3", "age" : 26 }
db.myuser.remove( {} ) #删除数据
db.myuser.drop() #删除集合
# 集合的field虽然不需要固定,但是一般来说不这样子使用
db.myuser.insert( {age: 28} )
db.myuser.insert( {'location': 'hangzhou'} )
db.myuser.find()
# 更新集合数据
use shijiange;
db.myuser.update({ 'location': 'hangzhou' }, { $set: { 'location': 'shanghai' } })
db.myuser.update({ age: 28 }, {$set: { age: 30 }})
# 删除数据库
use shijiange
db.dropDatabase()
# 【注意】:mongodb自带的三个库不要动
MongoDB集合的多种查询方式
# collection数据准备
use shijiange
db.myuser.insert( {name:"shijiange1", age: 20} )
db.myuser.insert( {name:"shijiange2", age: 28} )
db.myuser.insert( {name:"shijiange3", age: 38} )
db.myuser.insert( {name:"zhangsan1", age: 58} )
db.myuser.insert( {name:"zhangsan2", age: 68} )
db.myuser.insert( {name:"zhangsan3", age: 25} )
# pretty易读的方式
db.myuser.find().pretty()
# 查询数据总共的记录数
db.myuser.find().count()
# limit限制条数查询
db.myuser.find()
db.myuser.find().limit(2) #查看前面两条记录
# { "_id" : ObjectId("5f5b39cefe38c3fe6a2b7f3e"), "name" : "shijiange1", "age" : 20 }
# { "_id" : ObjectId("5f5b39cefe38c3fe6a2b7f3f"), "name" : "shijiange2", "age" : 28 }
# 使用skip跳过记录
db.myuser.find().skip(2).limit(2)
# { "_id" : ObjectId("5f5b39cefe38c3fe6a2b7f40"), "name" : "shijiange3", "age" : 38 }
# { "_id" : ObjectId("5f5b39cefe38c3fe6a2b7f41"), "name" : "zhangsan1", "age" : 58 }
# mongodb分页查询(每次显示两条,递进显示)
db.myuser.find().skip(0).limit(2)
db.myuser.find().skip(2).limit(2)
db.myuser.find().skip(4).limit(2)
# 使用sort进行排序
db.myuser.find().sort({ age: 1 }) #按age升序
db.myuser.find().sort({ age: -1 }) #按age降序
# 根据字段进行数字比较查询
db.myuser.find({ age: {$lt: 30} })
# $gt:大于;$lt:小于;$gte:大于或等于;$lte:小于或等于
# 查询多种条件的组合
db.myuser.find( {name: 'shijiange1'} )
db.myuser.find( {name: 'shijiange2'} )
db.myuser.find({ $or: [ {name: 'shijiange1'},{name: 'shijiange2'} ] })
db.myuser.find({ $and: [ {name: 'shijiange1'},{age: 20} ] })
# mongodb正则查询,支持普通正则和扩展正则
db.myuser.find({ name: {$regex: "shijiange[1-9]"} }) #普通正则过滤
db.myuser.find( {"name":{$regex:"(zhangsan)"}} ) #支持分组正则
db.myuser.find({ $and: [ {name: {$regex: "shijiange[1-9]"}},{age: 20} ] })
MongoDB索引查询与建立
# mongodb数据准备
use shijiange
for(i=1; i<=500000;i++){
db.myuser.insert( {name:'mytest'+i, age:i} )
}
# mongodb有慢查询的概念,默认是超过100ms会记录慢日志mongodb.log
db.getProfilingStatus()
# { "was" : 0, "slowms" : 100, "sampleRate" : 1 } # 100为100ms
# 查询age为9999的,查看扫描的行数
# tail -f /data/mongodb/27017/mongodb.log # 在另一个终端中执行
db.myuser.find( {age:9999} )
db.myuser.find( {age:9999} ).explain(true) #使用explain可以查看是否全表扫描
# 每查询一次,会多出如下一条日志记录:
# {"t":{"$date":"2020-09-11T17:24:01.364+08:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn3","msg":"Slow query","attr":{"type":"command","ns":"shijiange.myuser","appName":"MongoDB Shell","command":{"find":"myuser","filter":{"age":9999.0},"lsid":{"id":{"$uuid":"b6e162bc-a7d7-4efb-9d6f-e717606b8f67"}},"$db":"shijiange"},"planSummary":"COLLSCAN","keysExamined":0,"docsExamined":500000,"cursorExhausted":true,"numYields":500,"nreturned":1,"queryHash":"3838C5F3","planCacheKey":"3838C5F3","reslen":164,"locks":{"ReplicationStateTransition":{"acquireCount":{"w":501}},"Global":{"acquireCount":{"r":501}},"Database":{"acquireCount":{"r":501}},"Collection":{"acquireCount":{"r":501}},"Mutex":{"acquireCount":{"r":1}}},"storage":{},"protocol":"op_msg","durationMillis":137}}
# 添加索引,加快查询
db.myuser.getIndexes() #获取当前索引,默认有_id的索引,所以用_id查是比较快
db.myuser.ensureIndex( {age:1} ) #增加age的升序索引
db.myuser.getIndexes()
db.myuser.find( {age:9999} )
db.myuser.find( {age:9999} ).explain(true)
db.myuser.dropIndex( {age:1} ) #删除索引
# 使用正则的话,索引无效果
db.myuser.find( {"name":"mytest1"} )
db.myuser.ensureIndex( {name:1} ) #添加索引
db.myuser.find( {"name":"mytest6"} )
db.myuser.find( {"name":/99999/} )
db.myuser.find( {"name":/99999/} ).explain(true) #使用正则,全表扫描,也是慢
# mongodb建立唯一索引,唯一索引对应的值不能重复
use shijiange
db.myuser.insert( {userid:1} )
db.myuser.insert( {userid:1} ) # 此时没有建立唯一索引,是可以插入重复值的
db.myuser.remove({}) #清空数据
db.myuser.ensureIndex( {userid:1},{unique:true} ) #创建唯一索引
db.myuser.insert( {userid:1} )
db.myuser.insert( {userid:2} )
db.myuser.insert( {userid:1} ) #因为是唯一索引,所以会报错
MongoDB数据库的监控命令
mongostat可以实时监控mongodb的状态,一直刷新输出
mongostat --help
mongostat -h 127.0.0.1:27017
mongostat # 默认监控127.0.0.1:27017
# 测试脚本
use shijiange
for(i=1; i<=300000;i++){
db.myuser.insert( {name:'mytest'+i, age:i} )
}
# mongodb监控之serverStatus。serverStatus可用来获取mongodb的状态信息
db.serverStatus() #查看所有的监控信息
db.serverStatus().network #单独查看网络流量信息
db.serverStatus().opcounters #统计增、删、改、查的次数
db.serverStatus().connections #连接
# 使用非交互式shell进行获取
echo 'db.serverStatus()' | mongo
echo 'db.serverStatus().opcounters' | mongo
MongoDB副本集
mongodb单台服务器,数据会有丢失的风险,且单台服务器无法做高可用性。
mongodb副本集能够预防数据丢失,多台mongodb数据一致,mongodb副本集能够在有问题的时候自动切换。
MongoDB副本集的搭建
实验环境介绍:使用3台服务器实战mongodb副本集,生产环境中建议至少三台服务器
3台服务器的ip为:192.168.1.202、192.168.1.203、192.168.1.204
mongodb副本集配置文件
# 配置文件
vim /data/mongodb/27017/mongodb.conf
# 日志
systemLog:
destination: file
logAppend: true
path: /data/mongodb/27017/mongodb.log
# 存储
storage:
dbPath: /data/mongodb/27017/
journal:
enabled: true
# 进程
processManagement:
fork: true
# 网络
net:
port: 27017
bindIp: 0.0.0.0
# 副本集
replication:
replSetName: shijiange # 目前MongoDB提供了三种Replication方式:Matser/Matser, Matser/Slave,Replica Sets
启动3个mongodb服务器
需要对应更改端口、数据目录、日志路径
# 192.168.1.202、192.168.1.203、192.168.1.204
su - mongodb -s /bin/bash
mongod -f /data/mongodb/27017/mongodb.conf
mongodb副本集的初始化及其状态查看
# 192.168.1.202,只需要在其中一台上进行初始化即可
mongo
use admin
config = { _id:"shijiange", members:[
{_id:0,host:"192.168.1.202:27017"},
{_id:1,host:"192.168.1.203:27017"},
{_id:2,host:"192.168.1.204:27017"}]
}
rs.initiate( config ) #副本集初始化,需要一定时间
rs.status() #副本集状态,一个PRIMARY(192.168.1.202),其它SECONDARY。PRIMARY是主,只有PRIMARY能写入
# 测试副本集的数据同步
# 在PRIMARY那台机器上
mongo
use shijiange
db.myuser.insert( {name:"shijiange1", age: 20} )
db.myuser.insert( {name:"shijiange2", age: 28} )
db.myuser.insert( {name:"shijiange3", age: 38} )
db.myuser.insert( {name:"zhangsan1", age: 58} )
db.myuser.insert( {name:"zhangsan2", age: 68} )
db.myuser.insert( {name:"zhangsan3", age: 25} )
# 在SECONDARY机器上查看
rs.secondaryOk() #4.4版本是rs.secondaryOk(),4.0版本是rs.slaveOk()。SECONDARY需要声明是slave才能查看数据【从库无法插入数据】
use shijiange
db.myuser.find()
# 查看slave的延时情况(所有机器都可以执行)
rs.printSlaveReplicationInfo()
MongoDB副本集故障自动切换
mongodb的副本集当primary挂了,会挑选其中的一台secondary升为主。挑选其中一台secondary升级为primary的条件是剩下的集群台数>=2,如果集群只剩下一个实例的话,会有异常。
#mongodb副本集自动切换演示
mongo #连接到primary
use admin
db.shutdownServer() #关闭主mongodb,会有其它mongodb提升为主。插入数据正常
# 关闭第二台
mongo
use admin
db.shutdownServer() #关闭两台mongodb的话,剩下一台不会提升为primary,插入数据将异常
# 同时启动192.168.1.202和192.168.1.203,没有固定的主,可通过优先级指定primary
mongod -f /data/mongodb/27017/mongodb.conf
MongoDB副本集的优先级
primary的选举依赖于各个实例的优先权重,默认权重都是1。副本集的主挑选权重最高的,权重一样的无法控制谁为主。
设置各个实例的优先权重,挑选自己想要的实例为主,只有primary可以更改权重配置。
conf = rs.config() #获取副本集的配置,默认权重都是1
conf.members[0].priority = 5 #索引号从0开始,每次递增1,类似数组(目前这台为primary)
conf.members[1].priority = 10
conf.members[2].priority = 15 # 让这台变成primary
rs.reconfig(conf) #更新mongodb副本集的配置,优先权重最高的提升为primary,关闭启动后也为主
MongoDB副本集的伸缩
mongodb副本集的扩展非常好,往副本集里添加实例和移除实例都非常方便。往mongodb副本集添加实例数据能够自动同步,无需人工干预。
# 往现有mongodb副本集中添加实例
# 创建mongodb_4(192.168.1.205)实例,配置和前三台机器一样(虚拟机克隆),注意副本集名称要保持一致replSetName: shijiange
# 连接primary(192.168.1.202)
mongo
use admin
rs.add('192.168.1.205:27017') #数据是自动同步
# rs.add的优先权重默认为1,id是顺序递增的
# 从mongodb副本集中移除实例,不可移除primary
use admin
rs.remove('192.168.1.204:27017') # 状态由secondary变成other
# 副本集经过添加删除后顺序会乱,设置权重需要注意
rs.config() #获取到后,需要注意每个实例的位置。id不改变,即移除2之后,3不会变成2
MongoDB的备份和恢复
单台服务器一定需要备份,mongodump工具用来备份数据,mongorestore工具用来恢复数据。
mongodb备份说明需要指定ip和端口,单台服务器直接使用mongodump进行备份,副本集需要连接到primary上备份。
# 数据清空,启动单台mongodb(192.168.1.202)
vim /data/mongodb/27017/mongodb.conf
# 日志
systemLog:
destination: file
logAppend: true
path: /data/mongodb/27017/mongodb.log
# 存储
storage:
dbPath: /data/mongodb/27017/
journal:
enabled: true
# 进程
processManagement:
fork: true
# 网络
net:
port: 27017
bindIp: 0.0.0.0
mongod -f /data/mongodb/27017/mongodb.conf
mongo
use shijiange
db.myuser.insert( {name:"shijiange1", age: 20} )
db.myuser.insert( {name:"shijiange2", age: 28} )
db.myuser.insert( {name:"shijiange3", age: 38} )
db.myuser.insert( {name:"zhangsan1", age: 58} )
db.myuser.insert( {name:"zhangsan2", age: 68} )
db.myuser.insert( {name:"zhangsan3", age: 25} )
# mongodb数据库的备份,备份所有库
mkdir -p /data/mongodbbackup/
mongodump -h 127.0.0.1:27017 -o /data/mongodbbackup/ # 备份所有的库
ll -h /data/mongodbbackup/
# drwxr-xr-x 2 root root 69 9月 14 17:20 admin
# drwxr-xr-x 2 root root 53 9月 14 17:20 shijiange
# mongodb数据库的恢复
# 先删除之前的数据
mongorestore -h 127.0.0.1:27017 /data/mongodbbackup/
# 测试数据是否恢复成功
mongo
show dbs
use shijiange
db.myuser.find()
Python操作MongoDB
mongodb可以使用java、python、php等语言去操作,运维使用Python居多,介绍使用python操作Mongodb数据库。
Python简单操作MongoDB
# 使用python操作mongodb,需要使用pip安装pymongo模块
# centos7(python2)
yum -y install epel-release python2-pip
pip install pymongo
# windows(python3)
pip install pymongo
# 连接代码,单实例的连接代码
import pymongo
client = pymongo.MongoClient( '192.168.1.202', 27017 )
shijiange=client.shijiange
myuser = shijiange.myuser
for item in myuser.find():
print(item)
# runfile('C:/Users/Administrator/.spyder-py3/temp.py', wdir='C:/Users/Administrator/.spyder-py3')
# {'_id': ObjectId('5f5f355cc7bc18dcf8165033'), 'name': 'shijiange1', 'age': 20.0}
# {'_id': ObjectId('5f5f355cc7bc18dcf8165034'), 'name': 'shijiange2', 'age': 28.0}
# {'_id': ObjectId('5f5f355cc7bc18dcf8165035'), 'name': 'shijiange3', 'age': 38.0}
# {'_id': ObjectId('5f5f355cc7bc18dcf8165036'), 'name': 'zhangsan1', 'age': 58.0}
# {'_id': ObjectId('5f5f355cc7bc18dcf8165037'), 'name': 'zhangsan2', 'age': 68.0}
# {'_id': ObjectId('5f5f355dc7bc18dcf8165038'), 'name': 'zhangsan3', 'age': 25.0}
# pymongo副本集的连接代码,代码支持自动切换
import pymongo
client = pymongo.MongoClient( ['192.168.1.203:27017', '192.168.1.205:27017'] )
shijiange = client.shijiange
myuser = shijiange.myuser
myvar = {'age':20, 'name': 'shijiange'}
myuser.insert(myvar)
for item in myuser.find():
print(item)
# runfile('C:/Users/Administrator/.spyder-py3/temp.py', wdir='C:/Users/Administrator/.spyder-py3')
# {'_id': ObjectId('5f5f3076d0a7709cefe0eea6'), 'name': 'shijiange1', 'age': 20.0}
# {'_id': ObjectId('5f5f3076d0a7709cefe0eea7'), 'name': 'shijiange2', 'age': 28.0}
# {'_id': ObjectId('5f5f3076d0a7709cefe0eea9'), 'name': 'zhangsan1', 'age': 58.0}
# {'_id': ObjectId('5f5f3076d0a7709cefe0eea8'), 'name': 'shijiange3', 'age': 38.0}
# {'_id': ObjectId('5f5f3076d0a7709cefe0eeaa'), 'name': 'zhangsan2', 'age': 68.0}
# {'_id': ObjectId('5f5f307dd0a7709cefe0eeab'), 'name': 'zhangsan3', 'age': 25.0}
# {'_id': ObjectId('5f5f86463670b531ec7837c6'), 'age': 20, 'name': 'shijiange'}
Python获取MongoDB的状态信息
使用Python去监控mongodb状态,获取mongodb的serverStatus状态信息,一般状态信息需要每个实例都进行监控
# 获取状态信息
import pymongo
client = pymongo.MongoClient('192.168.1.202',27017)
db = client.admin
serverStatus = db.command('serverStatus')
print(serverStatus)
# 每个状态信息单独打印
import pymongo
client = pymongo.MongoClient('192.168.1.202',27017)
db = client.admin
serverStatus = db.command('serverStatus')
for key,value in serverStatus.items():
print(key, value)
print()
# MongoDB建议的监控方向
# connections,连接信息;network ,流量信息;opcounters,增删改查信息
# 状态信息获取
import pymongo
client = pymongo.MongoClient('192.168.1.202',27017)
db = client.admin
serverStatus = db.command('serverStatus')
print(serverStatus['connections'])
print(serverStatus['network'])
print(serverStatus['opcounters'])
MongoDB分片集群
mongodb分片一般用得比较少,需要较多的服务器,还有三种的角色,一般把mongodb的副本集应用得好就足够用了,可搭建多套mongodb副本集。
mongodb分片技术,mongodb副本集可以解决数据备份、读性能的问题,但由于mongodb副本集是每份数据都一模一样的,无法解决数据量过大问题。
mongodb分片技术能够把数据分成两份存储,假如shijiange.myuser里面有1亿条数据,分片能够实现5千万左右存储在data1,5千万左右存储在data2,data1、data2需要使用副本集的形式,预防数据丢失。
MongoDB分片集群角色
mongodb分片集群3种角色
- router角色:mongodb的路由,提供入口,使得分片集群对外透明。router不存储数据
- configsvr角色:mongodb的配置角色,存储元数据信息。分片集群后端有多份存储,读取数据该去哪个存储上读取,依赖于配置角色。配置角色建议使用副本集
- shardsvr角色:mongodb的存储角色,存储真正的数据。建议使用副本集
分片集群角色之间的依赖关系
- 当用户通过router角色插入数据时,需要从configsvr知道这份数据插入到哪个节点,然后执行插入动作插入数据到sharedsvr
- 当用户通过router角色获取数据时,需要从configsvr知道这份数据是存储在哪个节点,然后再去sharedsvr获取数据
MongoDB分片集群配置
mongodb分片集群的搭建说明:使用同一份mongodb二进制文件,修改对应的配置就能实现分片集群的搭建
mongodb分片集群实战环境搭建说明:
- router:使用
192.168.1.202
来搭建 - configsvr:使用
192.168.1.203
和192.168.1.204
来搭建 - shardsvr:使用
192.168.1.205
、192.168.1.206
、192.168.1.207
、192.168.1.208
来搭建,192.168.1.205
和192.168.1.206
为一个集群,192.168.1.207
和192.168.1.208
为一个集群
MongoDB分片集群之configsvr
# 192.168.1.203和192.168.1.204
vim /data/mongodb/27017/mongodb.conf
# 日志
systemLog:
destination: file
logAppend: true
path: /data/mongodb/27017/mongodb.log
# 存储
storage:
dbPath: /data/mongodb/27017/
journal:
enabled: true
# 进程
processManagement:
fork: true
# 网络
net:
port: 27017
bindIp: 0.0.0.0
# 副本集
replication:
replSetName: shijiangeconf
# 分片角色
sharding:
clusterRole: configsvr
# mongodb配置服务集群的启动跟单例的启动方式一致,都是使用mongod
mongod -f /data/mongodb/27017/mongodb.conf
# 分片集群的配置角色副本集搭建
mongo
config = { _id:"shijiangeconf",
configsvr: true,
members:[
{_id:0,host:"192.168.1.203:27017"},
{_id:1,host:"192.168.1.204:27017"}
]
}
rs.initiate(config)
# 在SECONDARY机器上查看
rs.secondaryOk() #4.4版本是rs.secondaryOk(),4.0版本是rs.slaveOk()
# 验证是否搭建成功(192.168.1.203、192.168.1.204)
mongo
rs.status()
MongoDB分片集群之router
router最重要的配置:指定configsvr的地址,使用configsvr副本集id(replSetName)/ip:port
的方式指定。如果配置多个router,任何一个都能正常的获取数据。
使用mongos启动,而不是mongod
vim /data/mongodb/27017/mongodb.conf
# 日志
systemLog:
destination: file
logAppend: true
path: /data/mongodb/27017/mongodb.log
# 进程
processManagement:
fork: true
# 网络
net:
port: 27017
bindIp: 0.0.0.0
# 分片角色
sharding:
configDB: shijiangeconf/192.168.1.203:27017,192.168.1.204:27017
# router的启动
mongos -f /data/mongodb/27017/mongodb.conf
# router的验证:需要等到数据角色搭建完才能够进行验证
MongoDB分片集群之sharedsvr
# 数据角色shijiangedata1:192.168.1.205和192.168.1.206
vim /data/mongodb/27017/mongodb.conf
# 日志
systemLog:
destination: file
logAppend: true
path: /data/mongodb/29017/mongodb.log
# 存储
storage:
dbPath: /data/mongodb/29017/
journal:
enabled: true
# 进程
processManagement:
fork: true
# 网络
net:
port: 27017
bindIp: 0.0.0.0
# 副本集
replication:
replSetName: shijiangedata1
# 分片
sharding:
clusterRole: shardsvr
# 数据角色shijiangedata2:192.168.1.207和192.168.1.208
vim /data/mongodb/27017/mongodb.conf
# 日志
systemLog:
destination: file
logAppend: true
path: /data/mongodb/29017/mongodb.log
# 存储
storage:
dbPath: /data/mongodb/29017/
journal:
enabled: true
# 进程
processManagement:
fork: true
# 网络
net:
port: 27017
bindIp: 0.0.0.0
# 副本集
replication:
replSetName: shijiangedata2
# 分片
sharding:
clusterRole: shardsvr
# 启动4个数据实例
mongod -f /data/mongodb/27017/mongodb.conf
# 数据角色shjiangedata1:192.168.1.205和192.168.1.206
mongo
config = { _id:"shijiangedata1",
members:[
{_id:0,host:"192.168.1.205:27017"},
{_id:1,host:"192.168.1.206:27017"}
]
}
rs.initiate(config)
# 在SECONDARY机器上查看
rs.secondaryOk() #4.4版本是rs.secondaryOk(),4.0版本是rs.slaveOk()
# 数据角色shjiangedata2:192.168.1.207和192.168.1.208
mongo
config = { _id:"shijiangedata2",
members:[
{_id:0,host:"192.168.1.207:27017"},
{_id:1,host:"192.168.1.208:27017"}
]
}
rs.initiate(config)
# 在SECONDARY机器上查看
rs.secondaryOk() #4.4版本是rs.secondaryOk(),4.0版本是rs.slaveOk()
MongoDB分片集群使用
所有的操作都是在route路由角色中
# 分片集群添加数据角色,连接到路由角色里面配置,数据角色为副本集的方式
# 在角色route(192.168.1.202)上执行
mongo
sh.addShard("shijiangedata1/192.168.1.205:27017,192.168.1.206:27017")
sh.addShard("shijiangedata2/192.168.1.207:27017,192.168.1.208:27017")
sh.status()
# 默认添加数据没有分片存储,操作都是在路由角色里面
use shijiange
for(i=1; i<=500;i++){
db.myuser.insert( {name:'mytest'+i, age:i} )
}
# 此时只有在shijiangedata2(或shijiangedata1)上有数据
db.dropDatabase() #验证完后删除
# 针对某个数据库的某个表使用hash分片存储,分片存储就会同一个colloection分配两个数据角色
use admin # 此操作只能使用admin用户执行
db.runCommand( { enablesharding :"shijiange"});
db.runCommand( { shardcollection : "shijiange.myuser",key : {_id: "hashed"} } )
# 插入数据校验,分布在两个数据角色上
use shijiange
for(i=1; i<=500;i++){
db.myuser.insert( {name:'mytest'+i, age:i} )
}
# 此时在shijiangedata2(268条)和shijiangedata1(232条)上各有250条数据