Mongodb和Redis都是NoSql阵营的数据库,所以他们有异曲同工之处。
Redis主从配置文章:Redis主从同步及其哨兵的配置和使用(Windows)
这篇文章记录了Mongodb的主从配置。他们有些东西是可以对应着来理解的。
首先说明一下几个名词:
1、副本集:Mongodb中主从复制的集合,简称副本集,Redis中是主从同步功能一致。
2、主节点:也就是可读可写的节点,但是一般用来写,Redis中也有这个概念。
3、从节点:自动同步主节点的数据,一般用来读取数据,写入数据默认关闭的,可以开启,Redis中也有这个概念。
4、仲裁节点:当主节点挂掉之后,自动选举出新的主节点,这个和Redis中哨兵是一个概念。
下载Mongodb
无论是msi还是zip的版本,使用上都是一样的,我更愿意选择zip,因为更加简洁,很多东西自己可以控制。
msi文件就是安装包,下一步就行,我这里使用zip进行演示。
解压到指定目录,得到这样的内容
进入到bin目录,这就是所有文件,没有配置文件
开始安装
1、为了方便在同一台电脑上演示多个实例,我们把刚刚解压的文件夹复制三份,分别命名:master,slave和arbiter
得到三个目录:都包含了zip文件中所有文件
C:\Program Files\MongoDB\Server\master //主库实例 C:\Program Files\MongoDB\Server\slave //从库实例 C:\Program Files\MongoDB\Server\arbiter //仲裁节点实例
2、再创建三个实例的数据和日志文件夹,总共六个文件夹,待会儿要用
//主库 C:\MongoDb\masterdb C:\MongoDb\masterlog //从库 C:\MongoDb\slavedb C:\MongoDb\slavelog //仲裁节点 C:\MongoDb\arbiterdb C:\MongoDb\arbiterlog
3、分别给三个实例文件夹的bin目录创建mongo.config 配置文件,内容分别如下
dbpath=C:\MongoDb\masterdb #数据文件存放目录 logpath=C:\MongoDb\masterlog\mongo.log #日志文件存放地址 port=27111 #实例的端口号 logappend=true #是否使用追加日志的方式 fork=true #以守护进程的方式运行MongoDB,创建服务器进程 journal=true #启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里 oplogSize=2048 #设置oplog的大小(MB) smallfiles=true #使用较小的默认文件 replSet=mySet #设置副本集名称 同一个副本集 名称应该一样
dbpath=C:\MongoDb\slavedb logpath=C:\MongoDb\slavelog\mongo.log port=27112 logappend=true fork=true journal=true oplogSize=2048 smallfiles=true replSet=mySet
dbpath=C:\MongoDb\arbiterdb logpath=C:\MongoDb\arbiterlog\mongo.log port=27113 logappend=true fork=true journal=true oplogSize=2048 smallfiles=true replSet=mySet
更加详细的配置解释
------------------------------------基本配置---------------------- --quiet # 安静输出 --port arg # 指定服务端口号,默认端口27017 --bind_ip arg # 绑定服务IP,若绑定127.0.0.1,则只能本机访问,不指定默认本地所有IP --logpath arg # 指定MongoDB日志文件,注意是指定文件不是目录 --logappend # 使用追加的方式写日志 --pidfilepath arg # PID File 的完整路径,如果没有设置,则没有PID文件 --keyFile arg # 集群的私钥的完整路径,只对于Replica Set 架构有效 --unixSocketPrefix arg # UNIX域套接字替代目录,(默认为 /tmp) --fork # 以守护进程的方式运行MongoDB,创建服务器进程 --auth # 启用验证 --cpu # 定期显示CPU的CPU利用率和iowait --dbpath arg # 指定数据库路径 --diaglog arg # diaglog选项 0=off 1=W 2=R 3=both 7=W+some reads --directoryperdb # 设置每个数据库将被保存在一个单独的目录 --journal # 启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里 --journalOptions arg # 启用日志诊断选项 --ipv6 # 启用IPv6选项 --jsonp # 允许JSONP形式通过HTTP访问(有安全影响) --maxConns arg # 最大同时连接数 默认2000 --noauth # 不启用验证 --nohttpinterface # 关闭http接口,默认关闭27018端口访问 --noprealloc # 禁用数据文件预分配(往往影响性能) --noscripting # 禁用脚本引擎 --notablescan # 不允许表扫描 --nounixsocket # 禁用Unix套接字监听 --nssize arg (=16) # 设置信数据库.ns文件大小(MB) --objcheck # 在收到客户数据,检查的有效性, --profile arg # 档案参数 0=off 1=slow, 2=all --quota # 限制每个数据库的文件数,设置默认为8 --quotaFiles arg # number of files allower per db, requires --quota --rest # 开启简单的rest API --repair # 修复所有数据库run repair on all dbs --repairpath arg # 修复库生成的文件的目录,默认为目录名称dbpath --slowms arg (=100) # value of slow for profile and console log --smallfiles # 使用较小的默认文件 --syncdelay arg (=60) # 数据写入磁盘的时间秒数(0=never,不推荐) --sysinfo # 打印一些诊断系统信息 --upgrade # 如果需要升级数据库 -----------------------------------Replicaton 参数-------------------- --fastsync # 从一个dbpath里启用从库复制服务,该dbpath的数据库是主库的快照,可用于快速启用同步 --autoresync # 如果从库与主库同步数据差得多,自动重新同步, --oplogSize arg # 设置oplog的大小(MB) ---------------------------------* 主/从参数------------------------- --master # 主库模式 --slave # 从库模式 --source arg # 从库 端口号 --only arg # 指定单一的数据库复制 --slavedelay arg # 设置从库同步主库的延迟时间 -----------------------------------Replica set(副本集)选项---------------------- --replSet arg # 设置副本集名称 -----------------------------------Sharding(分片)选项------------------------ --configsvr # 声明这是一个集群的config服务,默认端口27019,默认目录/data/configdb --shardsvr # 声明这是一个集群的分片,默认端口27018 --noMoveParanoia # 关闭偏执为moveChunk数据保存
4、分别在bin目录运行CMD,将实例以服务方式运行
mongod --replSet mySet --port 27111 --dbpath C:\MongoDb\masterdb --logpath C:\MongoDb\masterlog\MongDb.log --serviceName "MongoDB27111" --serviceDisplayName "MongoDB27111" --install mongod --replSet mySet --port 27112 --dbpath C:\MongoDb\slavedb --logpath C:\MongoDb\slavelog\MongDb.log --serviceName "MongoDB27112" --serviceDisplayName "MongoDB27112" --install mongod --replSet mySet --port 27113 --dbpath C:\MongoDb\arbiterdb --logpath C:\MongoDb\arbiterlog\MongDb.log --serviceName "MongoDB27113" --serviceDisplayName "MongoDB27113" --install
如果开启远程的话,还需要加入
mongod --replSet mySet --port 27111 --dbpath C:\MongoDb\masterdb --logpath C:\MongoDb\masterlog\MongDb.log --bind-ip 0.0.0.0 --serviceName "MongoDB27111" --serviceDisplayName "MongoDB27111" --install
--replSet mySet:表明了所属的副本集
--port 27111:端口号
--dbpath C:\MongoDb\masterdb:数据存放地址
--logpath C:\MongoDb\masterlog\MongDb.log:日志存放地址
--serviceName "MongoDB27111":服务名称
--serviceDisplayName "MongoDB27111":服务显示名称
--install :安装
运行完成之后得到三个服务如下:
实际上是没有启动的,需要我们手动启动,也可以命令启动
net start MongoDB27111
5、服务启动之后,需要来设置谁是主节点、谁是从节点、谁是仲裁节点。
先登入27111这个服务,进入bin下执行
mongo --port 27111
登录成功应该是这样的,起码文字差不多
我们进入27111的实例之后,再次执行配置命令
初始化 第一种方式: >rs.initiate({"_id":"mySet",members:[{_id:0,host:"127.0.0.1:27111"},{_id:1,host:"127.0.0.1:27112"},{_id:2,host:"127.0.0.1:27113",aibiterOnly:true}]}); 初始化 第二种方式: >cfg={ _id:"mySet", members:[ {_id:0,host:'127.0.0.1:27111',priority:2}, {_id:1,host:'127.0.0.1:27112',priority:1},{_id:2,host:'127.0.0.1:27113',arbiterOnly:true}]}; >rs.initiate(cfg)
注意看:最后一个节点多了一个参数:
aibiterOnly:true
意思是这三个实例组成的集群里面,你来担任仲裁节点,仲裁选择的对象就是前面那两个。
看到下面这个内容说明设置成功了。
{ "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1590769503, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1590769503, 1) }
设置成功之后,我们要进行管理,需要以下命令
>rs.status() #查看状态 >rs.remove("127.0.0.1:27112") #删除一个副本 >rs.reconfig({"_id":"mySet",members:[{_id:0,host:"127.0.0.1:27111"},{_id:2,host:"127.0.0.1:27113",arbiterOnly:true}]}) #改成新的配置 >rs.reconfig({"_id":"mySet",members:[{_id:0,host:"127.0.0.1:27111"},{_id:1,host:"127.0.0.1:27112"},{_id:2,host:"127.0.0.1:27113","aibiterOnly":"true"}]})#改成新的配置 或者 >cfg={ _id:"mySet", members:[ {_id:0,host:'127.0.0.1:27111',priority:2}, {_id:1,host:'127.0.0.1:27112',priority:1},{_id:2,host:'127.0.0.1:27113',arbiterOnly:true}]}; >rs.reconfig(cfg) >rs.reconfig(cfg, {force:true}); //覆盖操作
如果是远程连接,不应该写成127.0.0.1,应该写成服务器IP
>cfg={ _id:"mySet", members:[ {_id:0,host:'4.50.40.35:27111',priority:2}, {_id:1,host:'4.50.40.35:27112',priority:1},{_id:2,host:'4.50.40.35:27113',arbiterOnly:true}]}; >rs.reconfig(cfg, {force:true}); //覆盖操作
我们看一下rs.status()这个命令,执行得到以下内容
> rs.status() { "set" : "mySet", "date" : ISODate("2020-05-29T16:25:12.670Z"), "myState" : 1, "term" : NumberLong(4), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "heartbeatIntervalMillis" : NumberLong(2000), "majorityVoteCount" : 2, "writeMajorityCount" : 2, "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1590769503, 1), "t" : NumberLong(4) }, "lastCommittedWallTime" : ISODate("2020-05-29T16:25:03.951Z"), "readConcernMajorityOpTime" : { "ts" : Timestamp(1590769503, 1), "t" : NumberLong(4) }, "readConcernMajorityWallTime" : ISODate("2020-05-29T16:25:03.951Z"), "appliedOpTime" : { "ts" : Timestamp(1590769503, 1), "t" : NumberLong(4) }, "durableOpTime" : { "ts" : Timestamp(1590769503, 1), "t" : NumberLong(4) }, "lastAppliedWallTime" : ISODate("2020-05-29T16:25:03.951Z"), "lastDurableWallTime" : ISODate("2020-05-29T16:25:03.951Z") }, "lastStableRecoveryTimestamp" : Timestamp(1590769476, 1), "lastStableCheckpointTimestamp" : Timestamp(1590769476, 1), "electionCandidateMetrics" : { "lastElectionReason" : "electionTimeout", "lastElectionDate" : ISODate("2020-05-29T16:17:55.803Z"), "electionTerm" : NumberLong(4), "lastCommittedOpTimeAtElection" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "lastSeenOpTimeAtElection" : { "ts" : Timestamp(1590769022, 1), "t" : NumberLong(2) }, "numVotesNeeded" : 2, "priorityAtElection" : 1, "electionTimeoutMillis" : NumberLong(10000), "numCatchUpOps" : NumberLong(0), "newTermStartDate" : ISODate("2020-05-29T16:17:55.970Z"), "wMajorityWriteAvailabilityDate" : ISODate("2020-05-29T16:17:56.587Z") }, "members" : [ { "_id" : 0, "name" : "127.0.0.1:27111", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 453, "optime" : { "ts" : Timestamp(1590769503, 1), "t" : NumberLong(4) }, "optimeDate" : ISODate("2020-05-29T16:25:03Z"), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1590769075, 1), "electionDate" : ISODate("2020-05-29T16:17:55Z"), "configVersion" : 4, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 1, "name" : "127.0.0.1:27112", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 6, "optime" : { "ts" : Timestamp(1590769503, 1), "t" : NumberLong(4) }, "optimeDurable" : { "ts" : Timestamp(1590769503, 1), "t" : NumberLong(4) }, "optimeDate" : ISODate("2020-05-29T16:25:03Z"), "optimeDurableDate" : ISODate("2020-05-29T16:25:03Z"), "lastHeartbeat" : ISODate("2020-05-29T16:25:11.956Z"), "lastHeartbeatRecv" : ISODate("2020-05-29T16:25:12.022Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "127.0.0.1:27111", "syncSourceHost" : "127.0.0.1:27111", "syncSourceId" : 0, "infoMessage" : "", "configVersion" : 4 }, { "_id" : 2, "name" : "127.0.0.1:27113", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 6, "lastHeartbeat" : ISODate("2020-05-29T16:25:11.956Z"), "lastHeartbeatRecv" : ISODate("2020-05-29T16:25:12.492Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "127.0.0.1:27112", "syncSourceHost" : "127.0.0.1:27112", "syncSourceId" : 1, "infoMessage" : "", "configVersion" : 4 } ], "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1590769503, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1590769503, 1) }
“health”:1 //1表明状态是正常,0表明异常
“stateStr”: "PRIMARY", #代表是主节点,可读写,其中有以下几下状态
STARTUP:刚加入到复制集中,配置还未加载
STARTUP2:配置已加载完,初始化状态
RECOVERING:正在恢复,不适用读
ARBITER: 仲裁者
DOWN:节点不可到达
UNKNOWN:未获取其他节点状态而不知是什么状态,一般发生在只有两个成员的架构
REMOVED:移除复制集
ROLLBACK:数据回滚,在回滚结束时,转移到RECOVERING或SECONDARY状态
FATAL:出错。查看日志grep “replSet FATAL”找出错原因,重新做同步
PRIMARY:主节点
SECONDARY:备份节点
6、测试一下,首先往27111节点写入数据
> use test #进入或者创建test库 > db.createCollection("yangshaofeng") #创建集合 > db.yangshaofeng.insert({"name" : "博客"}) #往集合中写入数据 如果没有集合自动创建
看一看是否在27112和27113两个实例同步了同样的数据。
再测试一下仲裁节点,你把27111服务直接停了,然后再去27112查看一下rs.status(),看看状态变化。
到这里MongoDb副本集已经配置完了,知识点很多,这篇文章篇幅有限,无法全部罗列,各位自己去学习吧。
留下您的脚步
最近评论