NoSQL数据库四大家族
列存储 Hbase
键值存储 Redis
图像存储 Neo4J
文档存储 MongoDB ES
NoSQL的优势
高可扩展性,分布式计算,没有复杂的关系,低成本,架构灵活,半结构化数据
Mongodb核心技术
Mongodb逻辑结构
库database
集合(collection)
文档(document)
安装部署
系统准备
redhat或centos6.2以上系统,系统开发包完整,ip地址和hosts文件解析正常,iptables防火墙和Elinux关闭,关闭大页内存机制
root用户下
在vim /etc/rc.local最后添加如下代码
if test -f /sys/kernel/mm/transparent_hugepage/enables;then
echo never >/sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kerbel/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
mongdb安装
创建所需用户和组
useradd mongod
passwd mongod
创建mongodb所需目录结构
mkdir -p /mongodb/conf
mkdir -p /mongodb/log
mkdir -p /mongodb/data
上传并解压软件到指定位置
上传到
cd /server/tools/
解压
tar xf mongodb-linux-x86_64-rhe170-3.2.16.tgz
拷贝目录下bin程序到/mongodb/bin
cp -a /server/tools/mongodb-linux-x86_64-rhe170-3.2.16/bin* /mongodb/bin
设置目录结构权限
chown -R mongodb:mongodb /mongodb
设置用户环境变量
su - mongod
vim .bash_profile
export PATH=/mongodb/bin:$PATH
source .bash_profile
启动mongodb
su - mongodb
mongodb --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --port=27017 --logappend --fork
登录mongodb
mongo
注:连接之后会warning,需要修改(使用root用户)
vim /etc/security/limits.conf
reboot重启生效
使用配置文件
YAML模式
系统日志有关
systemLog:
destination:file
path:"/mongodb/log/mongodb.log" 日志位置
logAppend:ture 日志以追加模式记录
数据存储有关
storage:
journal:
enabled:true
dbPath:"/mongodb/data"
进程控制
processManagement:
fork:true 后台守护进程
pidFilePath:<string> pid文件的位置,一般不用配置,可以去掉这行,自动生成到data中
网络配置有关
net:
bindIp:<ip> 监听地址,如果不配置这行是监听在0.0.0.0
port:<port> 端口号,默认不配置端口号是27017
安全验证有关配置
security:
authorization:enabled 是否打开用户密码验证
YANL例子
cat >/mongodb/conf/mongo.conf <<EOF
systemLog:
destination:file
path:"/mongodb/log/mongodb.log"
logAppend:true
storage:
journal:
enabled:true
dbPath:"/mongodb/data/"
processManagement:
fork:true
net:
port:27017
bindIp:10.0.0.51,127.0.0.1
EOF
mongod -f /mongodb/conf/mongo.conf --shutdown
mongod -f /mongodb/conf/mongo.conf
mongodb的关闭方式
mongod -f mongodb.conf --shutdown
systemd管理(root)
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
systemctl restart mongod
systemctl stop mongod
systemctl start mongod
mongodb常用基本操作
mongodb默认存在的库 show databases
命令种类
数据库对象(库(database),表(collection),行(document))
db命令
db 当前在的库
db.[TAB] 类似于linux中的tab功能
db.help() db级别的命令使用帮助
collection级别操作
db.Collection_name.xxx
document级别操作
db.t1.insert()
复制集有关(replication set)
rs.
分片集群(sharding cluster)
sh.
帮助
help
KEYWORD.help()
KEYWORD.[TAB]
show
use
db.help()
db.a.help()
rs.help()
sh.help()
常用操作
查看当前db版本 db.version()
显示当前数据库 db db.getName()
查询所有数据库 show dbs
切换数据库 use local
查看所有的collection show tables
显示当前数据库状态 use local db.stats()
查看当前数据库的连接机器地址 db.getMongo()
指定数据库进行连接,默认连接本机test数据库
库的操作
创建数据库
当use的时候,系统就会自动创建一个数据库,如果use之后没有创建任何集合,系统就会删除这个数据库
删除数据库
如果没有选择任何数据库,会删除默认的test数据库
show dbs
use test
db.dropDatabase()
集合的操作
创建集合
方法1:
use app
db.createCollection('a')
db.createCollection('b')
show collections
db.getCollectionNames()
方法2:当插入一个文档的时候,一个集合就会自动创建
use oldboy
db.testinsert({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.stu.find({}).pretty()
删除集合
use app
db.log.drop()
重命名集合
把log改名为log1
db.log.renameCollection("log1")
show collections
批量插入数据
for (i=0;i<10000;i++){db.log.insert({"uid":i,"name":"mongodb","age",6,"date":new Date()})}
Mongodb数据查询语句
查询集合中的记录数 db.log.find()
默认每页显示20条记录,当显示不下的情况下,可以用it迭代命令查询下一页数据
设置每页显示50条记录 DBQuery.shellBatchSize=50
查看第一条记录 db.log.findOne()
查询总的记录数 db.log.count()
删除集合中所有数据 db.log.remove({})
查询去掉当前集合中某列的重复数据 db.log.distinct("name")
查看集合存储信息 db.log.status()
集合中数据的原始大小 db.log.dataSize()
集合中索引数据的原始大小 db.log.totalIndexSize()
集合中索引+数据压缩存储之后的大小 db.log.totalSize()
集合中数据压缩存储的大小 db.log.storageSize()
用户管理
验证库,建立用户时use到的库,在使用用户时,要加上验证库才能登陆。对于管理员用户,必须在admin下创建
建用户时,use到的库就是此用户的验证库
登录时必须明确指定验证库才能登录
通常管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库
如果直接登录到数据库不进行use,默认的验证库是test,不是我们生产建议的
use admin
mongo 10.0.0.53/admin
db.createUser
{
user:"<name>",
pwd:"<cleartext password>",
roles:[
{role:"<role>",
db:"<database>"} | "<role>",
]
}
基本语法说明
user 用户名
pwd 密码
roles
role 角色名
db 作用对象
role:root,readWrite,read
验证数据库
mongo -u oldboy -p 123 10.0.0.53/oldboy
用户管理例子
创建超级管理员,管理所有数据库(必须use admin再去创建)
mongo
use admin
db.createUser(
{
user:"root",
pwd:"root123",
roles:[{role:"root",db:"admin"}]
}
)
验证用户
db.auth('root','root123')
配置文件中,加入以下配置
security:
authorization:enabled
重启mongodb
mongod -f /mongodb/conf/mongo.conf --shutdown
mongod -f /mongodb/conf/mongo.conf
登录验证
mongo -uroot -port123 admin
mongo -uroot -port123 10.0.0.53/admin
或者
mongo
use admin
db.auth('root','root123')
查看用户
use admin
db.system.users.find().pretty()
创建库管理用户
mongo -uroot -proot123 admin
use app
db.createUser(
{
user:"admin",
pwd:"admin",
roles:[{role:"dbAdmin",db:"app"}]
}
)
db.auth('admin','admin')
登录测试
mongo -uadmin -padmin 10.0.0.53/app
创建对app数据库,读,写权限的用户app01
超级管理员用户登录 mongo -uroot -proot123 admin
选择一个验证库 use app
创建用户
db.createUser(
{
user:"app01",
pwd:"app01",
roles:[{role:"readWrite",db:"app:}]
}
)
mongo -uapp01 -papp01 app
创建app数据库读写权限的用户对test数据库具有读写权限
mongo -uroot -proot123 10.0.0.53/admin
use app
db.createUser(
{
user:"app03",
pwd:"app03",
roles:[{role:"readWrite",db:"app"},{role:"read",db:"test"}]
}
)
查询mongodb中的用户信息
mongo -uroot -proot123 10.0.0.53/admin
db.system.users.find().pretty()
删除用户(root身份登录,use到验证库)
mongo -uroot -proot123 10.0.0.51/admin
use app
db.dropUser("admin")
MongoDB复制集RS(ReplicationSet)
基本原理
基本构成是1主2从的结构,自带互相监控投票机制(Raft(MongoDB)) Paxo(mysql MGR用的是变种),如果发生主库宕机,复制集内部会进行投票选举,选择一个新的主库替代原有主库对外提供服务。同时复制集会自动通知客户端程序,主库已经发生切换了。应用就会连接到新的主库
Relication Set配置过程详解
规划 3个以上的mongodb节点(或多实例)
环境准备
多个端口 28017 28018 28019 28020
多套目录
su -mongod
mkdir -p /mongodb/28017/conf /mongodb/28017/data /mongod28017/log
mkdir -p /mongodb/28018/conf /mongodb/28018/data /mongod28018/log
mkdir -p /mongodb/28019/conf /mongodb/28019/data /mongod28019/log
mkdir -p /mongodb/28020/conf /mongodb/28020/data /mongod28020/log
多套配置文件
/mongodb/28017/conf/mongod.conf
/mongodb/28018/conf/mongod.conf
/mongodb/28019/conf/mongod.conf
/mongodb/28020/conf/mongod.conf
配置文件内容
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
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/28018/conf/mongod.conf -i
sed 's#28017#28020#g' /mongodb/28018/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
netstat -lnp | grep 280
配置普通复制集
1主2从,从库普通从库
mongo --port 28017 admin
config={_id:'my_repl',members:[
{_id:0,host:'10.0.0.51:28017'},
{_id:0,host:'10.0.0.51:28017'},
{_id:0,host:'10.0.0.51:28017'}]
}
rs.initiate(config)
查询复制集状态 rs.status()
1主1从1个arbiter
mongo -port 28017
config={_id:'my_repl',members:[
{_id:0,host:'10.0.0.51:28017'},
{_id:1,host:'10.0.0.51:28018'},
{_id:2,host:'10.0.0.51: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 28018 admin
添加仲裁节点
rs.addArb("10.0.0.53:28020")
查看节点状态
rs.isMaster()
{
"hosts":[
"10.0.0.53:28017",
"10.0.0.53:28018",
"10.0.0.53:28019"
],
"arbiters":[
"10.0.0.53:28020"]
}
rs.remove("ip:port") 删除一个节点
特殊从节点
arbiter节点 主要负责选主过程中的投票,但是不存储任何数据,也不提供任何服务
hidden节点 隐藏节点,不参与选主,也不对外提供服务
delay节点 延时节点,数据落后于主库一段时间,因为数据是延时的,也不应该提供服务或参与选主,所以通常会配合hidden
一般情况下会将delay+hidden一起配置使用
配置延时节点(一般延时节点也配置成hidden)
cf=rs.conf()
cfg.members[2].priority=0
cfg.members[2].hidden=true
cfg.member[2].slaveDelay=120
rs.reconfig(cfg)
取消以上配置
cfg=rs.conf()
cfg.members[2].priority=1
cfg.members[2].hidden=false
cfg.members[2].slaveDelay=0
rs.reconfig(cfg)
配置成功后,通过以下命令查询配置后的属性
rs.conf()
分片集群
备份工具
mongoexport/mongoimport 导入/导出的是JSON格式或CSV格式
mongodump/mongorestore 导入/导出的是BSON格式
JSON可读性强但体积较大,BSON是二进制文件,体积小但几乎没有可读性
在一些mongodb版本之间,BSON格式可能会随版本不同而有所不同,所以不同版本之间用mongodump/mongorestore可能不会成功。具体要看版本之间的兼容性,当无法使用BSON进行跨版本的数据迁移的时候,使用JSON格式即mongoexport/mongoimport是一个可选项,跨版本的mongodump/mongorestore不推荐,实在要做请先检查文档看两个版本是否兼容
JSON虽然具有较好的跨版本通用性,但其只保留了数据部分,不保留索引,账户等其他基础信息,使用时应该注意
应用场景
mongoexport/mongoimport jdon/csv
异构平台迁移 mysql<-->mongodb
同平台不同版本 mongodb2<-->mongodb3
导出工具mongoexport
mongodb的mongoexport工具可以把一个collection导出成JSON格式或CSV格式的文件,可以通过参数指定导出的数据项,也可以根据指定的条件导出数据
版本差异较大,异构平台数据迁移
mongoexport --help
-h 指定数据库宿主机IP
-u 指明数据库的用户名
-p 指明数据库的密码
-d 指明数据库的名字
-c 指明collection的名字
-f 指明要导出哪些列
-o 指明到要导出的文件名
-q 指明导出数据的过滤条件
单表备份至json格式
mongoexport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log -o /mongodb/log.json
注:备份文件的名字可以自定义,默认导出了json格式的数据
单表备份至csv格式
如果我们需要导出csv格式的数据,则需要使用--type=csv参数
mongoexport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log --type=csv -f uid,name,age,date -o /mongodb/log.csv
导入工具mongoimport
mongodb中的mongoimport工具可以把一个特定格式文件中的内容导入到指定的collection中。该工具可以导入json格式数据,也可以导入csv格式数据
mongoimport --help
-h 指明数据库宿主机IP
-u 指明数据库的用户名
-p 指明数据库的密码
-d 指明数据库的名字
-c 指明collection的名字
-f 指明要导入哪些列
-j 并发导入
数据恢复
恢复json格式表数据到log1
mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log1 /mongodb/log.json
恢复数据csv格式的文件到log2
如果要导入csv格式文件中的内容,则需要通过--type参数指定导入格式
csv格式的文件头行有列名字
mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log2 --type=csv --headerline --file /mongodb/log.csv
csv格式的文件头行没有列名字
mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log3 --type=csv -f id,name,age,date --file /mongodb/log1.csv
异构平台迁移案例 mysql -->mongodb
world数据库下city表进行导出,导入到mongodb
mysql开启安全路径
secure-file-priv=/tmp
重启数据库生效
/etc/init.d/mysqld restart
导出mysql的city表数据
source /root/world.sql
select * from world.city into outfile '/tmp/city1.csv' fileds terminated by ',';
处理备份文件
desc world.city
在mongodb中导入备份
mongoimport -uroot -proot123 -port 27017 --authenticationDatabase admin -d world -c city --type=csv -f ID,Name,CountryCode,District,Population --file /tmp/city1.csv
mongodump和mongorestore
mongodump能够在mongodb运行时进行备份,它的工作原理是对运行的mongodb做查询,然后将所有查到的文档写入磁盘,但是存在的问题时使用mongodump产生的备份不一定是数据的实时快照,如果我们在备份时对数据库进行了写入操作,则备份出来的文件可能不完全和mongodb实时数据相等,另外在备份时可能会对其他客户端性能产生不利的影响
mongodump用法
mongodump --help
-h 指明数据库宿主机的IP
-u 指明数据库的用户名
-p 指明数据库的密码
-d 指明数据库的名字
-c 指明collection的名字
-o 指明要导出的文件名
-q 指明导出数据的过滤条件
-j 并发
--oplog 备份时同时备份oplog
mongodump和mongorestore基本使用
全库备份
mkdir /mongodb/backup
mongodump -uroot -proot123 --port 27017 --authenticationDatabase admin -o /mongodb/backup
备份world库
mongodump -uroot -proot123 --port 27017 --authentioncaDatabase admin -d world -o /mongodb/backup/
备份oldboy库下的log集合
mongodump -uroot -proot123 --port 27017 --authentioncationDatabase admin -d oldboy -c log -o/mongodb/backup/
压缩备份
mongodump -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldguo -o /mongodb/backup/ --gzip
mongodump -uroot -proot123 --port 27017 --authenticationDatabase admin -o /mongodb/backup/ --gzip
mongdump -uroot -proot123 --port 27017 --authenticationDatabase admin -d app -c vast -o /mongodb/backup/ --gzip
恢复world库
mongorestore -uroot -proot123 --port 27017 --authenticationDatabase admin -d world /mongodb/backup/world
恢复oldguo库下的t1集合
mongorestore -uroot -proot123 --port 27017 --authenticationDatabase admin -d world -c t1 --gzip /mongodb/backup.bak/oldboy/log1.bson.gz
drop表示恢复的时候把之前的集合drop掉(危险)
mongorestore -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy --drop /mongodb/backup/oldboy
mongodump和mongorestore高级企业应用(--oplog)
这是replica set或者master/slave模式专用
--oplog
use oplog for taking a point-in-time snapshot
oplog介绍
在replica set中oplog是一个定容集合(capped collection),它的默认大小是磁盘空间的5%(可以通过--oplogSizeMB参数修改)
位于local库的db.oplog.rs,其中记录的是整个mongodb实例一段时间内数据库的所有变更(插入/更新/删除)操作,当空间用完时新纪录自动覆盖最老的记录,其覆盖范围被称作oplog时间窗口,需要注意的是因为oplog是一个定容的集合,所以时间窗口能覆盖的范围会因为你单位时间内的更新次数不同而变化
想要查看当前的oplog时间窗口预计值,可以使用以下命令
mongod -f /mongodb/27017/conf/mongod.conf
mongod -f /mongodb/27018/conf/mongod.conf
mongod -f /mongodb/27019/conf/mongod.conf
mongod -f /mongodb/27020/conf/mongod.conf
use local
db.oplog.rs.find().pretty()
rs.printReplicationInfo()
oplog企业级应用
实现热备,在备份时使用--oplog选项
oplog配合mongodump实现热备
mongodump --port 28017 --oplog -o /mongodb/backup
作用 --oplog会记录备份过程中的数据变化,会以oplog.bson保存下来
恢复 mongorestore --port 28017 --oplogReplay /mongodb/backup
背景 每天0点全备,oplog恢复窗口为48小时
某天上午10点world.city业务表被误删除
恢复思路
停应用,找测试库,恢复昨天晚上全备,截取全备之后到world.city误删除时间点的oplog,并恢复到测试库,将误删除表导出,恢复到生产库
网友评论