文章目录
一、概念简介
1、主从复制的作用
我们常见的主从复制的架构,有redis,mysql,zookeeper,mongodb等等,一说到这种主从复制的架构,
其主要的作用有两方面:
**a、高可用(最主要的功能)**
如果只有一个节点,假如它挂了,那么服务就不可用了;实现主从复制,当主节点挂了,从节点可以
被选举为主节点,继续提供服务。而且,mongodb的主从选举是自动进行的,系统自带的,并不需要借助第三方软件。
**b、读写分离,提高性能**
2、mongoDb复制集群机构
PRIMARY 节点: 可以查询和新增数据
SECONDARY 节点:只能查询 不能新增 基于priority 权重可以被选为主节点
RBITER 节点: 不能查询数据 和新增数据 ,不能变成主节点(图中未画出)
3、mongoDb复制集节点类型
a、主动节点:参与选举和工作,priority>0
b、被动节点:不参与选举,只工作,prority=0
c、仲裁节点:不参与选举和工作,只是用来执行选举工作的,提高系统的高可用性
二、mongDb复制集搭建演示
1. 主节点搭建
(服务器环境:这里以阿里云centos7服务器为环境,演示一主两从的伪集群)
a、目录结构:
/data : 数据目录
/conf : 配置文件目录
先在/data 目录下新建3个目录:
#主节点数据目录(primary)
mkdir repl-27017
#从节点数据目录(secondary1)
mkdir repl-27018
#从节点数据目录(secondary2)
mkdir repl-27019
在/conf目录下编写3个节点的配置
以主节点配置“repl-27017.conf”为例: vim repl-27017.conf
#数据目录
dbpath=/root/Hugo/tools/mongodb/mongodb-linux-x86_64-4.0.5/data/repl-27017
#启动端口
port=27017
#日志目录
logpath=/root/Hugo/tools/mongodb/mongodb-linux-x86_64-4.0.5/data/repl-27017/27017.log
#后台启动
fork=true
#复制集的名称
replSet=hugoCluster
b、启动主节点
#指定配置文件启动主节点
./bin/mongod -f conf/repl-27017.conf
2. 从节点搭建
参照注解点配置编写从节点的配置文件:
#直接复制一份repl-27017.conf为repl-27018.conf
cp repl-27018.conf repl-27018.conf
#编辑repl-27018.conf
vim repl-27018.conf
#批量替换27017 --》 27018
:%s/27017/27018/g
repl-27018.conf的结果如下:
#数据目录
dbpath=/root/Hugo/tools/mongodb/mongodb-linux-x86_64-4.0.5/data/repl-27018
#启动端口
port=27018
#日志目录
logpath=/root/Hugo/tools/mongodb/mongodb-linux-x86_64-4.0.5/data/repl-27018/27018.log
#后台启动
fork=true
#复制集的名称
replSet=hugoCluster
同理,repl-27019.conf的配置如下:
#数据目录
dbpath=/root/Hugo/tools/mongodb/mongodb-linux-x86_64-4.0.5/data/repl-27019
#启动端口
port=27019
#日志目录
logpath=/root/Hugo/tools/mongodb/mongodb-linux-x86_64-4.0.5/data/repl-27019/27019.log
#后台启动
fork=true
#复制集的名称
replSet=hugoCluster
启动从节点
./bin/mongod -f conf/repl-27018.conf
./bin/mongod -f conf/repl-27019.conf
3. 启动复制集
1. 进入任意一个节点,查看当前集群的状态:
./bin/mongo --port=27017
rs.status();
提示:集群尚未配置,其实我们刚刚启动的三个节点只是游离的节点,并没有加入到集群中
2. 初始化集群配置
a、编写配置脚本
var cfg = {
"_id":"hugoCluster",
"protocolVersion":1,
"members":[
{
"_id":1,"host":"127.0.0.1:27017"
},{
"_id":2,"host":"127.0.0.1:27018"
},{
"_id":3,"host":"127.0.0.1:27019"
}
]
}
使用rs.initiate(cfg)初始化集群配置:
查看当前集群状态:rs.status 或者 rs.config() 或者 rs.isMaster()
往集群写数据,验证是否可用
a、先在主节点中写数据:
#新建一个test的数据库
use test
#新建emp表,往里面写数据
db.emp.insert({
"name":"张三","sex":"男"})
#查看数据状态
db.emp.find()
b、进入27018的客户端,查看从节点的数据是否从主节点同步过来了
./bin/mongo --port 27018
发现提示:“not master and slaveOk=false”,从节点尚未准备好,执行rs.slaveOk()即可
4. 模拟自动选举
a、kill掉主节点
b、进入27018节点查看是否已经完成主从选举
mongoDB的主从选举是自动进行的,根据每个节点配置时给定的优先级priority来选举,优先级越大(数字越大)就当选为主节点,最开始的时候我们没有明确在配置cfg中指定priority的值,大家默认priority都是1,随机选一个
hugoCluster:SECONDARY> rs.config()
{
"_id" : "hugoCluster",
"version" : 1,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [
{
"_id" : 1,
"host" : "127.0.0.1:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "127.0.0.1:27018",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 3,
"host" : "127.0.0.1:27019",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("5dccf89531265d40292a4892")
}
}
现在,我们从新指定集群的配置文件cfg,为每个节点指定priority:
(注意:重新加载配置cfg,调用rs.reconfig(cfg)都要在当前的primary节点上执行,在secondary上执行会报错)
先把之前停掉的27017节点启动起来:
#注意:由于重新加载配置只能在当前的primary节点执行rs.reconfig(cfg),新的配置里面的分配给当前主节点的priority不能为0(前面说过,priority=0的节点是被动几点,priority>0的节点是主动节点)
#我们试错一下,当前的主节点是27019,如果priority分配为0,如下
var cfg = {
"_id":"hugoCluster",
"protocolVersion":1,
"members":[
{
"_id":1,"host":"127.0.0.1:27017","priority":10
},{
"_id":2,"host":"127.0.0.1:27018","priority":5
},{
"_id":3,"host":"127.0.0.1:27019","priority":0
}
]
}
报错的场景如下:
hugoCluster:PRIMARY> var cfg = {
... "_id":"hugoCluster",
... "protocolVersion":1,
... "members":[
... {
... "_id":1,"host":"127.0.0.1:27017","priority":10
... },{
... "_id":2,"host":"127.0.0.1:27018","priority":5
... },{
... "_id":3,"host":"127.0.0.1:27019","priority":0
... }
... ]
... }
hugoCluster:PRIMARY> rs.reconfig(cfg)
{
"operationTime" : Timestamp(1573717050, 1),
"ok" : 0,
"errmsg" : "This node, 127.0.0.1:27019, with _id 3 is not electable under the new configuration version 2 for replica set hugoCluster",
"code" : 103,
"codeName" : "NewReplicaSetConfigurationIncompatible",
"$clusterTime" : {
"clusterTime" : Timestamp(1573717050, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
正确的配置如下:
hugoCluster:PRIMARY> var cfg = {
... "_id":"hugoCluster",
... "protocolVersion":1,
... "members"