MongoDB分布式集群
Replication 复制、Replica Set 复制集/副本集 概念
一、 副本集的相关概念
1.概念
“ A replica set is a group of mongod instances that maintain the same data set. ”
- 一组MongoDB服务器(多个mongod实例)(有不同的IP或端口)(具有相同的副本集名称)
- 具有相同副本集,相同的数据 (为了保证数据的相同,需要各mongod实例间保持数据的复制)
2.副本集的组成
- Primary Node 主节点 (一个) 默认的可写节点
- Secondary Nodes 从节点 (多个)
3.复制原理
- 复制的初始化:当一个复制集被建立之初,我们需要首先初始化一个Primary主节点。
- Replication(复制)发生在Primary(主节点)和Secondaries(从节点)之间。由主节点将操作记录(oplog)同步到从节点上,从节点根据oplog进行数据更新以获得与主节点相同的数据。【读比较多,写较少,主节点可读可写,从节点只可读】
- 分担负载均衡,至少三台机器,选举需要超半数,一般是三台机器。一个T->3个T
4. 选举制度
- 当主节点不可用时,一个复制集中的其他从节点将选举出一个新的主节点
- 选举采用分级投票制:在最高优先级的节点中得票最高(超过总成员半数)的节点成为新的主节点
- 影响选举的主要副本集配置:
- members.priority
- members.votes
- 影响选举的主要副本集配置:
二、从零开始搭建PSS副本集
一个主节点,两个从节点;在一台机器上模拟三台机器,一个目录代表一个机器,创建三个目录。首先做好规划表:
- 如果不加副本集名称,那么这三台服务器之间没有关联。为了让三台服务器之间建立联系,引入相同的副本集(rs0)
- 根据规划表,创建三个配置文件xxx.ini,都需要有副本集
//server1.ini
bind_ip=127.0.0.1
port=27001
dbpath=.\server1
logpath=.\server1\mongod.log
logappend=true
replSet = rs0
//server2.ini
bind_ip=127.0.0.1
port=27002
dbpath=.\server2
logpath=.\server2\mongod.log
logappend=true
replSet = rs0
//server3.ini
bind_ip=127.0.0.1
port=27003
dbpath=.\server3
logpath=.\server3\mongod.log
logappend=true
replSet = rs0
- 写一个启动脚本文件
//创建目录,一个目录相当于一个服务器
mkdir .\server1
mkdir .\server2
mkdir .\server3
//启动3个服务器
start "MongoDB Server1" mongod --config=.\server1.ini
start "MongoDB Server2" mongod --config=.\server2.ini
start "MongoDB Server3" mongod --config=.\server3.ini
//启动3个客户端分别去连接3个服务器
start "Connect to Server1" mongo --port=27001
start "Connect to Server2" mongo --port=27002
start "Connect to Server3" mongo --port=27003
- 启动后,三个服务器之间并未建立联系
- 需要进行初始化,构造成员名单,通过initiate()函数传递名单,可以在终端执行以下语句,亦可以写在rs0conf.js中,客户端连接服务端时附带rs0conf.js配置文件
var rsconf={
_id:"rs0",
"members":[
{_id:0,host:"127.0.0.1:27001"},
{_id:1,host:"127.0.0.1:27002"},
{_id:2,host:"127.0.0.1:27003"},
]};
rs.initiate(rsconf)
-
server1默认为primary,当server1挂掉之后,其它接任,即使重启server1,它当前也不能作为primary。
-
主节点上可以创建、插入数据,但从节点没有读的功能。在secondary中运行命令会报错,报错
"codeName" : "NotPrimaryNoSecondaryOk"
,需要先在secondary运行以下命令:
rs.secondaryOk()
- primary具有读写功能,但是secondary只具有读功能。在primary中插入数据,其它两个secondary也能读到对应信息。
use zr;
db.students.insert({"name":"zhangsan"});
show dbs;
show collections;
db.students.find();
- 在primary中插入GenerateStudents.js(需要放到与PSS副本集相同的目录中)相关学生数据后,在其它两个secondary中也能看到。
load("GenerateStudents.js")
- 可以使用命令让当前的primary降级为secondary,其它服务器当选为primary
rs.stepDown();
- 查看当前配置
rs.conf();
- 默认10s中之内进行选举
复制方法
有关特定方法(包括事务语法和示例)的详细信息,请单击该方法的参考页面链接。
名称 | 说明 |
---|---|
rs.add() | 将节点添加到副本集。 |
rs.addArb() | 将仲裁节点添加到副本集。 |
rs.conf() | 返回副本集配置文档。 |
rs.freeze() | 阻止当前节点在一段时间内寻求选举为主节点。 |
rs.help() | 返回副本集函数的基本帮助文本。 |
rs.initiate()**** | 初始化新的副本集。 |
rs.printReplicationInfo() | 从主节点的角度打印副本集状态的格式化报告。 |
rs.printSecondaryReplicationInfo() | 从从节点的角度打印副本集状态的格式化报告。 |
rs.reconfig() | 通过应用新的副本集配置对象来重新配置副本集。 |
rs.reconfigForPSASet() | 在主从仲裁 (PSA) 副本集或正在更改为 PSA 架构的副本集上安全地执行某些重新配置更改。 |
rs.remove() | 从副本集中删除节点。 |
rs.status() | 返回包含副本集状态信息的文档。 |
rs.stepDown() | 导致当前的主节点变为强制选举的从节点。 |
rs.syncFrom() | 设置该副本集节点与哪个节点进行同步,复写默认的同步目标选择逻辑。 |
修改三台服务器的优先级
rs0:PRIMARY>rs.conf()//查看副本集内容,包括三台服务器的id、priority...
rs0:PRIMARY> var rsconf=rs.conf()//拿到配置信息保存到变量rsconf中
rs0:PRIMARY> rsconf.members[0].priority=9//将server1优先级改为9,默认是1
rs0:PRIMARY> rsconf.members[1].priority=0//将server2优先级改为0
rs0:PRIMARY> rs.reconfig(rsconf)//重新配置信息生效
//等待10秒,primary变为server1
- 退出primary
rs0:PRIMARY> rs.stepDown()
三、搭建PSA副本集
-
配置server4、server5、server6三台服务器,并设置仲裁节点(PSA副本集),规划表如图
-
配置文件xxx.ini
//server4.ini
bind_ip=127.0.0.1
port=27004
dbpath=.\server4
logpath=.\server4\mongod.log
logappend=true
replSet = rs1
//server5.ini
bind_ip=127.0.0.1
port=27005
dbpath=.\server5
logpath=.\server5\mongod.log
logappend=true
replSet = rs1
//server6.ini
bind_ip=127.0.0.1
port=27006
dbpath=.\server6
logpath=.\server6\mongod.log
logappend=true
replSet = rs1
- rs1.conf文件
var rsconf={
_id:"rs1",
"members":[
{_id:0,host:"127.0.0.1:27004"},
{_id:1,host:"127.0.0.1:27005"},
{_id:2,host:"127.0.0.1:27006",priority:0,arbiterOnly:true},
]};
rs.initiate(rsconf)
- priority: 0: 这个字段指定了成员在选举过程中的优先级。优先级为0意味着这个成员不会被选举为主节点(primary node)。
- arbiterOnly: true: 这个字段表示该成员是一个仲裁者(arbiter)。仲裁者不存储数据,只参与选举过程,以帮助在副本集中保持奇数个成员来避免脑裂(split-brain)问题。
- 启动脚本
mkdir .\server4
mkdir .\server5
mkdir .\server6
start "MongoDB Server4" mongod --config=.\server4.ini
start "MongoDB Server5" mongod --config=.\server5.ini
start "MongoDB Server6" mongod --config=.\server6.ini
start "Connect to Server4" mongo --port=27004 --shell rs1conf.js
start "Connect to Server5" mongo --port=27005
start "Connect to Server6" mongo --port=27006
只能有一个仲裁节点,文件大小固定而且最小,都是300MB
- rs0和rs1两个副本集之间没有任何关联。副本集是分布式集群中的一个基本单元。