MongoDB4.0副本集搭建及java连接MongoDB副本集

        MongoDB提供了两种复制部署方案:主从复制和副本集。两种方式共同点是只在一个主节点上进行写操作,然后写入的数据会异步的同步到所有的从节点上。但主从复制有明显的缺陷:当主节点出现故障停电或者死机等情况,整个MongoDB服务集群就不能正常工作了,需要人工的处理这种情况。而副本集是具有自动故障恢复功能的主从复制。所以一般都用副本集。

1、思路:

       当副本集的总可投票数为偶数时,可能出现无法选举出主节的情况。2个节点组成副本集是不合理的,因为这样的副本集不具备故障切换能能力:
        ·当 SECONDARY节点挂掉,剩下一个 PRIMARY,此时副本集运行不会出现问题,但不具备副本集的功能了,相当于单实例 Mongodb服务
        ·当 PRIMARY节点挂掉,此时副本集只剩下一个 SECONDARY,它只有1票,不超过总节点数的半数,不会成功选举自己为 PRIMARY节点。会错误提示。
因此我们有两种方案,

     一是设置 MONGODB集群的节点数量为奇数。

     二是当Mongodb集的节点数量为偶数时,适当增加仲裁节点,增加集群的稳定性。

所以尝试部署副本集的可行方案是:3个数据节点或2个数据节点+1个仲裁节点

2、创建目录

先在3台机器上都安装MongoDB

第一台机器:192.168.32.135

mkdir -p /data/replset/data1    #1号机器存放数据的目录
mkdir -p /data/replset/key    #存放秘钥的目录
mkdir -p /data/replset/log    #存放日志的目录

第二台机器:192.168.32.137

mkdir -p /data/replset/data2    #2号机器存放数据的目录
mkdir -p /data/replset/key    #存放秘钥的目录
mkdir -p /data/replset/log    #存放日志的目录

第三台机器:192.168.32.138

mkdir -p /data/replset/data3    #3号机器存放数据的目录
mkdir -p /data/replset/key    #存放秘钥的目录
mkdir -p /data/replset/log    #存放日志的目录

3、创建Key

副本集认证的总体思路是用户名,密码和keyFile文件。KeyFile需要各个副本集服务启动时加载而且KeyFile文件的内容必须一致

KeyFile文件必须满足条件:

  1. 至少6个字符,小于1024字节
  2. 认证的时候不考虑文件中的空白字符
  3. 必须是base64编码,但是不能有等号
  4. 连接副本集的成员的KeyFile必须都一样
  5. 文件权限必须x00 也就是说不能分配任何权限给group成员和other成员,新版本推荐400

注意:秘钥是集群中服务器之间进行沟通使用的

第一台机器:

echo replsetkey> /data/replset/key/r1
chmod 400 /data/replset/key/r1

第二台机器:

echo replsetkey> /data/replset/key/r2
chmod 400 /data/replset/key/r2

第三台机器:

echo replsetkey> /data/replset/key/r3
chmod 400 /data/replset/key/r3

4、修改配置文件

开启了KeyFile,隐含就开启了auth 所以不用在配置文件中配置authorization: enable了

vim /etc/mongod.conf

第一台机器:

MongoDB4.0副本集搭建及java连接MongoDB副本集_第1张图片

第二台机器:

MongoDB4.0副本集搭建及java连接MongoDB副本集_第2张图片

第三台机器:

MongoDB4.0副本集搭建及java连接MongoDB副本集_第3张图片

5、分别启动三台机器上的MongoDB服务

./mongod --config /etc/mongod.conf

出现上面代表启动成功

6、初始化副本集

       启动三台MongoDB服务后,开始把他们初始化为副本集。在想要设置成primary(主节点)的机器上运行客户端mongo。例如第1台机器上:

6.1、启动客户端

      ./mongo

6.2、执行 rs.initiate()

说明初始化成功!

rs.conf()查看副本集配置,因为我的myadmin只付给了userAdminAnyDatabase权限。如果提示没有权限,则执行以下代码:

db.grantRolesToUser( "myadmin" , [ { role: "dbOwner", db: "admin" },{ "role": "clusterAdmin", "db": "admin" },
{ "role": "userAdminAnyDatabase", "db": "admin" },
{ "role": "dbAdminAnyDatabase", "db": "admin" },
{ role: "root", db: "admin" } ])

信息如下:

MongoDB4.0副本集搭建及java连接MongoDB副本集_第4张图片

6.3、添加secondary节点

例如将第2台机器设为secondary节点

rs.add("192.168.32.137:27017");

 

如果还要添加更多的secondary节点,执行rs.add(“主机名/IP:端口”)即可

6.4、添加仲裁节点ARBITER

将第三台机器设为仲裁节点

rs.addArb("192.168.32.138:27017")

如果还要添加更多的arbiter节点,执行rs.addArb(“主机名/IP:端口”)即可

查看集群情况可以使用命令:rs.status()

7、数据同步测试

1)首先向PRIMARY(主节点)写入一条数据

2)启动第二台机器的客户端,进入SECONDARY(副节点)

默认情况下SECONDARY节点不能读写,要设置slaveOK为true才行。集群中只能有一个Primary节点,只能在Primary写数据,不能在SECONDARY写数据

例如:

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

然后查看say集合

8、故障切换测试

副本集还有个很重要的功能就是故障切换,把主节点关闭,看看副本点是否能接替主节点进行工作。

在第1台机器执行db.shutdownServer()

然后发现第2台机器 SECONDARY节点变成了PRIMARY节点:

rs.status()查看集群状态,发现第1台机器的状态是:

9、java程序连接MongoDB副本集


public class ReplSetTest {

	public static void main(String[] args) {
		//副本集
		final List servers=new ArrayList();
		servers.add(new ServerAddress("192.168.32.135", 27017));
		servers.add(new ServerAddress("192.168.32.137", 27017));
		servers.add(new ServerAddress("192.168.32.138", 27017));
		
		//认证信息
		String user="myTest"; // the user name
	    String db="test"; // the name of the database in which the user is defined
	    char[] password="123".toCharArray(); // the password as a character array
		MongoCredential credential = MongoCredential.createCredential(user,db, password);
		MongoClientSettings settings = MongoClientSettings.builder()
				.credential(credential)
				.applyToClusterSettings(new Block() {
					public void apply(
							com.mongodb.connection.ClusterSettings.Builder t) {
						t.hosts(servers);// 副本集
					}
				}).build();

	    MongoClient mongoClient = MongoClients.create(settings);
		
	    MongoDatabase database = mongoClient.getDatabase("test");
	    MongoCollection collection = database.getCollection("book");
	    //插入数据
	    collection.insertOne(new Document("name","高数"));
	    collection.insertOne(new Document("name","MongoDB从入门到精通"));
		
	    
	    MongoCursor iterator = collection.find().iterator();
	    while(iterator.hasNext()){
	    	System.out.println(iterator.next().toJson());
	    }
	}
}

10、注意事项

1)不能使用service mongod start启动服务,否则报错

2)使用keyFile模式启动数据库服务,默认会启用--auth认证模式。一般需要先在单例模式下创建好用户,再使用--keyFile模式启动,认证后访问数据库。(否则没权限)

3)初始化还可以用这种方式:

rs.initiate(
  {
    _id : ,
    members: [
      { _id : 0, host : "192.168.32.135:27017,priority:4" },
      { _id : 1, host : "192.168.32.137:27017,priority:2" },
      { _id : 2, host : "192.168.32.138:27017,arbiterOnly:true" }
    ]
  }
)

4)新版本MongoDB客户端构造函数new MongoClient()已经不推荐使用了,改为MongoClients.create()

你可能感兴趣的:(MongoDB)