一、主从复制
1、读写分离的概念
1、读写分离的概念
读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
读写分离的目的是为了实现高并发场景下的请求分流,避免对数据库的访问过于集中,导致性能下降甚至是宕机。
2、主从复制介绍
2、主从复制介绍
在MongoDB的集群中,会有指定为master的主节点存在,该节点用于被客户端进行数据的增删改操作。同时集群中还会有被指定为slave的节点存在,即从节点,该节点主要接收来自于客户端的读,检索操作,并不具备增删改操作的功能。
在master节点处理完增删改操作后,会实时同步数据到与其绑定的从节点上,实现主从复制至少要有两个数据库实例,并且每个从节点需要知道主节点的地址,如果是在linux中记得开通主从端口的防火墙。
主从复制的优势在于比较灵活,适用于数据备份,故障后人工进行数据恢复,以及对读数据的扩展等。
3、主从复制局限
3、主从复制局限
(1)MongoDB目前建议使用副本集实现集群管理,不建议使用简单的主从复制
(2)主从复制在master宕机后,没有自动选举master机制,导致主节点服务一挂,便不能对外提供增删改操作。
(3)所有增删改操作都是针对主节点进行操作,可能导致主节点性能下降。
(4)从节点对主节点的数据都是全量拷贝,对主从节点的压力都是不小的。
4、主从复制简单配置及实现
4、主从复制简单配置及实现
设备有限,为方便简单的实现,可在一台机器上模拟主节点和从节点。在C盘创建master目录,在E盘创建slave目录,master目录作为主节点数据存放的目录,slave目录作为从节点数据存放的目录。
注意:主节点和从节点要指定不同的端口。
启动主节点:mongod --dbpath C:\master --port 666 --master
启动从节点:mongod --dbpath E:\slave --port 888 --slave --source localhost:666
启动成功后就可以连接主节点进行操作了,而对主节点的操作会同步到从节点,而对从节点进行插入操作时,会报not master的提示并拒绝写入数据。
配置实现解释
master:默认为false,若要设置当前节点为主节点,需要在服务端启动添加--master
slave:默认为false,若要设置当前节点为从节点,需要在服务端启动添加--slave
source:默认为空,用于从节点,指定从节点的复制来源,即主节点所在的地址,格式为:<host><:port>
only:默认为空,用于从节点,主动复制默认复制主节点上所有的数据库,通过设置此项指定需要复制的数据库名称
slavedelay:设置从节点同步主节点的延迟时间,用于从节点设置,默认为0,单位秒。
autoresync:默认为false,用于从节点设置。是否自动重新同步。设置为true,如果落后主节点超过10秒,会强制从节点自动重新同步。如果oplogSize太小,此设置可能有问题。如果oplog大小不足以存储主节点的变化状态和从节点的状态变化之间的差异,这种情况下强制重新同步是不必要的。当设置autoresync选项设置为false,10分钟内从节点不会进行大于1次的自动重新同步。
什么是oplog?
主节点的操作会被记录为oplog,存储在系统数据库local的集合oplog.$main中,这个集合中的每个文档都代表主节点的一个操作(不包括查询),从节点定期从主服务器获取oplog数据,并在本机进行执行,oplog使用的是固定集合,随着操作的逐渐增加,新的文档会逐渐覆盖旧的文档。
二、副本集
1、副本集概念
1、副本集概念
什么是副本?可能第一印象想到的是游戏副本,游戏副本就是为了让每个玩家都有一个独立的游戏环境,这种环境的复制就是副本的一种体现。MongoDB也提供了对副本的支持,副本集中有多个副本保证数据库的容错性,即使一个副本挂掉了还是会存在很多副本;并且支持副本间的自动选举,切换,解决了上一篇博文讲到的主从复制的故障恢复得人工进行的问题。其实主从复制就是一个单副本,缺少扩展性,容错性。
2、副本集原理及图解
2、副本集原理及图解
应用服务器,也就是客户端,连接到MongoDB的整个副本集,副本集中有一台主服务器负责整个副本集的读写,副本节点定期同步主节点的数据和oplog,以保证数据的一致性,一旦主节点宕机或挂掉,副本节点会通过心跳机制检测到,并根据事先副本集创建时设置的节点优先级进行主节点的重新选举,从而保证高可用。如此,客户端完全不必关心副本集的健康状况,MongoDB集群也可以长期保持高可用。
副本集提供了MongoDB集群故障的自动回复机制,扩展性高,容错性强,是MongoDB官方强烈推荐使用的集群解决方案。
3、副本集使用说明
3、副本集使用说明
以4个节点为例,ip,端口,日志以及数据存放路径如下
节点1
地址:127.0.0.1:1001 # 在项目中,是实际的机器IP和端口,
如192.168.1.101:27017
安装路径:D:\mongodb_cluster\MongoDB1
日志存放路径:D:\mongodb_cluster\MongoDB1\log\mongodb.log
数据存放路径:D:\mongodb_cluster\MongoDB1\data
节点2
地址:127.0.0.1:1002
安装路径:D:\mongodb_cluster\MongoDB2
日志存放路径:D:\mongodb_cluster\MongoDB2\log\mongodb.log
数据存放路径:D:\mongodb_cluster\MongoDB2\data
节点3
地址:127.0.0.1:1003
安装路径:D:\mongodb_cluster\MongoDB3
日志存放路径:D:\mongodb_cluster\MongoDB3\log\mongodb.log
数据存放路径:D:\mongodb_cluster\MongoDB3\data
节点4
地址:127.0.0.1:1004
安装路径:D:\mongodb_cluster\MongoDB4
日志存放路径:D:\mongodb_cluster\MongoDB4\log\mongodb.log
数据存放路径:D:\mongodb_cluster\MongoDB4\data
分别启动节点命令如下
启动节点1:
mongod --dbpath D:\mongodb_cluster\MongoDB1\data --logpath D:\mongodb_cluster\MongoDB1\log\mongodb.log --logappend --port 1001 --replSet guanghuan
启动节点2:
mongod --dbpath D:\mongodb_cluster\MongoDB2\data --logpath D:\mongodb_cluster\MongoDB2\log\mongodb.log --logappend --port 1002 --replSet guanghuan
启动节点3:
mongod --dbpath D:\mongodb_cluster\MongoDB3\data --logpath D:\mongodb_cluster\MongoDB3\log\mongodb.log --logappend --port 1003 --replSet guanghuan
启动节点4:
mongod --dbpath D:\mongodb_cluster\MongoDB4\data --logpath D:\mongodb_cluster\MongoDB4\log\mongodb.log --logappend --port 1004 --replSet guanghuan
启动节点命令解释
dbpath: 数据存放路径
logpath:日志存放路径
logappend : 日志拼接声明
replSet:声明是副本集,后面格式为副本集名称/与之位于同一个副本集的节点地址(副本集要求至少要有两个节点,一个主,一个从)
--fork:后台启动,这里为了效果没有添加此参数
初始化节点(只能初始化一次,执行初始化之前,必须启动所有节点)
mongo 127.0.0.1:1001
use admin
rs.initiate(
{"_id" : "guanghuan",
"members" : [
{"_id" : 1, "host" : "127.0.0.1:1001", "priority":3},
{"_id" : 2, "host" : "127.0.0.1:1002", "priority":2},
{"_id" : 3, "host" : "127.0.0.1:1003", "priority":1},
{"_id" : 4, "host" : "127.0.0.1:1004", "arbiterOnly" : true}
]
});
初始化节点命令解释
_id:副本集名称,与启动节点中的名称保持一致
host:副本集成员地址
priority:优先级,即选举成为新master的优先级,越大优先级越高
arbiterOnly:仲裁节点
验证 : rs.status() # 查看副本集的状态
登录主节点,即优先级最高的master节点,输入是否主节点的命令:rs.isMaster()
相关指令:
rs.remove(hostportstr) : 删除节点hostportstr:127.0.0.1:1003
rs.add(hostportstr) :增加节点
登录所有副本集成员,设置:rs.slaveOk(),不然副本集不允许读取数据
修改节点优先级:
cfg = rs.conf()
cfg.members[0].priority=10
rs.reconfig(cfg)
将该主节点关闭,登录优先级第二的从节点,输入是否主节点的命令: 发现在主节点宕机后,优先级较高的节点被选举为了master节点,继续负责读写的工作,从而持续地提供服务,保持集群高可用。
4、仲裁者节点及其作用
4、仲裁者节点及其作用
当集群中的节点数量为偶数个时,投票选举机制会根据数据最后操作,更新时间戳,优先级等来判定谁将成为master节点,如果出现以上条件都符合的情况,且票数相等,此投票环节需要等待若干分钟,这对于客户端来说是无法接受的。
仲裁节点的出现打破了这个僵局,仲裁节点并不需要太多系统资源,也并不持有数据本身,而是参与投票并有效协调从节点争master的撕逼。
集群中部署多仲裁节点时,需在初始化副本集时,添加属性arbiterOnly:true。
三、笔记
1、mongodb中 嵌套文档的访问
1、mongodb中 嵌套文档的访问
{size:{w:18}}
是通过 "size.w" 来进行访问
2、$field_name
2、mongodb中, 只要字段出现在 : 符号的右边,必须通过 '$field_name' 来进行访问
3、心跳包
3、心跳包
机器A 向 机器B 发送心跳包
其实就是机器A 定时向 机器B 发送一个特定的数据包, 告诉机器B, 我机器A还在正常工作
这个 特定的数据包 就叫做心跳包,因为他是 定时发送的, 就类似人的心跳
4、搭建 副本集 命令
4、搭建 副本集 命令
mongod --dbpath D:\mongodb_cluster\MongoDB\data --logpath D:\mongodb_cluster\MongoDB\log\mongodb.log --logappend --bind_ip 192.168.8.254 --port 1809 --replSet guanghuan
rs.initiate(
{"_id" : "guanghuan",
"members" : [
{"_id" : 1, "host" : "192.168.8.254:1809", "priority":30},
{"_id" : 3, "host" : "192.168.8.226:1809", "priority":30},
{"_id" : 4, "host" : "192.168.8.98:1809", "priority":30},
{"_id" : 5, "host" : "192.168.8.227:1809", "priority":30},
{"_id" : 6, "host" : "192.168.8.106:1809", "priority":30},
{"_id" : 7, "host" : "192.168.8.144:1809", "priority":30},
{"_id" : 24, "host" : "192.168.8.254:1004", "arbiterOnly" : true}
]
})
5、 pip 不是内部或外部变量
5、 pip 不是内部或外部变量
解决:将 python 安装目录下的 Scripts 目录 添加到 环境变量中即可解决
6、再次强调去 阅读 PEP8
6、再次强调去 阅读 PEP8
注意 命名冲突!
不能以数字、中文 作为 模块名