文档(json)类数据库
{
id : 101
name : zhangsan
age : 18
}
Mongodb 逻辑结构 MySQL逻辑结构
库database 库
集合(collection) 表
文档 (document) 数据行
最像RDBMS的NoSQL
事务,锁,索引类似于MySQL
项目:
Oracle MySQL ---一部分数据转换---> Mongodb
银行,保险公司 流水信息 -----------> Mongodb
流水信息 ---> 大数据分析 ---> 推送产品
国内目前最大: 360 ---> 17年底 ---> 2600多个节点Mongodb
病毒库,各种信息,大数据存储
(1)redhat或centos6.2以上系统
(2)系统开发完整
(3)ip地址和hosts文件解析正常
(4)iptables防火墙&SElinux关闭
(5)关闭大页内存机制(提高mongodb性能)
关闭大页内存
root用户下vim /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
sh /etc/rc.local
# 手工设置方法
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
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/
# 创建所需用户和组
[root@db01 ~]# useradd mongod
[root@db01 ~]# passwd mongod
# 创建mongodb所需目录结构
[root@db01 ~]# mkdir -p /mongodb/conf
[root@db01 ~]# mkdir -p /mongodb/log
[root@db01 ~]# mkdir -p /mongodb/data
# 上传并解压软件到指定位置
[root@db01 ~]# cd /data
[root@db01 data]# tar xf mongodb-linux-x86_64-rhel70-3.6.12.tgz
# mongodb目录下bin下文件才有用
[root@db01 data]# cp -r /data/mongodb-linux-x86_64-rhel70-3.6.12/bin/ /mongodb
# 设置目录结构权限
[root@db01 data]# chown -R mongod:mongod /mongodb
# 设置用户环境变量
[root@db01 ~]# su - mongod
[mongod@db01 ~]$ vim .bash_profile
export PATH=/mongodb/bin:$PATH
[mongod@db01 ~]$ source .bash_profile
# 启动mongodb(mongodb默认端口27017)
[mongod@db01 ~]$ mongod --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --port=27017 --logappend --fork
# 登录mongodb
[mongod@db01 ~]$ mongo
MongoDB shell version v4.2.8
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
从目前阿里云 MongoDB 云数据库上的用户看,MongoDB 的应用已经渗透到各个领域:
游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新;
物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来;
社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能;
物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析;
视频直播,使用 MongoDB 存储用户信息、礼物信息等;
大数据应用,使用云数据库MongoDB作为大数据的云存储系统,随时进行数据提取分析,掌握行业动态。
YMAL模式:
NOTE:
YMAL does not support tab characters for indentation: use spaces instead.
--系统日志有关
systemLog:
destination: file
path: "/mongodb/log/mogodb.log" -- 日志位置
logAppend: true -- 日志以追加模式记录
--数据存储有关
storage:
journal: -- 是否开启日志功能
enabled: true
dbPath: "/mongodb/data" -- 数据路径位置
--进程控制
processManagement:
fork: true -- 后台守护进程
pidFilePath: > -- pid文件的位置,一般不用配置,可以去掉这行,自动生成到data中
--网络配置有关
net:
bindIp: > -- 监听端口
port: > -- 端口号,默认不配置端口号,是27017
-- 安全验证有关配置
security:
authorization: enabled --是否打开用户名密码验证
================以下是复制集与分片集群有关===============
replication:
oplogSizeMB: >
replSetName: ""
secondaryIndexPrefetch: "all"
sharding:
clusterRole: >
archiveMovedChunks: >
---for mongos only
replication:
localPingThresholdMs: >
sharding:
configDB: >
---
YMAL例子:
cat > /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: 10.0.0.61,127.0.0.1
EOF
# 重启mongodb
[mongod@db01 ~]$ mongod -f /mongodb/conf/mongo.conf --shutdown
[mongod@db01 ~]$ mongod -f /mongodb/conf/mongo.conf
mongodb使用systemd管理(root用户下配置):
[root@db01 ~]# cat > /etc/systemd/system/mongod.service <
[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
# mongodb启动、停止、重启
[root@db01 ~]# systemctl start mongod
[root@db01 ~]# systemctl stop mongod
[root@db01 ~]# systemctl restart mongod
test: 登陆时默认存在的库(默认在test这个库里面)
管理mongodb有关的系统库
admin库: 系统预留库,mongodb系统管理库
local库: 本地预留库,存储关键日志
config库:mongodb配置信息库
mysql / mongodb 命令(mongodb有的两者都可以用)
show databases / show dbs
show tables / show collections
use admin
select database() / db
db 对象相关命令
db.[TAB][TAB]
db.help()
db.biao.[TAB][TAB]
db.biao.help()
rs 复制集有关(replication set):
rs.[TAB][TAB]
rs.help()
sh 分片集群(sharding cluster)
sh.[TAB][TAB]
sh.help()
mongo mysql
库 库
集合 表
文档 数据行
# 进入test库,如果不存在test库,默认创建临时库test,在test库中创建表之后,test库才会被真正创建
> use school
# 删除当前的school库
> db.dropDatabase()
{ "ok": 1}
建表方式一:
> use school
# 查看当前库
> db
school
# 在school库中创建a表
> db.createCollection('a')
{"ok": 1}
> db.createCollection('b')
{"ok": 1}
# 查看school库中的表
> show tables;
a
b
建表方式二:
use school
# 当插入一个文档的时候,一个集合就会自动创建
db.student.insert(
{
id : 101 ,
name: "zhagnsan"
}
)
# 向test表中插入多条数据
db.test.insert({id:101,name:"zhangsan",age:20})
show tables;
db.test.insert({id:101,name:"lisi",age:20})
db.test.insert({id:101,name:"wanger",age:20})
数据录入:
for(i=1;i<10000;i++){db.log.insert({"uid":i,"name":"mongodb","age":6,"data":new Date()})}
# 查询数据行
> db.log.count()
# 全表查询:
> db.log.find()
# 每页显示50条记录
> DBQuery.shellBatchSize=50;
# 按照条件查询
> db.log.find({uid:999})
以标准的json格式显示数据
> db.log.find({uid:999}).pretty()
{
"_id" : ObjectId("62cafcac622c7159766183ed"),
"uid" : 999,
"name" : "mongodb",
"age" : 6,
"data" : ISODate("2022-07-10T16:22:04.197Z")
}
删除集合中所有记录
> db.log.remove({})
查看集合存储信息
> db.log.totalSize() //集合中索引+数据压缩存储之后的大小
CRUD操作查看官网文档
验证库: 建立用户时use到的库,在使用用户时,要加上验证库才能登录。
对于管理员用户,必须在admin下创建
1. 建用户时,use到的库,就是此用户的验证库
2. 登录时,必须明确指定验证库才能登录
3. 通常,管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库
4. 如果直接登录到数据库,不进行use,默认的验证库是test,不是我们生产建议的
5. 从3.6版本开始,不添加binIP参数,默认不让远程登录,只能本地管理员登录
总结:验证库,bindIP
use admin
db.createUser
{
user: ">".
pwd: "" ,
roles: [
{ role: "" ,db: "" } | ">",
...
]
}
基本语法说明:
user: 用户名
pwd: 密码
roles:
role: 角色名
db: 作用对象
role: root,readWrite,read
验证数据库:
mongo -u zhangsan -p 123456 10.0.0.61/school(验证库)
# 创建超级管理员: 管理所有数据库(必须use admin再去创建)
$ mongo
use admin ---> 选择验证库
db.createUser(
{
user: "root",
pwd: "123456",
# 拥有root的角色,去管理admin库
roles: [ { role: "root", db: "admin" } ]
}
)
在创建一个zhangsan用户:
use admin
db.createUser(
{
user: "zhangsan",
pwd: "123456",
# 拥有readWrite的角色,去管理admin库
roles: [ { role: "readWrite" , db: "admin" } ]
}
)
# 验证用户(使用户及时生效)
db.auth('root','root123')
# 配置文件中,加入以下配置
[mongod@db01 ~]$ vim /mongodb/conf/mongo.conf
security:
authorization: enabled
# 重启mongodb
mongod -f /mongodb/conf/mongo.conf --shutdown
mongod -f /mongodb/conf/mongo.conf
# 登录验证(远程登录要指定验证库)
mongo -uroot -proot123 admin # 本地可以不加验证库
mongo -uroot -proot123 10.0.0.53/admin
# 查看用户:(用户信息都在admin库下)
> use admin
> show tables
system.users # system.users这个整体就是表名
system.version
> db.system.users.find().pretty()
# 创建应用用户(普通用户)
> use school
> db.createUser(
{
user: "app01",
pwd: "app01",
# 拥有readWrite的角色,去管理school库
roles: [ { role: "readWrite", db: "school" } ]
}
)
# 连接测试
mongo -uapp01 -papp01 10.0.0.61/school
# 查询mongodb中的用户信息
db.system.users.find().pretty()
# 创建app01用户
> use school
> db.createUser(
{
user: "app01",
pwd: "app01",
roles: [ { role: "readWrite" , db: "school" } ]
}
)
# root身份登录,use到验证库,删除用户(在哪个库里创建的用户,就要到哪个库里面删除用户)
mongo -uroot -proot123 10.0.0.61/admin
> use school
> db.dropUser("app01")
true
基本构成是1主2从的结构(一般一主两从,如果一主一从容易出现脑裂),
自带互相监控投票机制(Raft 分布式一致性协议(mongodb) Paxos(mysql MGR 用的是变种)) 如果发生主库宕机,
复制集内部会进行投票选举,选择一个新的主库替代原有主库对外提供服务。
同时复制集会自动通知客户端程序,主库已经发生切换了。应用就会连接到新的主库。
优点:不需要像atlas、mycat、sentinel这种中间件,就可以实现高可用。
只要在应用端安装了mongodb相应的api驱动,自动发起应用透明的功能,
如果节点宕了,会自动通知客户端,去进行业务的转移
复制集的功能是集合了一个高可用的功能,还有数据一致性为一身的架构。会有自动的投票选举,保证数据的一致性。设计三个节点就是防止脑裂的问题,单个节点就行检测和心跳检测,两个节点没法投票(两个人去吃饭,要不去要么不去,没办法投票)
三个以上的mongodb节点(或多实例)
# 多个端口
28017、28018、28019、28020
# 1. 创建多个目录
su - mongod
mkdir -p /mongodb/28017/conf /mongodb/28017/data /mongodb/28017/log
mkdir -p /mongodb/28018/conf /mongodb/28018/data /mongodb/28018/log
mkdir -p /mongodb/28019/conf /mongodb/28019/data /mongodb/28019/log
mkdir -p /mongodb/28020/conf /mongodb/28020/data /mongodb/28020/log
# 2. 创建多个配置文件(执行2.1下面的操作即可)
/mongodb/28017/conf/mongod.conf
/mongodb/28018/conf/mongod.conf
/mongodb/28019/conf/mongod.conf
/mongodb/28020/conf/mongod.conf
## 2.1 给配置文件/mongodb/28017/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
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
net:
bindIp: 10.0.0.61,127.0.0.1
port: 28017
replication:
oplogSizeMB: 2048
# mongodb重启之后,可以重构这个集群
replSetName: my_repl
EOF
## 2.2 配置文件说明
3.x版本以上,默认是WT引擎,相当于MySQL InnoDB支持事务,文件锁
2.x版本以上,相当于MySQL MyISAM引擎
## 2.2 给其他配置文件也写入内容
\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
# 3. 启动多个实例备用
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
## 3.1 查看端口
[mongod@db01 ~]$ netstat -tlunp | grep 280
# 1主2从,从库普通从库
[mongod@db01 ~]$ mongo --port 28017 admin # 先连接到一个节点
# 把后面的json赋值给一个变量config,然后在初始化变量
> config = {_id: 'my_repl', members: [
{_id: 0, host: '10.0.0.61:28017'},
{_id: 1, host: '10.0.0.61:28018'},
{_id: 2, host: '10.0.0.61:28019'}]
}
# 初始化变量
> rs.initiate(config)
# 当前节点会被选成主节点
my_repl:PRIMARY>
# 查询复制集状态
> rs.status();
三个节点防止脑裂,三个节点进行心跳检测,进行投票,两个节点没法投票。因为第二个节点没太大必要去参加复制的操作,只需要到个时间点投个篇就可以了,没必要去复制数据。所以就有了一下的架构: 1主1从1个Arbiter ,Arbiter只负责投票,不负责复制(Replication)数据。增加了集群的性能
开始实验:
一个节点在某个复制集里面存在了,就不能在存在别的复制集里面了。
因为10.0.0.61:28019这个节点已经是1主2从里面的从节点了,所以可以用复制集管理把这个节点删除,然后在加进来,使这个节点的状态为Arbiter。
[mongod@db01 ~]$ mongo --port 28017 admin
my_repl:PRIMARY> rs.remove("10.0.0.61:28019");
my_repl:PRIMARY> rs.addArb("10.0.0.61:28019");
# 添加之后,手动启动一下这个节点
# 集群会自动把这个节点停掉,原来这个节点有数据,会自动把这个数据清空掉,所以需要重启这个节点
mongod -f /mongodb/20819/conf/mongo.conf
小提示: 正确的操作是先把节点踢掉,然后把节点的数据清空,然后在他把加进来或者新加一个新节点。因为测试环境没有数据,可以像上面这样操作。
# 如果刚开始搭建集群的话,可以这样操作,就跟1主2从那样操作即可
[mongod@db01 ~]$ mongo --port 28017 admin # 先连接到一个节点
# 把后面的json赋值给一个变量config,然后在初始化变量
> config = {_id: 'my_repl', members: [
{_id: 0, host: '10.0.0.61:28017'},
{_id: 1, host: '10.0.0.61:28018'},
{_id: 2, host: '10.0.0.61:28019'},"arbiterOnly":true]
}
# 初始化变量
> rs.initiate(config)
# 查看整体复制集状态
rs.status();
# 查看当前是否是主节点
rs.isMaster();
# 查看复制集配置信息
rs.conf();
# 删除一个节点
rs.remove();
# 新增从节点
rs.add("ip:port");
# 新增仲裁节点
rs.addArb("ip:port");
特殊从节点介绍:
arbiter节点:主要负责选主过程中的投票,但是不存储任何数据,也不提供任何服务
hidden节点:隐藏节点,不参与选主,也不对外提供服务
delay节点:延时节点,数据落后于主库一段时间,因为数据是延时的,也不应该提供服务或参与选主,所以通常会配合hidden(隐藏)
一般情况下会将delay+hidden一起配置使用
配置延时节点(一般延时节点也配置成hidden)
目的: 这个延时从库跟mysql的延时从库一个道理,主要防止逻辑的损坏,架构设计是一主一从一Arbiter。
如果出现删除的误操作的话,逻辑损坏也能快速的恢复。所以可以在加一个节点,是这个节点成为
hidden+delay,来防止逻辑损坏。
开始实验:
# 1. 在一主一从一Arbiter集群中添加一个新节点10.0.0.61:28020
my_repl:PRIMARY> rs.add("10.0.0.61:28020");
# 2. 给新节点10.0.0.61:28020配置成特殊节点(hidden+delay)
cfg=rs.conf() // 定义配置为cfg变量
cfg.members[3].priority=0 // 定义权重为0,不参与选主
cfg.members[3].hidden=true // 隐藏节点,不参与业务
cfg.members[3].slaveDelay=120 // 延时的描述,这里配置2分钟,可以配置6个小时
cfg.members[3].votes=0 // 持有票数为0
rs.reconfig(cfg) // 重新加载配置
# 取消以上配置
cfg=rs.conf();
cfg.members[3].priority=1
cfg.members[3].hidden=false
cfg.members[3].slaveDelay=0
cfg.members[3].votes=1
rs.reconfig(cfg)
# 配置成功后,通过以下命令查询配置后的属性
rs.conf();