搭建: 一台机器启动多个实例
1、创建三个文件夹做为三个 MongoDB 实例的工作空间
mkdir -p /myMongoDb/mongodb1mkdir -p /myMongoDb/mongodb2mkdir -p /myMongoDb/mongodb3
2、在三个工作空间下分别创建数据,日志,进程存放等目录或者文件
mkdir -p /myMongoDb/mongodb1/datamkdir -p /myMongoDb/mongodb1/logmkdir -p /myMongoDb/mongodb1/pidmkdir -p /myMongoDb/mongodb2/datamkdir -p /myMongoDb/mongodb2/logmkdir -p /myMongoDb/mongodb2/pidmkdir -p /myMongoDb/mongodb3/datamkdir -p /myMongoDb/mongodb3/logmkdir -p /myMongoDb/mongodb3/pidtouch /myMongoDb/mongodb1/log/mongodb.logtouch /myMongoDb/mongodb2/log/mongodb.logtouch /myMongoDb/mongodb3/log/mongodb.logtouch /myMongoDb/mongodb1/pid/mongodb.pidtouch /myMongoDb/mongodb2/pid/mongodb.pidtouch /myMongoDb/mongodb3/pid/mongodb.pid
3、在每个工作空间下创建配置文件
enableMajorityReadConcern
是否开启 readConcern 的级别为 majority,默认为 false;只有开启此选项,才能在 read 操作中使用 majority
destination:
日志输出目的地,可以指定为 file 或者 syslog,表述输出到日志文件,如果不指定,则会输出到标准输出
journal
是否开启 journal 日志持久存储,journal 日志用来数据恢复,是 mongod 最基础的特性,通常用于故障恢复。64 位系统默认为 true,32 位默认为 false,建议开启,仅对 mongod 进程有效。
vim /myMongoDb/mongodb[1, 2, 3]/mongodb.conf# 分别写入systemLog:destination: filelogAppend: truepath: /myMongoDb/mongodb[1, 2, 3]/log/mongodb.logstorage:dbPath: /myMongoDb/mongodb[1, 2, 3]/datajournal:enabled: trueprocessManagement:fork: truepidFilePath: /myMongoDb/mongodb[1, 2, 3]/pid/mongodb.pidnet:port: [7000, 7001, 7002]bindIp: 192.168.204.199replication:replSetName: rs0enableMajorityReadConcern: true
4、启动
/usr/local/mongodb/bin/mongod -f /myMongoDb/mongodb1/mongodb.conf/usr/local/mongodb/bin/mongod -f /myMongoDb/mongodb2/mongodb.conf/usr/local/mongodb/bin/mongod -f /myMongoDb/mongodb3/mongodb.conf
客户端连接,初始化副本:
mongo --host=192.168.204.199 --port=7000> rs.initiate(){"info2" : "no configuration specified. Using a default configuration for the set","me" : "192.168.204.199:7000","ok" : 1,"$clusterTime" : {"clusterTime" : Timestamp(1584452776, 1),"signature" : {"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),"keyId" : NumberLong(0)}},"operationTime" : Timestamp(1584452776, 1)}rs0:OTHER>rs0:PRIMARY>OK为1的话 则初始化成功rs.conf() 查看副本信息
加入副本和仲裁节点
加入副本节点
rs.add("192.168.204.199:7001")
加入仲裁节点
不建议使用仲裁节点,因为一旦使用了仲裁节点,就不支持分布式事务
rs.addArb("192.168.204.199:7002")
运行测试
连接主节点
use test
db.xyj.insert({name:"猪八戒", age:28, gender:"男"});
连接副本节点
rs.slaveOk() 默认为 rs.slaveOk(true),不想复制的时候可以执行 rs.slaveOk(false)
mongo --host=192.168.204.199 --port=7001
show dbs // 会报错
rs.slaveOk() // 响应主节点
show dbs // 正常
连接仲裁节点
仲裁节点不会复制数据
mongo --host=192.168.204.199 --port=7002
rs.slaveOk()
show dbs
故障测试
副本挂掉的情况
主节点和仲裁节点不受影响,如果副本挂掉的时候主节点还写入数据,当副本重启时主会同步数据给副本
主节点挂掉的情况
执行故障转移,从节点成为主节点,仲裁节点没有被选举权(不会成为主节点),当挂掉的主节点回来了。将成为副本
主节点和仲裁节点挂掉的情况
副本还是副本,但是此时随便一个成员加入:
- 仲裁节点加入: 副本成为主节点
- 主节点加入:看谁的数据新,谁就是主节点
副本节点和仲裁节点挂掉的情况
主节点降级为副本
数据是如何复制的
当一个修改(增删改)操作到达主节点时,它对数据的操作经过特定的转化之后将被记录下来,这些称为oplog,
从节点通过在主节点上打开一个 tailable 游标不断获取新进入主节点的 oplog,并在自己的数据上回放。
故障转移
具有投票权的节点之间两两互相发送心跳
当 5 次心跳未收到则判断为节点失联
如果是主节点,从节点会发起选举,选出主节点
如果失联的是从节点则不会发生新的选举
选举基于 RAFT 一致性算法,选举成功的必要条件是大多数投票节点存活
复制集中最多可以有 50 个节点,但最多只能有 7 个投票节点
影响选举的因素
**
被选举为主节点的节点必须:
能与多数节点建立连接
具有较新的 oplog
根据配置文件的优先级
