技术思绪摘录旅行笔记
MongoDB在4.0之后,增加了事务,说明Mongodb生态越来越丰富,将来肯定可以满足更多的应用场景,在用了事务之后,操作数据的时候报错,提示实例需要是副本集,这篇文章就说一下,什么是副本集,能干啥?

Mongodb和Redis都是NoSql阵营的数据库,所以他们有异曲同工之处。

Redis主从配置文章:Redis主从同步及其哨兵的配置和使用(Windows)

这篇文章记录了Mongodb的主从配置。他们有些东西是可以对应着来理解的。

首先说明一下几个名词:

1、副本集:Mongodb中主从复制的集合,简称副本集,Redis中是主从同步功能一致。

2、主节点:也就是可读可写的节点,但是一般用来写,Redis中也有这个概念。

3、从节点:自动同步主节点的数据,一般用来读取数据,写入数据默认关闭的,可以开启,Redis中也有这个概念。

4、仲裁节点:当主节点挂掉之后,自动选举出新的主节点,这个和Redis中哨兵是一个概念。


下载Mongodb

MongoDB官方社区版

无论是msi还是zip的版本,使用上都是一样的,我更愿意选择zip,因为更加简洁,很多东西自己可以控制。

msi文件就是安装包,下一步就行,我这里使用zip进行演示。

解压到指定目录,得到这样的内容

image.png

进入到bin目录,这就是所有文件,没有配置文件

image.png

开始安装

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 :安装

运行完成之后得到三个服务如下:

image.png

实际上是没有启动的,需要我们手动启动,也可以命令启动

net start MongoDB27111

5、服务启动之后,需要来设置谁是主节点、谁是从节点、谁是仲裁节点。

先登入27111这个服务,进入bin下执行

mongo --port 27111

登录成功应该是这样的,起码文字差不多

image.png

我们进入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副本集已经配置完了,知识点很多,这篇文章篇幅有限,无法全部罗列,各位自己去学习吧。

CarsonIT 微信扫码关注公众号 策略、创意、技术

留下您的脚步

 

最近评论

查看更多>>

站点统计

总文章数:276 总分类数:18 总评论数:90 总浏览数:170.64万

精选推荐

阅读排行

友情打赏

请打开您的微信,扫一扫