Mongodb的replication主要有两种:主从和副本集(replica set)。主从的原理和mysql类似,主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。 
   现在mongodb官方建议用副本集替代主从复制,现在我们来了解下如何配置复制集。

什么是oplog:

  MongoDB 的Replication是通过一个日志来存储写操作的,这个日志就叫做oplog。 在默认情况下,oplog分配的是5%的空闲磁盘空间。通常而言,这是一种合理的设置。可以通过mongod --oplogSize来改变oplog的日志大小。 oplog是capped collection,因为oplog的特点(不能太多把磁盘填满了,固定大小)需要,MongoDB才发明了capped collection(the oplog is actually the reason capped collections were invented)。

  oplog的位置 oplog在local库:  replica sets 架构下: local.oplog.rs。

现在来用两台服务器来配置一个复制集,两个数据节点+一个仲裁节点

db1配置(mongodb.conf )(数据节点)

# 数据库文件存储位置
dbpath = /data/db/mongodb
# log文件存储位置
logpath = /data/log/mongodb/mongodb.log
# 使用追加的方式写日志
logappend = true
# 是否以守护进程方式运行
fork = true
# 端口号
port =
# 是否启用认证
auth = true
# 集群的私钥的完整路径,只对于Replica Set 架构有效(noauth = true时不用配置此项)
keyFile = /usr/local/mongodb/mongodb-keyfile
# diaglog选项 =off =W =R =both =W+some reads
#diaglog =
# 设置oplog的大小(MB)
oplogSize=
# 启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里
journal=true
# 设置副本集名称
replSet=COOL

db2配置(standard.conf )(数据节点)

# 数据库文件存储位置
dbpath = /data/db/mongodb/standard
# log文件存储位置
logpath = /data/log/mongodb/standard/mongodb.log
# 使用追加的方式写日志
logappend = true
# 是否以守护进程方式运行
fork = true
# 端口号
port =
# 是否启用认证
auth = true
# 集群的私钥的完整路径,只对于Replica Set 架构有效(noauth = true时不用配置此项)
keyFile = /usr/local/mongodb/mongodb-keyfile
# diaglog选项 =off =W =R =both =W+some reads
#diaglog =
# 设置oplog的大小(MB)
oplogSize=
# 启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里
journal=true
# 设置副本集名称
replSet=COOL

db3配置(arbiter.conf )(arbiter节点)

# 数据库文件存储位置
dbpath = /data/db/mongodb/arbiter
# log文件存储位置
logpath = /data/log/mongodb/arbiter/mongodb.log
# 使用追加的方式写日志
logappend = true
# 是否以守护进程方式运行
fork = true
# 端口号
port =
# 是否启用认证
auth = true
# 集群的私钥的完整路径,只对于Replica Set 架构有效(noauth = true时不用配置此项)
keyFile = /usr/local/mongodb/mongodb-keyfile
# diaglog选项 =off =W =R =both =W+some reads
#diaglog =
# 设置oplog的大小(MB)
oplogSize=
# 启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里
journal=true
# 设置副本集名称
replSet=COOL

注意:

  如果使用认证的方式启动服务(auth = true),那么要在主从服务器配置私钥。

//    在一台服务器上生成私钥
openssl rand -base64 745 > mongodb-keyfile // 修改私钥的权限为可读写
chmod 600 mongodb-keyfile // 将私钥拷贝到其余的服务器上
scp mongodb-keyfile root@xxx.xxx.xxx.xxx:/usr/local/mongodb/

  然后配置私钥路径,启动服务。

配置root管理员成员,用于权限验证和管理数据库和执行副本集初始化命令(只需要在primary上配置就行,副本集会同步用户)

  先以非验证模式启动数据库:

/usr/local/mongodb/bin/mongod --fork --dbpath=/data/db/mongodb --logpath=/data/log/mongodb/mongodb.log

  配置管理员:

use admin;

db.createUser({ user: "root", pwd: "root", roles: [ { role: "root", db: "admin" } ] });

  然后以权限验证模式(config模式)重启数据库服务。

启动数据库:

//    第一台主机:
/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/master.conf // 第二台主机:
/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/standard.conf
/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/arbiter.conf

初始化副本集(连接任意一个服务器。初始化命令只执行一次即可,如果是已有数据的数据库,请在有数据的数据库执行此命令)

  以刚刚创建的root用户登录:

  查看副本集状态( rs.status() ):

  发现副本集还未初始化,现在开始初始化:

config = {"_id" : "COOL",    "members" : [   {"_id" : 0, "host" : "xxx.xxx.xxx.xxx:27017"},   {"_id" : 1, "host" : "xxx.xxx.xxx.xxx:27017"}  ]}

rs.initiate(config);

  初始化副本集成功,再次查看副本集状态:

COOL:SECONDARY> rs.status()
{
"set" : "COOL",
"date" : ISODate("2018-01-10T13:13:01.988Z"),
"myState" : 2,
"term" : NumberLong(0),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"appliedOpTime" : {
"ts" : Timestamp(1515589972, 1),
"t" : NumberLong(-1)
},
"durableOpTime" : {
"ts" : Timestamp(1515589972, 1),
"t" : NumberLong(-1)
}
},
"members" : [
{
"_id" : 0,
"name" : "xxx.xxx.xxx.xxx:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 82,
"optime" : {
"ts" : Timestamp(1515589972, 1),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("2018-01-10T13:12:52Z"),
"infoMessage" : "could not find member to sync from",
"configVersion" : 1,
"self" : true
},
{
"_id" : 1,
"name" : "xxx.xxx.xxx.xxx:27017",
"health" : 1,
"state" : 5,
"stateStr" : "STARTUP2",
"uptime" : 9,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2018-01-10T13:12:57.888Z"),
"lastHeartbeatRecv" : ISODate("2018-01-10T13:13:01.911Z"),
"pingMs" : NumberLong(32),
"syncingTo" : "xxx.xxx.xxx.xxx:27017",
"configVersion" : 1
}
],
"ok" : 1
}

  发现自己变成了secondary节点,另一个数据库变成了startup2状态,没关系,等下自己会变成primary节点,等另一个数据库同步数据完成,会自动变成secondary节点。

COOL:SECONDARY> rs.status()
{
"set" : "COOL",
"date" : ISODate("2018-01-10T13:35:59.935Z"),
"myState" : 2,
"term" : NumberLong(1),
"syncingTo" : "xxx.xxx.xxx.xxx:27017",
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1515591358, 6),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1515591358, 6),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1515591358, 6),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "xxx.xxx.xxx.xxx:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1385,
"optime" : {
"ts" : Timestamp(1515591358, 6),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1515591358, 4),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-01-10T13:35:58Z"),
"optimeDurableDate" : ISODate("2018-01-10T13:35:58Z"),
"lastHeartbeat" : ISODate("2018-01-10T13:35:58.921Z"),
"lastHeartbeatRecv" : ISODate("2018-01-10T13:35:59.545Z"),
"pingMs" : NumberLong(2),
"electionTime" : Timestamp(1515589983, 1),
"electionDate" : ISODate("2018-01-10T13:13:03Z"),
"configVersion" : 1
},
{
"_id" : 1,
"name" : "xxx.xxx.xxx.xxx:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 3603,
"optime" : {
"ts" : Timestamp(1515591358, 6),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-01-10T13:35:58Z"),
"syncingTo" : "xxx.xxx.xxx.xxx:27017",
"configVersion" : 1,
"self" : true
}
],
"ok" : 1
}

这时我们可以到secondary所在的服务器查看日志,可以在日志查看到同步信息:

--10T21::57.124+ I REPL     [repl writer worker ] CollectionCloner::start called, on ns:cocheer.9_users
--10T21::57.148+ I INDEX [InitialSyncInserters-cocheer.9_users0] build index on: cocheer.9_users properties: { v: , unique: true, key: { openid: }, name: "openid_1", ns: "cocheer.9_users", background: true }
--10T21::57.148+ I INDEX [InitialSyncInserters-cocheer.9_users0] building index using bulk method; build may temporarily use up to megabytes of RAM

增加第三个节点,arbiter节点:

rs.addArb("xxx.xxx.xxx.xxx:27018")

  

COOL:PRIMARY> rs.status()
{
"set" : "COOL",
"date" : ISODate("2018-01-10T14:09:29.751Z"),
"myState" : 1,
"term" : NumberLong(1),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1515593366, 2),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1515593366, 2),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1515593366, 2),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "xxx.xxx.xxx.xxx:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 3470,
"optime" : {
"ts" : Timestamp(1515593366, 2),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-01-10T14:09:26Z"),
"electionTime" : Timestamp(1515589983, 1),
"electionDate" : ISODate("2018-01-10T13:13:03Z"),
"configVersion" : 2,
"self" : true
},
{
"_id" : 1,
"name" : "xxx.xxx.xxx.xxx:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 3396,
"optime" : {
"ts" : Timestamp(1515593366, 2),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1515593366, 2),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-01-10T14:09:26Z"),
"optimeDurableDate" : ISODate("2018-01-10T14:09:26Z"),
"lastHeartbeat" : ISODate("2018-01-10T14:09:27.797Z"),
"lastHeartbeatRecv" : ISODate("2018-01-10T14:09:27.876Z"),
"pingMs" : NumberLong(3),
"syncingTo" : "xxx.xxx.xxx.xxx:27017",
"configVersion" : 2
},
{
"_id" : 2,
"name" : "xxx.xxx.xxx.xxx:27018",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 68,
"lastHeartbeat" : ISODate("2018-01-10T14:09:27.803Z"),
"lastHeartbeatRecv" : ISODate("2018-01-10T14:09:26.860Z"),
"pingMs" : NumberLong(2),
"configVersion" : 2
}
],
"ok" : 1
}

如果想修改复制集的配置,也可以使用rs.reconfig(config,{"force":true})强制更新配置。

var config = rs.config()
config.members[0].host = '172.18.169.230:27017'
config.members[1].host = '172.18.169.232:27017'
config.members[2].host = '172.18.169.232:27018'
rs.reconfig(config,{"force":true})

再次通过rs.status()命令查看复制集的状态,可以看到配置已经修改并生效。

secondary节点默认是不可读的,如果需要读secondary节点,需要在secondary节点上输入命令:

db.getMongo().setSlaveOk()
// 或者
rs.slaveOk()

只是每次重新登录secondary节点都需要输入此命令。

顺便贴一下mongoose连接复制集的option:

options = {
autoReconnect: true,
poolSize: 8,
promiseLibrary: global.Promise,
useMongoClient: true,
keepAlive: 1,
connectTimeoutMS: 30000,
reconnectTries: 100,
replicaSet: 'COOL',
readPreference: 'secondaryPreferred',
}

没有问题,大功告成!

mongodb配置复制集replset的更多相关文章

  1. 搭建mongoDB 配置副本集 replSet

    mongodb的master_slave和ReplSet是很常见的两种构架: 下面记录下搭建mongodbReplSet 的过程: 首先,进入到一个指定目录下 >cd /opt 下载mongod ...

  2. Mongodb 基础 复制集原理和搭建

    数据复制原理 开启复制集后,主节点会在local库下生成一个集合叫 oplog.rs,这是一个有限的集合,即大小固定.这个集合记入了整个mongod实例一段时间内数据库的所有变更操作(如:增/删/改) ...

  3. MongoDB 部署复制集(副本集)

    部署MongoDB复制集(副本集)   环境 操作系统:Ubuntu 18.04 MongoDB: 4.0.3 服务器 首先部署3台服务器,1台主节点 + 2台从节点 3台服务器的内容ip分别是: 1 ...

  4. mongodb之 复制集维护小结

    原文地址:https://www.cnblogs.com/zhaowenzhong/p/5667312.html 一.新增副本集成员 1.登录primary 2.use admin >rs.ad ...

  5. MongoDB之 复制集搭建

    MongoDB复制集搭建步骤,本次搭建使用3台机器,一个是主节点,一个是从节点,一个是仲裁者. 主节点负责与前台客户端进行数据读写交互,从节点只负责容灾,构建高可用,冗余备份.仲裁者的作用是当主节点宕 ...

  6. docker添加mongo4.0.3并配置复制集

    1.创建docker 具体略过 自行百度 2.创建数据持久化目录文件(/data/mongo0是个例子 命名随意)  拉取mongo docker pull mongo:4.0.3 3.启动容器 do ...

  7. mongodb配置副本集(多台服务器间的副本集搭建) replica[ˈrɛplɪkə]

    副本集具有多个副本保证了容错性,就算一个副本挂掉了还有很多副本存在,并且解决了“主节点挂掉了,整个集群内会自动切换”的问题.我们来看看mongoDB副本集的架构图: 由图可以看到客户端连接到整个副本集 ...

  8. 利用Mongodb的复制集搭建高可用分片,Replica Sets + Sharding的搭建过程

    参考资料 reference:  http://mongodb.blog.51cto.com/1071559/740131  http://docs.mongodb.org/manual/tutori ...

  9. mongoDB的复制集5----复制集安全(认证,用户,权限)

    一.什么是认证  如何开启认证    1).auth=true(在配置文件里增加)    2).keyFile(建议添加到配置文件里) #如果设置了auth=true,但第一次没有创建用户就启动实例怎 ...

随机推荐

  1. PHP Web开发入门流程

    在学习WEB开发前,至少有一个对C或者计算机编程任何一种语言的基本学习,这会对你以后的开发有一定的启蒙作用. 一.Web开发入门 推荐学习网址: http://www.w3school.com.cn/ ...

  2. jQuery任意标签锚点跳转插件

    // 任意锚点平滑跳转插件// 2010-07-15 v1.0(function($){ $.fn.zxxAnchor = function(options){ var defaults = { ie ...

  3. 使用 PHP + shell 生成 一键设置权限的脚本。

    linux 系统 支持PHP脚本一键设置环境.shell脚本一键设置环境.那么 我今天 使用 PHP  + shell 生成 一键设置权限的脚本. 举例子:linux服务器 一键配置discuz网站环 ...

  4. 【makefile】symbol <函数> : can't resolve symbol 问题分析

    调试程序的时候,在linux编译器上可以编译通过,但是编译生成的firmware烧录到板子上的后出现以下异常: can't resolve symbol,无法解析元素符号. review一下code, ...

  5. 后端传前端数据乱码(返回json字符串到前端)

    中文乱码的问题,在开发过程中难免会遇到,而在配置好编码之后,不管是数据库,还是其他地方都配置好统一UTF-8编码之后,后端从数据库取出数据传回前端,还会乱码,这里以ssm框架为例,因为是我自己遇到的, ...

  6. Linux 搭建 squid 代理服务器 三种模式

    CentOS 6.7 squid 代理服务器 一般有两张或以上网卡,一张链接公网,访问外网资源,一张位于局域网. 代理服务器可以提供文件缓存.复制和地址过滤等服务,充分利用有限的出口带宽,加快内部主机 ...

  7. 集训第六周 数学概念与方法 概率 F题

    Submit Status Description Sometimes some mathematical results are hard to believe. One of the common ...

  8. hive 删除表内容

    TRUNCATE:truncate用于删除所有的行,这个行为在hive元存储删除数据是不可逆的delect:用于删除特定行条件,你可以从给定表中删除所有的行insert overwrite table ...

  9. [luoguP1440] 求m区间内的最小值(单调队列 || 线段树)

    传送门 这种水题没必要搞线段树了,单调队列就行啊. ——代码 #include <cstdio> ; , t = ; int a[MAXN], q[MAXN]; int main() { ...

  10. 【ZZ】神与学霸的区别

    神与学霸的共同点是积点都令人发指得高,这也是他们的主要特征,或者说是基本特征.但是他们的区别也是很大的. 平时打电话给普通人:喂在干嘛? 玩 玩什么? 逛街/唱k/打游戏/看电影/睡觉/... 打电话 ...