mongodb副本集搭建流程

一、准备

准备三台服务器,或者在一台服务器上启动三个不同端口的mongodb服务

防火墙,开放对应的端口,否则会报错

selinux设置关闭

二、mongodb搭建

#!/bin/bash
#This is a script to install mongidb, the version of mongodb is 3.4.0

#Download the installation package

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.4.0.tgz


tar zxvf mongodb-linux-x86_64-3.4.0.tgz -C /opt

cd /opt

mv mongodb-linux-x86_64-3.4.0   mongodb

Cat>>/etc/profile<<EOF
export MONGODB_HOME=/usr/local/mongodb
export PATH=$PATH:$MONGODB_HOME/bin
EOF

source /etc/profile

mkdir -p /opt/mongodb/data
mkdir -p /opt/mongodb/data/db
mkdir -p /opt/mongodb/data/logs

cd /opt/mongodb/data/logs

touch mongodb.log
cat>>/opt/mongodb/data1/mongodb.conf<<EOF
#端口号
port=27017
#数据目录
dbpath=/opt/mongodb/data/db
#日志目录
logpath=/opt/mongodb/data/logs/mongodb.log
#以后台方式运行
fork=true
#日志输出方式
logappend=true
#开启认证
#auth=true
#副本集名称
replSet=test
#本机IP
bind_ip=127.0.0.1

#操作文件最大值,单位 mb,默认硬盘百分之 5
oplogSize=10000

#不预先分配内存
noprealloc=true

EOF

cd /opt/mongodb/bin
./mongod --config /opt/mongodb/data/mongodb.conf
ln -s /opt/mongodb/bin/* /usr/bin/

按照这个安装也可以,路径改成自己想要安装的路径。

安装完成

查看进程
ps -aux |grep mongod

我这个上面启动了两个mongo

是指定路径,端口,配置文件启动

启动命令是

sudo mongod -f /opt/mongodb/data/mongodb.conf -dbpath /opt/mongodb/data/db -replSet LZAPP --bind_ip=10.10.100.186 --port=27017 &

设置开机启动

vim  /etc/rc.d/rc.local

添加

sudo mongod -f /opt/mongodb/data/mongodb.conf -dbpath /opt/mongodb/data/db -replSet test --bind_ip=10.10.100.186 --port=27017

修改 rc.local文件的的权限

chmod +x rc.local

重启机器,测试看看

三、修改配置文件

port=27017            #启动端口
#数据目录
dbpath=/opt/mongodb/data/db     #数据目录
logpath=/opt/mongodb/data/logs/mongodb.log    #日志文件
#设置后台运行
fork=true          
#日志输出方式
logappend=true
#开启认证
#auth=true
bind_ip=10.10.100.186             #本机IP,这个一定要写
replSet=test                        #副本集名称

四、初始化副本集

在三个节点中的任意一个节点机上操作(比如在10.10.100.186节点机)

登录mongodb

mongo 10.10.100.177:27017

登录admin数据库

>use admin

switched to db admin

#定义副本集配置变量,这里的 _id:”repset” 和上面命令参数“ –replSet repset” 要保持一样。

> config={_id:"test",members:[{_id:0,host:"10.10.100.186:27018"},{_id:1,host:"10.10.100.187:27018"},{_id:2,host:"10.10.100.188:27018"}]}
{
	"_id" : "test",
	"members" : [
		{
			"_id" : 0,
			"host" : "10.10.100.186:27018"
		},
		{
			"_id" : 1,
			"host" : "10.10.100.187:27018"
		},
		{
			"_id" : 2,
			"host" : "10.10.100.188:27018"
		}
	]
}

初始化副本集配置

> rs.initiate(config)
{ "ok" : 1 }
返回1,是正常,返回0,就是失败

查看副本集配置

test:OTHER> rs.conf()
{
	"_id" : "test",
	"version" : 1,
	"protocolVersion" : NumberLong(1),
	"members" : [
		{
			"_id" : 0,
			"host" : "10.10.100.186:27018",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		},
		{
			"_id" : 1,
			"host" : "10.10.100.187:27018",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		},
		{
			"_id" : 2,
			"host" : "10.10.100.188:27018",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		}
	],
	"settings" : {
		"chainingAllowed" : true,
		"heartbeatIntervalMillis" : 2000,
		"heartbeatTimeoutSecs" : 10,
		"electionTimeoutMillis" : 10000,
		"catchUpTimeoutMillis" : 2000,
		"getLastErrorModes" : {
			
		},
		"getLastErrorDefaults" : {
			"w" : 1,
			"wtimeout" : 0
		},
		"replicaSetId" : ObjectId("5d6db54279053540497f68c8")
	}
}

#查看集群节点的状态

test:PRIMARY> rs.status();
{
	"set" : "test",
	"date" : ISODate("2019-09-03T00:36:45.238Z"),
	"myState" : 1,
	"term" : NumberLong(1),
	"heartbeatIntervalMillis" : NumberLong(2000),
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp(1567470995, 1),
			"t" : NumberLong(1)
		},
		"appliedOpTime" : {
			"ts" : Timestamp(1567470995, 1),
			"t" : NumberLong(1)
		},
		"durableOpTime" : {
			"ts" : Timestamp(1567470995, 1),
			"t" : NumberLong(1)
		}
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "10.10.100.186:27018",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 213,
			"optime" : {
				"ts" : Timestamp(1567470995, 1),
				"t" : NumberLong(1)
			},
			"optimeDate" : ISODate("2019-09-03T00:36:35Z"),
			"infoMessage" : "could not find member to sync from",
			"electionTime" : Timestamp(1567470924, 1),
			"electionDate" : ISODate("2019-09-03T00:35:24Z"),
			"configVersion" : 1,
			"self" : true
		},
		{
			"_id" : 1,
			"name" : "10.10.100.187:27018",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 90,
			"optime" : {
				"ts" : Timestamp(1567470995, 1),
				"t" : NumberLong(1)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1567470995, 1),
				"t" : NumberLong(1)
			},
			"optimeDate" : ISODate("2019-09-03T00:36:35Z"),
			"optimeDurableDate" : ISODate("2019-09-03T00:36:35Z"),
			"lastHeartbeat" : ISODate("2019-09-03T00:36:45.077Z"),
			"lastHeartbeatRecv" : ISODate("2019-09-03T00:36:43.544Z"),
			"pingMs" : NumberLong(0),
			"syncingTo" : "10.10.100.186:27018",
			"configVersion" : 1
		},
		{
			"_id" : 2,
			"name" : "10.10.100.188:27018",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 90,
			"optime" : {
				"ts" : Timestamp(1567470995, 1),
				"t" : NumberLong(1)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1567470995, 1),
				"t" : NumberLong(1)
			},
			"optimeDate" : ISODate("2019-09-03T00:36:35Z"),
			"optimeDurableDate" : ISODate("2019-09-03T00:36:35Z"),
			"lastHeartbeat" : ISODate("2019-09-03T00:36:45.077Z"),
			"lastHeartbeatRecv" : ISODate("2019-09-03T00:36:43.543Z"),
			"pingMs" : NumberLong(0),
			"syncingTo" : "10.10.100.186:27018",
			"configVersion" : 1
		}
	],
	"ok" : 1
}

五、创建帐户密码

副本集搭建成功后,需要给整个副本集创建帐户、密码

1、在主节点上,用客户端连接,创建用户权限(主节点,可以用 rs.status() 查看)
#创建分配用户权限的帐户:root

[root@localhost ~]#mongo ip:端口              #登录
replSet:PRIMARY> use admin 

#创建分配用户权限的帐户              
replSet:PRIMARY> db.createUser({user:"账号", pwd:"密码", roles:[{role: "root", db:"admin" }]})

Successfully added user: {
    "user" : "root",
    "roles" : [
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        }
    ]
}

#创建普通数据库、用户
replSet:PRIMARY>use  test  #创建test数据库
switched to db test
replSet:PRIMARY>db.createUser({user:"test", pwd:"test", roles:[{role: "readWrite", db:"lzkj"}]})
Successfully added user: {
    "user" : "test",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "test"
        }
    ]
}

#在test库上创建一个test用户,密码为test,具有读写权限。
#注意字符,标点符号,是英文下的的字符,否则会报错。

链接方式

[root@localhost ~]#mongo ip:端口/库名 -u 用户  -p  密码

创建副本集认证key文件

副本集设置身份验证与单机不同,需要增加一个 keyFile 以便副本集成员相互认证。

这个文件需要满足下面几点要求:

  • 文本长度需要在 6 和 1024 之间
  • 认证时候不考虑文件中空白字符
  • 连接到副本集的成员和 mongos 进程的 keyfile 文件内容必须一样
  • 必须是base64编码,但是不能有等号
  • 文件权限必须是x00,也就是说,不能分配任何权限给group成员和other成员

我们可以在 Linux 上直接使用 openssl 创建一个这样的文件,然后上传至其他副本集成员服务器

创建key文件: 注意,三个节点必须要用同一份keyfile,在一台机器生成,拷贝到另外两台,并且修改成 600 的文件属性

[root@localhost ~]# openssl rand -base64 90 -out ./keyfile  #生成key文件
[root@localhost ~]# cp keyfile  /opt/mongodb/data/      #将key复制到指定路径
[root@localhost ~]#chomd 600  /opt/mongodb/data/keyfile   #修改属性,不修改会报错
 
备注需要将keyfile文件同步到每一个节点

修改每个节点的配置文件mongo.conf下面的内容

...
...
#是否以安装认证方式运行
auth=true
#KeyFile鉴权文件:改为实际路径
keyFile=/opt/mongodb/data/keyfile

重新启动副本集

[root@localhost ~] mongod -f 配置文件的路径

附录

1、创建数据库的用户角色:

role角色

  • 数据库用户角色:read、readWrite;
  • 数据库管理角色:dbAdmin、dbOwner、userAdmin;
  • 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
  • 备份恢复角色:backup、restore;
  • 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
  • 超级用户角色:root
  • 内部角色:__system

角色说明

  • read:允许用户读取指定数据库
  • readWrite:允许用户读写指定数据库
  • dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
  • userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
  • clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
  • readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
  • readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
  • userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
  • dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
  • root:只在admin数据库中可用。超级账号,超级权限
  • dbOwner: readWrite + dbAdmin + dbAdmin

Java客户端连接配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mongo="http://www.springframework.org/schema/data/mongo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/data/mongo     
        http://www.springframework.org/schema/data/mongo/spring-mongo.xsd 
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- credentials="用户名:密码@用户归属数据库" -->
    <mongo:mongo-client replica-set="172.17.0.3:27018,172.17.0.4:27018, 172.17.0.5:27018" credentials="mytest:mytest@mytest"  id="mongo">
        <mongo:client-options 
            connections-per-host="20"
            threads-allowed-to-block-for-connection-multiplier="10" 
            connect-timeout="120000"
            max-wait-time="120000"
            socket-keep-alive="true"
            socket-timeout="150000"
             /> 
    </mongo:mongo-client>

    <mongo:db-factory dbname="数据库名" mongo-ref="mongo" />

    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
    </bean>
</beans>

Spring Boot配置

spring.data.mongodb.uri=mongodb://user:pwd@ip1:port1,ip2:port2/database

副本集常用管理命令

命令                                                       解释
rs.initiate()                                   使用默认配置初始化副本集
rs.initiate(cfg)                              使用配置文件cfg初始化副本集
rs.reconfig(cfg)                            修改副本集配置信息
rs.status()                                   查看副本集状态
rs.conf()                                     查看副本集配置
rs.add(hostportstr)
rs.add(membercfgobj)                      添加新的节点 
rs.addArb(hostportstr)                  添加投票节点
rs.remove(hostportstr)                删除节点
rs.slaveOk()                              允许从库只读,默认从库不允许读写
rs.isMaster()                             查看哪个节点为主节点
rs.printReplicationInfo()                  查看oplog大小以及oplog可用时间,可以判断系统繁忙程度
rs.printSlaveReplicationInfo()                     查看复制集成员以及延迟
rs.stepDown([stepdownSecs, catchUpSecs])                  手动主从切换
rs.freeze(secs)                                      冻结当前节点在指定的时间内(秒)不能选举为主
rs.syncFrom(hostportstr)                   管理员临时覆盖当前成员的默认同步目标。以[hostname]:[port]的形式指定要复制的成员的名称。

db.system.users.find()                           查看已存在的用户

db.system.users.remove({user:”simpleUser”})         删除用户

 

六、测试Mongodb副本集数据复制功能 <mongodb默认是从主节点读写数据的,副本节点上不允许读,需要设置副本节点可以读>

1)在主节点建立数据库,插入测试数据

test:PRIMARY> use test;
switched to db test
test:PRIMARY> db.testdb.insert({"test1":"testval1"})
WriteResult({ "nInserted" : 1 })

2)在从节点查看数据是否复制过来

登录数据库

mongo 10.10.100.187:27017
test:SECONDARY> use test;
switched to db test
test:SECONDARY> show tables;
2019-09-03T08:40:09.371+0800 E QUERY    [main] Error: listCollections failed: {
	"ok" : 0,
	"errmsg" : "not master and slaveOk=false",
	"code" : 13435,
	"codeName" : "NotMasterNoSlaveOk"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype._getCollectionInfosCommand@src/mongo/shell/db.js:805:1
DB.prototype.getCollectionInfos@src/mongo/shell/db.js:817:19
DB.prototype.getCollectionNames@src/mongo/shell/db.js:828:16
shellHelper.show@src/mongo/shell/utils.js:748:9
shellHelper@src/mongo/shell/utils.js:645:15
@(shellhelp2):1:1

上面出现了报错!

这是因为mongodb默认是从主节点读写数据的,副本节点上不允许读,需要设置副本节点可以读

test:SECONDARY> db.getMongo().setSlaveOk();  设置一下
test:SECONDARY> show tables;    就可以读出来了,两台都需要设置一下
testdb

现在,把主节点宕掉,登录另外的节点,查看副本集的状态

test:PRIMARY> rs.status();
{
	"set" : "test",
	"date" : ISODate("2019-09-03T00:46:21.057Z"),
	"myState" : 1,
	"term" : NumberLong(2),
	"heartbeatIntervalMillis" : NumberLong(2000),
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp(1567471577, 1),
			"t" : NumberLong(2)
		},
		"appliedOpTime" : {
			"ts" : Timestamp(1567471577, 1),
			"t" : NumberLong(2)
		},
		"durableOpTime" : {
			"ts" : Timestamp(1567471577, 1),
			"t" : NumberLong(2)
		}
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "10.10.100.186:27018",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 34,
			"optime" : {
				"ts" : Timestamp(1567471577, 1),
				"t" : NumberLong(2)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1567471577, 1),
				"t" : NumberLong(2)
			},
			"optimeDate" : ISODate("2019-09-03T00:46:17Z"),
			"optimeDurableDate" : ISODate("2019-09-03T00:46:17Z"),
			"lastHeartbeat" : ISODate("2019-09-03T00:46:20.494Z"),
			"lastHeartbeatRecv" : ISODate("2019-09-03T00:46:19.899Z"),
			"pingMs" : NumberLong(0),
			"syncingTo" : "10.10.100.188:27018",
			"configVersion" : 1
		},
		{
			"_id" : 1,
			"name" : "10.10.100.187:27018",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 664,
			"optime" : {
				"ts" : Timestamp(1567471577, 1),
				"t" : NumberLong(2)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1567471577, 1),
				"t" : NumberLong(2)
			},
			"optimeDate" : ISODate("2019-09-03T00:46:17Z"),
			"optimeDurableDate" : ISODate("2019-09-03T00:46:17Z"),
			"lastHeartbeat" : ISODate("2019-09-03T00:46:20.462Z"),
			"lastHeartbeatRecv" : ISODate("2019-09-03T00:46:19.161Z"),
			"pingMs" : NumberLong(0),
			"syncingTo" : "10.10.100.188:27018",
			"configVersion" : 1
		},
		{
			"_id" : 2,
			"name" : "10.10.100.188:27018",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 724,
			"optime" : {
				"ts" : Timestamp(1567471577, 1),
				"t" : NumberLong(2)
			},
			"optimeDate" : ISODate("2019-09-03T00:46:17Z"),
			"infoMessage" : "could not find member to sync from",
			"electionTime" : Timestamp(1567471486, 1),
			"electionDate" : ISODate("2019-09-03T00:44:46Z"),
			"configVersion" : 1,
			"self" : true
		}
	],
	"ok" : 1
}

发现当原来的主节点10.10.100.186宕掉后,经过选举,原来的从节点10.10.100.188被推举为新的主节点。

然后在新的节点插入数据

test:PRIMARY> for(var i=0;i<10000;i++){db.test.insert({"name":"test"+i,"age":123})}

WriteResult({ "nInserted" : 1 })
test:PRIMARY> 

登录从节点查看数据是否同步

test:SECONDARY> db.test.find()
{ "_id" : ObjectId("5d6db9ce460b07bcce150716"), "name" : "test0", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce150718"), "name" : "test2", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce150717"), "name" : "test1", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce15071b"), "name" : "test5", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce15071e"), "name" : "test8", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce150719"), "name" : "test3", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce15071c"), "name" : "test6", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce15071d"), "name" : "test7", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce15071a"), "name" : "test4", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce150720"), "name" : "test10", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce15071f"), "name" : "test9", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce150721"), "name" : "test11", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce150722"), "name" : "test12", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce15072b"), "name" : "test21", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce150725"), "name" : "test15", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce150728"), "name" : "test18", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce15072a"), "name" : "test20", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce150726"), "name" : "test16", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce150729"), "name" : "test19", "age" : 123 }
{ "_id" : ObjectId("5d6db9ce460b07bcce150727"), "name" : "test17", "age" : 123 }

发现数据已经同步

六、Mongodb读写分离

目前来看。Mongodb副本集可以完美支持故障转移。至于主节点的读写压力过大如何解决?常见的解决方案是读写分离。

一般情况下,常规写操作来说并没有读操作多,所以在Mongodb副本集中,一台主节点负责写操作,两台副本节点负责读操作。
1)设置读写分离需要先在副本节点SECONDARY 设置 setSlaveOk。
2)在程序中设置副本节点负责读操作,如下代码:<br>
public class TestMongoDBReplSetReadSplit {
public static void main(String[] args) {
try {
List<ServerAddress> addresses = new ArrayList<ServerAddress>();
ServerAddress address1 = new ServerAddress("10.10.100.186" , 27017);
ServerAddress address2 = new ServerAddress("10.10.100.187" , 27017);
ServerAddress address3 = new ServerAddress("10.10.100.188" , 27017);
addresses.add(address1);
addresses.add(address2);
addresses.add(address3);
MongoClient client = new MongoClient(addresses);
DB db = client.getDB( "test" );
DBCollection coll = db.getCollection( "testdb" );
BasicDBObject object = new BasicDBObject();
object.append( "test2" , "testval2" );
 
//读操作从副本节点读取
ReadPreference preference = ReadPreference. secondary();
DBObject dbObject = coll.findOne(object, null , preference);
System. out .println(dbObject);
} catch (Exception e) {
e.printStackTrace();
}
}
}

读参数除了secondary一共还有五个参数:primary、primaryPreferred、secondary、secondaryPreferred、nearest。
primary:默认参数,只从主节点上进行读取操作;
primaryPreferred:大部分从主节点上读取数据,只有主节点不可用时从secondary节点读取数据。
secondary:只从secondary节点上进行读取操作,存在的问题是secondary节点的数据会比primary节点数据“旧”。
secondaryPreferred:优先从secondary节点进行读取操作,secondary节点不可用时从主节点读取数据;
nearest:不管是主节点、secondary节点,从网络延迟最低的节点上读取数据。

读写分离做好后,就可以进行数据分流,减轻压力,解决了"主节点的读写压力过大如何解决?"这个问题。不过当副本节点增多时,主节点的复制压力会加大有什么办法解决吗?基于这个问题,Mongodb已有了相应的解决方案 - 引用仲裁节点:
在Mongodb副本集中,仲裁节点不存储数据,只是负责故障转移的群体投票,这样就少了数据复制的压力。看起来想的很周到啊,其实不只是主节点、副本节点、仲裁节点,还有Secondary-Only、Hidden、Delayed、Non-Voting,其中:
Secondary-Only:不能成为primary节点,只能作为secondary副本节点,防止一些性能不高的节点成为主节点。
Hidden:这类节点是不能够被客户端制定IP引用,也不能被设置为主节点,但是可以投票,一般用于备份数据。
Delayed:可以指定一个时间延迟从primary节点同步数据。主要用于备份数据,如果实时同步,误删除数据马上同步到从节点,恢复又恢复不了。
Non-Voting:没有选举权的secondary节点,纯粹的备份数据节点。


 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rio520

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值