MongoDB复制集知识点及PHP7连接mongodb

概述

诚然,网上很多大佬列出了详细的MongoDB复制集配置教程,但是新人总是还是遇到一些困惑的地方,我把我遇到的困惑点列出来,相互学习之、加深记忆之。

MongoDB搭建集群主要有三种方式:1):主从;2):复制集;3):分片;

  • 主从
    主从就是一主(master)多从(slave)架构,可以是做到安全备份,读写分离等;但官方考虑到技术的更新换代,主从方式已不推荐使用,并从MongoDB4.0移除了对主从方式的支持,主要是因为主从方式有明显缺点:
    1):不具有高可用性,只要主节点挂掉,整个集群都不可用了,需要人为启动主节点才可以。
    2):如果不进行读写分离,读写都在主节点上,主节点的压力无疑会很大
    3):从节点都从主节点复制数据,主节点压力会不会过大
    4):如果采用读写分离(写主读从),会不会因为主从同步时因为数据复制延迟的问题,导致客户端读到的是旧数据或无法拿到数据,假设一个极端的场景:在读写分离模式下,客户端写入一个文档,就立马读出来,这时可能会出现读到的是旧数据或无法拿到数据的情况,在实际业务中要避免的,主要是因为从节点从主节点复制数据是要一定时间的。

Removed
MongoDB 4.0 removes support for master-slave replication. Before you can upgrade to MongoDB 4.0, if your deployment uses master-slave replication, you must upgrade to a replica set.
To convert your master-slave replication, see Convert a Master-Slave Deployment to a Replica Set

  • 复制集
    原理:主节点是副本集中接收写操作的唯一成员。MongoDB在主数据库上应用写操作,然后在主数据库的oplog上记录操作。次要成员复制此日志,并将操作应用于其数据集。
    在这里插入图片描述
    复制集采用一主(Primary,即主要)多从(Secondary,即次要)的架构,这里的主是所有节点推选出来的,很民主吧,并不像主从架构的主节点是上帝(你)指定的。官方规定,副本集最多50个节点,但拥有选举权最多可以有七个,要知道拥有选举权的节点才可能成为主节点。如下图:
    在这里插入图片描述
    官方推荐具有选举权的(可以投票的)节点数为奇数,从节点有几种角色:
    普通节点:备份主节点数据
    仲裁节点:仅有选举权,不备份主节点数据
    隐藏节点:对客户端应用程序不可见,但备份主节点数据
    延迟节点:所含数据集是主节点的过去某时刻的内容
    详细说明见官网副本集次要成员
    优点:高可用(主的死了再推一个主的,不会因此不能工作),灾备恢复,读写分离等
    缺点:除了提高了可用性(对于集群来说很重要的一个特性),其他与主从模式差不多
    1):如果不进行读写分离,读写都在主节点上,主节点的压力无疑会很大
    2):从节点都从主节点复制数据,主节点压力会不会过大?
    3):如果采用读写分离(写主读从),会不会因为主从同步时因为数据复制延迟的问题,导致客户端读到的是旧数据或无法拿到数据,假设一个极端的场景:在读写分离模式下,客户端写入一个文档,就立马读出来,这时可能会出现读到的是旧数据或无法拿到数据的情况,在实际业务中要避免的,主要是因为从节点从主节点复制数据是要一定时间的。

复制集配置

(由于我只有一台个人电脑(mac),所以通过区分端口(27017,27018,27019)来进行三个节点的配置),具体下载安装mongodb就不说了,玩到到副本集段位的这些也不用说,哈哈。
mongodb配置:

#mongodb config file
dbpath=/Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/rs0/data/db/
logpath=/Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/rs0/log/mongod.log
logappend = true #日志追加方式
port = 27017 #端口
fork = true #守护进程运行
#auth = true
noauth = true
#bind_ip = 192.168.40.253
bind_ip = 127.0.0.1 #绑定IP

replSet = rs0 #副本集名字,具有唯一性,换别的也可以
oplogSize=2048 #oplog集合大小,单位M,用于主从同步的一个固定集合(即大小受限的集合),在local库里
directoryperdb=true # 设置每个数据库将被保存在一个单独的目录
#私钥
#security:
	#keyFile = /Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/key/keyfile

并命名为mongodb.conf,位于/Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/rs0/conf/mongodb.conf。

启动服务

按配置文件建好目录,文件等,启动 。切换到/Applications/MAMP/db/mongodb-osx-x86_64-4.0.10目录,执行
mongod -f ./rs0/conf/mongodb.conf
同理,进行节点2,3的初始化:
mongod -f ./rs1/conf/mongodb.conf
mongod -f ./rs2/conf/mongodb.conf

注意:初始化时不要开启认证模式,先用免认证模式进行复制集设置。

进入端口27017服务,mongo --port 27017

1:rs.initiate()//初始化复制集配置
2:rs.add("127.0.0.1:27018")//增加节点
3:rs.add("127.0.0.1:27019")//增加节点
4:rs.status()//查看节点状态
5:rs.conf()//查看节点配置
6:use admin
8:db.createUser({ user: "root", pwd: "123456", roles: [ { role: "root", db: "admin"} ]})//创建用户,这里如果通过Robo 3T看,可以看到新建的用户已同步到27018,27019服务

三个服务全关闭,可以通过 ps -ef | grep mongo 查看mongo进程号,然后kill掉就好了,也可执行db.shutdownServer()。

主从间的同步需要安全机制,所以要生成秘钥(注意,如果多台机器,一个机器生成,复制到其他机器上即可,各节点必须保持一致):openssl rand -base64 90 -out ./keyfile,将生成的keyfile放到配置文件指定的目录 /Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/key/keyfile

修改配置文件,开启认证模式:

#mongodb config file
dbpath=/Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/rs0/data/db/
logpath=/Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/rs0/log/mongod.log
logappend = true #日志追加方式
port = 27017 #端口
fork = true #守护进程运行
auth = true
#noauth = true
#bind_ip = 192.168.40.253
bind_ip = 127.0.0.1 #绑定IP

replSet = rs0 #副本集名字,具有唯一性,换别的也可以
oplogSize=2048 #
directoryperdb=true # 设置每个数据库将被保存在一个单独的目录
#私钥
security:
	keyFile = /Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/key/keyfile

启动三个mongo服务,使用之前创建的用户登录即可。现在已经具有灾备,高可用的特性了。

我们这样搭建下来,27017为主要节点,27018,27019为次要节点,如果关闭27017主节点,你会发现27018和27019中的某一个变成主节点,并且再启动27017节点,它变成了一个次要节点,并开始从主节点复制数据,并不会恢复主节点的身份。当然,恢复也是不合理的,毕竟它挂了的那段时间实际数据已经改变了

PHP连接MongoDB实现读写分离

安装:PHP7安装MongoDB扩展(php7以前可以用mongo扩展,但PHP7已放弃),
mongodb的composer包(composer require mongodb/mongodb)

require_once 'vendor/autoload.php';
$uri='mongodb://'.$host1.':'.$port1.','.$host2.':'.$port2.','.$host3.':'.$port3;
$uriOptions = [
       'username' => $username,
       'password' => $password,
       'ssl' => false,//ssl连接,需要证书,默认false
       'replicaSet' => $replicaset,//复制集名称,如我用的 rs0
       'authSource' => $authdb,//认证的数据库,admin
       //'slaveOk'=>true,//已弃用
       'readPreference' => 'secondaryPreferred'//指定读模式
 ];
 $diverOptions = [
            'typeMap' => [         
                'root' => 'array',
                'document' => 'array',
                'array' => 'array',
            ]
        ];
/**
   限定MongoDB扩展返回来的是方便php处理的数组,而不是bsonarray对象,默认配置
   [
    'array' => 'MongoDB\Model\BSONArray',
    'document' => 'MongoDB\Model\BSONDocument',
    'root' => 'MongoDB\Model\BSONDocument',
]
*/
$mongo = new MongoDB\Client($uri,$uriOptions,$diverOptions);

注意读模式共有五种模式:

primary:默认参数,只从主节点上进行读取操作;
primaryPreferred:大部分从主节点上读取数据,只有主节点不可用时从secondary节点读取数据。
secondary:只从secondary节点上进行读取操作,存在的问题是secondary节点的数据会比primary节点数据“旧”。
secondaryPreferred:优先从secondary节点进行读取操作,secondary节点不可用时从主节点读取数据;
nearest:不管是主节点、secondary节点,从网络延迟最低的节点上读取数据。

主从复制原理浅析

首先,主节点会把本服务的与写有关的操作记录下来,读操来不记录,这些操作就记录在local数据库中的oplog.rs0(因为我创建复制集的名称叫rs0)这个集合中,这是一个固定集合,大小是可以配置的,主要是通过配置oplogSize这个参数来实现,单位是M,大小一般为磁盘剩余空间的5%左右.因为是固定集合所以当固定集合放满日志的时候,新进来的日志就会把最旧的日志覆盖掉,如果这个值设置的不合理,导致数据很快的被覆盖,而从节点没有来得及更新,这样就会产生数据不同步的情况.设置为主节点的local数据库有会有oplog.$admin与slave这两个集合.slave记录的是从节点的信息.
从节点与主节点的数据同步主要是从节点定时的会去连接主节点,请求主节点的操作日志,从而对自己的数据副表进行同样的操作来达到数据的同步.从节点的local数据库中会多了source与me这两个集合,source是记录主节点的信息,me是记录从节点的标识

待续。。。。。。

参考资料

1】MongoDB官网
2】生产环境配置MongoDB复制集
3】使用新版MongoDB1.4–composer安装、使用与填坑
4] MongoDB副本集实现及读写分离

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值