MongoDB 搭建副本集
副本集(Replica Set)是一组MongoDB实例组成的集群,由一个主(Primary)服务器和多个备份(Secondary)服务器构成。通过Replication,将数据的更新由Primary推送到其他实例上,在一定的延迟之后,每个MongoDB实例维护相同的数据集副本。通过维护冗余的数据库副本,能够实现数据的异地备份,读写分离和自动故障转移。
一,MongoDB版本和环境
在Windows上创建包含三个节点的副本集,使用的环境:
- 数据库:MongoDB 版本 3.2.9
- Server 环境:Windows Server 2012 R2
- 可视化编程环境:Robomongo 版本 0.08.4
- 三台Windows Server:srv1,srv2,srv3
二,拓扑结构分析
创建一个Replica Set,包含三个成员:一个Primary 成员和两个Secondary 成员,Primary用于处理客户端请求,Secondary用于保存Primary的数据副本。客户端Application 在 Primary 节点上进行读写操作,通过Replication的异步同步机制,将数据操作同步到 Secondary 成员,在一定的延迟之后,三个成员拥有相同的数据集。
理论上,每个成员可以分布在不同的数据中心机房内,这些数据中心可能相距甚远,实现数据的异地备份;可以设置Primary 节点只负责写入操作,而使Secondary节点负责读取操作,实现数据集的读写分离;如果Primary 连接中断超过10s,其他节点会自动选举出一个Primary 节点,负责响应客户端Application的请求,实现数据的自动故障转移。
三,技术原理说明
1,以Replica Set模式启动MongoDB实例
MongoDB Instance有两种不同的启动方式:单机模式(Standalone)和副本集模式(Replica Set),在启动mongod时,如果设置 replSet 参数,那么MongoDB 实例以副本集模式启动;如果不设置replSet 参数,那么MongoDB以单机模式启动。
单机实例是指运行在服务器上的一个mongod 进程,该进程不是任何一个Replica Set的成员,因此,单机实例不能自动故障转移,在产品环境中,风险很高,如果服务器崩溃了,客户端App至少在一段时间内不可访问,如果硬件出现问题,可能会造成数据的永久丢失。建议,使用Replica Set,至少保留两份数据集副本。
2,选举Primary成员
在Replica Set中有两种成员:Primary成员和Secondary成员,一个Replica Set只能有一个Primary成员,但可以有多个Secondary成员。Primary用于处理客户端请求,Secondary用于保存Primary的数据副本。如果Primary崩溃了,Replica Set探测到Primary不可访问,将启动自动故障转移进程,从剩下的Secondary成员中,投票选举出一个成员作为Primary,接收和处理客户端的请求。
选举Primary成员时,使用“大多数”和“一票否决”原则。在Replica Set中,每个成员只能要求自己被选举为Primary节点。当一个Secondary成员无法与Primary成员连通时,该成员就会发起选举,请求其他成员将自己选举为Primary成员,只有得到“大多数”成员的支持,该成员才能被选举为Primary成员;只要有一个成员否决,选举就会取消。
不是每一个成员都有投票选举的权利,在一个Replica Set中,最多有7个成员用于投票选举的权利,Primary成员是由这7个成员选举出来的。有投票权利的成员,其属性:"votes" 是1;若为0,表示该成员没有投票权利。
3,操作日志
MongoDB使用操作日志(oplog)来实现复制(Replication)功能,oplog包含了Primary成员的每一个更新操作,通过将oplog传递到其他Secondary成员中,在其他成员中重做(redo)已经提交的操作,实现数据的异步同步。Replica Set中的每个成员都维护着自己的oplog,记录着每一个从Primary成员复制操作的数据。复制操作的过程是先复制数据,再将操作写入到oplog中。如果某一个成员在执行操作时失败,当该成员重启之后,自动从oplog中最后一个操作进行同步。由于复制操作的过程是先复制数据,再写入oplog,该成员可能会在已经同步的数据上再次执行复制操作,MongoDB在设计oplog时,就考虑到这种情况:将oplog中的同一个操作执行多次,与执行一次的结果是一样的。
oplog保存的是对每个doc的更新操作日志,如果一个命令只更新一个doc,那么Replication进程向oplog插入一条日志;如果一个命令更新多个doc,那么Replication进程向oplog插入多条日志,每一条日志只更新一个doc。
oplog的大小是固定的,只能保存特定数量的操作日志,如果Primary成员更新的数据量特别大,oplog很快就被填满,Secondary来不及同步数据,Primary成员就将oplog中的日志,这样,Secondary成员就会变成陈旧的(Stale)。建议,让Primary成员使用比较大的oplog,保存足够多的操作日志。
四,创建配置文档
1,创建mongod 启动的配置文件
在每台server上创建配置文件,将配置文件存放在目录C:\data\中。在同一个Replica Set中的所有成员必须有相同的Replica Set Name,这里设置为“rs0”。
--srv1 config_file_name:rs0_1.conf
dbpath=C:\data\db\db_rs0
logpath=C:\data\db\db_rs0\rs0_1.log
port=40001
replSet=rs0 --srv2 config_file_name:rs0_2.conf
dbpath=C:\data\db\db_rs0
logpath=C:\data\db\db_rs0\rs0_2.log
port=40002
replSet=rs0 --srv3 config_file_name:rs0_3.conf
dbpath=C:\data\db\db_rs0
logpath=C:\data\db\db_rs0\rs0_3.log
port=40003
replSet=rs0
配置参数含义:
- replSet:设置Replica Set的name,在各个配置文件中,其值必须相同。
- dbpath:MongoDB用于存储数据的目录,默认值是C:\data\db
- logpath:用于记录mongod的日志数据
- port:指定MongoDB监听的端口,默认值是27017
2,以配置文件方式启动mongod
一般情况下,mongod的参数值是不变的,将这些参数写入到配置文件中,能够简化MongoDB的管理。
mongod 命令有参数:--config 或 -f,用于引用配置文件。
--srv1
mongod -f C:\data\rs0_1.conf --srv2
mongod -f C:\data\rs0_2.conf --srv3
mongod -f C:\data\rs0_3.conf
3,启动mongo shell
在任意一台Server上打开三个mongo shell,使用参数 --host 指定Server Name,使用 --port 指定端口号。由于mongod没有使用默认的监听端口 27017,因此,必须使用 在mongo shell中使用 --port参数显式指定监听的Port。
--connect srv1
mongo --host srv1 --port 40001 --connect srv2
mongo --host srv2 --port 40002 --connect srv3
mongo --host srv3 --port 40003
五,配置Replica Set
在不同的Server上运行不同的MongoDB Instance,但是,每个mongod 都不知道其他mongod的存在,为了让每个mongod能够感知彼此的存在,需要配置Replica set,增加成员。
1,使用配置文档为Replica Set 增加成员
在srv1的mongo shell中,创建配置文档,调用rs.initiate()函数,按照配置文档来初始化Replica Set。
conf=
{
"_id" : "rs0",
"members" : [
{ "_id" : 0, "host" : "srv1:40001" },
{ "_id" : 1, "host" : "srv2:40002" },
{ "_id" : 2, "host" : "srv3:40003" }
]
} rs.initiate(conf)
在配置doc中,使用"_id" : "rs0" 指定Replica Set的name,members数组指定 Replica Set的成员的ID 和 host(“host:port”)。等到所有成员配置完成之后,Replica Set 会自动选举出一个Primary 节点,两个Secondary 节点。在Primary 节点上进行更新操作,就能同步到Secondary 节点了。
2,修改Replica Set
如果以rs.initiate()方式初始化Replica Set,那么MongoDB以默认配置文档初始化Replica Set,可以通过add()函数增加成员。
2.1 向Replica Set中增加一个成员
rs.add("host:port")
2.2 从Replica Set中删除一个成员
rs.remove("host")
2.3 查看Replica Set的配置
rs.conf()
2.4 重新配置Replica Set
var conf=rs.conf()
conf.members[1].priority =5
--at primary member
rs.reconf(conf) --at secondary member
rs.reconf(conf,{force:true})
2.5 查看Replica Set的状态
rs.status()
六,维护Replica Set
1,查看Replica Set的配置信息
rs.conf()
配置文档主要分为三块:Replica Set 的ID和 Version,Members数组 和 Settings,下面是经过简化的配置信息。
{
"_id" : "rs0",
"version" : 202997,
"members" : [
{
"_id" : 1,
"host" : "srv1:40001",
"arbiterOnly" : false,
"hidden" : false,
"priority" : 5,
"votes" : 1
}, {...}
],
"settings" : { ..... }
}
Replica Set的ID字段唯一标识一个Replica Set,每一个Replica Set都有一个自增的版本号,由Version字段标识,标识Replica Set的不同版本。version字段的初始值是1,每次修改Replica Set的配置时,version字段都会自增。
Settings 字段的值是应用到Replica Set中所有成员的配置信息。
最关键的是members数组的字段,标识每个成员的配置信息。
- arbiterOnly:0或1,标识一个仲裁(arbiter),Arbiter的唯一作用是参与Primary的选举,Arbiter不保存数据,不会为client提供服务,它存在的意义就是为了选举Primary。
- hidden:0或1,表示该成员是不是隐藏成员,Hidden成员的主要作用是备份数据,可以使用性能较差的服务器作为Hidden成员。Hidden成员不会接收Client的请求,也不会成为Primary。在设置Hidden成员时,必须设置members[n].priorty属性为0;
- priority:数值类型,用于设置成员成为Primary的优先级。priority越高的成员,越有机会成为Primary。如果priority=0,那么该成员永远不会成为Primary。
- votes:1或0,表示该成员的投票的数量,在每个Replica Set中,最多有7个成员,其votes属性值是1。votes 属性是1的成员(voting members)拥有选举Primary的权利。一个成员要想成为一个Primary,那么必须获得voting members的大多成员的支持。
在Replica Set中,如果voting members的数量是5,那么一个成员成为Primary的条件是:获得超过2个voting members的支持,并且没有任何voting members 反对。只要有任意一个voting member 反对该成员成为Primary,那么该成员就不能成为Primary。
2,强制一个成员成为Primary
如果将一个成员的priority属性在Replica Set的所有成员中是最高的,那么该成员最有可能成为Primary。
将成员0的priority设置5,其他成员的priority设置为1,这样,成员0成为Primary的优先级是最高的。
cfg = rs.conf()
cfg.members[0].priority = 5
cfg.members[1].priority = 1
cfg.members[2].priority = 1
rs.reconfig(cfg)
七,测试数据
1,在Primary上读写数据
db.users.insert({_id:1,name:"a",age:24})
2,在Secondary上读取数据
默认情况下,客户端不能从Secondary成员中读取数据。在Secondary成员上显式执行setSlaveOk之后,才能从Secondary节点读取数据。
rs.setSalveOk() db.users.find({_id:1})
八,查看mongod 服务器的命令行参数
db.serverCmdLineOpts()
/* 0 */
{
"argv" : [
"mongod",
"-f",
"C:\\data\\rs0_1.conf"
],
"parsed" : {
"config" : "C:\\data\\rs0_1.conf",
"net" : {
"port" : 40001
},
"replication" : {
"replSet" : "rs0"
},
"storage" : {
"dbPath" : "C:\\data\\db\\db_rs0"
},
"systemLog" : {
"destination" : "file",
"path" : "C:\\data\\db\\db_rs0\\rs0_1.log"
}
},
"ok" : 1
}
参考doc:
Force a Member to Become Primary
MongoDB 搭建副本集的更多相关文章
- MongoDB集群搭建-副本集
MongoDB集群搭建-副本集 概念性的知识,可以参考本人博客地址: 一.Master-Slave方案: 主从: 二.Replica Set方案: 副本集: 步骤:(只要按步骤操作,100%成功) 1 ...
- Mongodb主从复制/ 副本集/分片集群介绍
前面的文章介绍了Mongodb的安装使用,在 MongoDB 中,有两种数据冗余方式,一种 是 Master-Slave 模式(主从复制),一种是 Replica Sets 模式(副本集). Mong ...
- MongoDB-3.4搭建副本集
搭建副本集 1:首先创建3台虚拟机作为配置环境 IP1:192.168.101.175 IP2:192.168.101.176 IP3:192.168.101.177 2.下载MongoDB 3.4版 ...
- [DataBase] MongoDB (8) 副本集
MongoDB 创建副本集 MongoDB复制是将数据同步在多个服务器的过程. 复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性. 复制还允许您从 ...
- mongodb创建副本集命令
mongodb创建副本集命令 ./mongod --replSet spock --dbpath ../data --smallfiles > config ={... "_id&qu ...
- MongoDB之副本集
MongoDB之副本集 一.简介 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库 ...
- MongoDB 复制(副本集)
MongoDB复制是将数据同步在多个服务器的过程. 复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性. 复制还允许您从硬件故障和服务中断中恢复数据. ...
- MongoDb的副本集搭建教程(个人操作笔记)
很多公司都在用MongoDb ,一直没有时间研究,最近好好的整了一下,做下笔记,直接上操作步骤,关于Mongodb的理论知识可以搜索其他资料,也可以联系我索取 mongoDB官方已经不建议使用主从模式 ...
- mongodb之 3.4.0 mongodb sharing 副本集群搭建
系统系统 centos6.5三台服务器:10.100.25.42/43/44安装包: mongodb-linux-x86_64-rhel62-3.4.0.tgz 服务器规划:mongos mongos ...
随机推荐
- [转]oracle分析函数Rank, Dense_rank, row_number
oracle分析函数Rank, Dense_rank, row_number 分析函数2(Rank, Dense_rank, row_number) 目录 ==================== ...
- WP8解析XML格式文件
DOTA2 WebAPI请求返回的格式有两种,一种是XML,一种是JSON,默认是返回JSON格式,如果要返回XML格式的话,需要在加上format=xml. 这里举一个简单的解析XML格式的例子(更 ...
- 使用spring的@Scheduled注解执行定时任务,启动项目不输出警告
在applicationContext.xml中添加: xmlns:task="http://www.springframework.org/schema/task" xsi:sc ...
- NotificationCenter接收不到通知的原因
今天在项目中遇到一个奇葩的事情,我在一个类中明明写了: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #00af ...
- iOS 让按钮上的标题换行显示
项目中遇到了要让按钮上的文字换行显示的需求,就写了这个博客. 1.如果按钮上的文字固定,形式是写死的,可以考虑给标题文字加\n换行符来达到效果,但是,记得一定要设置这个属性,不然是不会换行的, but ...
- java反射技术详解
反射: 其实就是动态的从内存加载一个指定的类,并获取该类中的所有的内容. 反射的好处:大大的增强了程序的扩展性. 反射的基本步骤: 1. 获得Class对象,就是获取到指定的名称的字节码文件对象. 2 ...
- USACO翻译:USACO 2012 FEB Silver三题
USACO 2012 FEB SILVER 一.题目概览 中文题目名称 矩形草地 奶牛IDs 搬家 英文题目名称 planting cowids relocate 可执行文件名 planting co ...
- Public key for mysql....rpm is not installed
解决方案: 此时导入rpm的签名信息即可,用root登录,执行下面命令(我的linux版本是centos 5.1) 原文地址: http://my.oschina.net/u/555639/blog/ ...
- 一鼓作气 博客--第四篇 note4
1.元祖允许重复数据.只读元组,列表,元祖没有增删改查,比如身份证列表,不允许修改,就存成 元祖. 2. 字典 key-value对 特性: 无顺序 去重 查询速度快,比列表快多了 比list占用内存 ...
- JDBC增删改查简单测试
首先编写一个entity以便与数据库表文件相对应 lyTable.java public class LyTable implements java.io.Serializable { private ...