欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MongoDB的配置与复制集

程序员文章站 2024-01-22 22:43:46
...


一、MongoDB复制集简介

那什么是复制集呢?而复制集具有多个副本保证了容错性,就算一个副本挂掉了还有很多副本存在,并且解决了上面第一个问题“主节点挂掉了,整个集群内会自动切换”。难怪mongoDB官方推荐使用这种模式。我们来看看mongoDB副本集的架构图:

MongoDB的配置与复制集

由图可以看到客户端连接到整个复制集,不关心具体哪一台机器是否挂掉。主服务器负责整个复制集的读写,复制集定期同步数据备份,一但主节点挂掉,副本节点就会选举一个新的主服务器,这一切对于应用服务器不需要关心。我们看一下主服务器挂掉后的架构:

MongoDB的配置与复制集

复制集中的副本节点在主节点挂掉后通过心跳机制检测到后,就会在集群内发起主节点的选举机制,自动选举一位新的主服务器。

主节点的读写压力过大如何解决?常见的解决方案是读写分离,mongodb复制集的读写分离如何做呢?

MongoDB的配置与复制集

常规写操作来说并没有读操作多,所以一台主节点负责写,两台副本节点负责读。

1、设置读写分离需要先在副本节点SECONDARY 设置 setSlaveOk。 
2、在程序中设置副本节点负责读操作,如下代码:

public class TestMongoDBReplSetReadSplit {

        public static void main(String[] args) {

               try {
                     List<ServerAddress> addresses = new ArrayList<ServerAddress>();
                     ServerAddress address1 = new ServerAddress("192.168.1.136" , 27017);
                     ServerAddress address2 = new ServerAddress("192.168.1.137" , 27017);
                     ServerAddress address3 = new ServerAddress("192.168.1.138" , 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。

MongoDB的配置与复制集

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

读写分离做好我们可以数据分流,减轻压力解决了“主节点的读写压力过大如何解决?”这个问题。不过当我们的副本节点增多时,主节点的复制压力会加大有什么办法解决吗?mongodb早就有了相应的解决方案。

MongoDB的配置与复制集

其中的仲裁节点不存储数据,只是负责故障转移的群体投票,这样就少了数据复制的压力。是不是想得很周到啊,一看mongodb的开发兄弟熟知大数据架构体系,其实不只是主节点、副本节点、仲裁节点,还有Hidden、Delayed等节点。

Hidden:这类节点是不能够被客户端制定IP引用,也不能被设置为主节点,但是可以投票,一般用于备份数据。 
Delayed:可以指定一个时间延迟从primary节点同步数据。主要用于备份数据,如果实时同步,误删除数据马上同步到从节点,恢复又恢复不了。 

到此整个mongodb副本集搞定了两个问题:

  • 主节点挂了能否自动切换连接?
  • 主节点的读写压力过大如何解决?

还有这两个问题后续解决:

  • 从节点每个上面的数据都是对数据库全量拷贝,从节点压力会不会过大?
  • 数据压力大到机器支撑不了的时候能否做到自动扩展?

做了副本集发现又一些问题:

  • 副本集故障转移,主节点是如何选举的?
  • 官方说副本集数量最好是奇数,为什么?
  • mongodb副本集是如何同步的?如果同步不及时会出现什么情况?会不会出现不一致性?
  • mongodb的故障转移会不会无故自动发生?什么条件会触发?频繁触发可能会带来系统负载加重.

 

参考文献

1. 搭建高可用的MongoDB集群(上):MongoDB的配置与副本集