设为首页 收藏本站
查看: 814|回复: 0

[经验分享] 十分钟搞定mongodb副本集

[复制链接]

尚未签到

发表于 2018-10-24 12:37:13 | 显示全部楼层 |阅读模式
  mongodb副本集配置
  最近项目中用到了mongodb,由于是用mongodb来记录一些程序的日志信息和日常的统计,为了增加应用的可靠性,一直在找mongodb集群的一些资料,下面是对最近做的一个小案例过程进行了一下总结记录。
  一.先介绍一下副本集是什么?
  副本集(复制)是将数据同步到多台服务器的过程,提供的数据的冗余备份,并且在多个服务器上存储数据的副本,提高了数据的可用性,也降低了数据的损坏风险,提高的安全性,并且可以实现故障的自动的切换恢复。
  二.副本集的组成结构是什么?
  一个副本集的最小结构有用三个成员。一个三个成员的副本集可以有三个成员保存数据,或者有两个保存,一个为监督者。即一个主节点(Primary),一个从节点(Secondary),一个监督者(Arbiter),监督者不存储数据,监督者的作用主要是当主节点不可用时从从节点中选中主节点。如下图:
DSC0000.jpg

  请点击此处输入图片描述
  三.下面我们就按步骤小试牛刀一下?
  第一步:
  我们在本机的1001、1002和1003三个端口上启动三个不同的Mongodb实例;                mongod --port 1001 --dbpath F:/mongos/mongodb1/data  --logpath  F:/mongos/mongodb1/log/mongodb.log  --pidfilepath F:/mongos/mongodb1/mongodb1.pid    --replSet  test --logappend --directoryperdb
  mongod --port 1002 --dbpath F:/mongos/mongodb2/data --logpath F:/mongos/mongodb2/log/mongodb.log  --pidfilepath F:/mongos/mongodb2/mongodb2.pid   --replSet test --logappend --directoryperdb
  mongod --port 1003 --dbpath F:/mongos/mongodb3/data --logpath F:/mongos/mongodb3/log/mongodb.log  --pidfilepath F:/mongos/mongodb3/mongodb3.pid   --replSet test --logappend   --directoryperdb
  到这里,members中可以包含多个值,这里列举的就是刚才启动的三个Mongodb实例,并且通过_id字段给副本集起了名字test。
  第三步:
  通过执行下面的命令初始化副本集。
  1
  rs.initiate(config_test);
  下面的命令可以查看副本集的状态。
  1
  rs.status();
  到这里搭建起一个由三个Mongodb实例构成的名称为test的副本集了。
  副本集现在搭建起来了,那么这个副本集能不能解决我们上面主从模式的两个问题呢?
  我们首先从第一个问题开始看,我们将1001端口的Mongodb服务器给关闭,然后我们使用rs.status()命令来查看下,如下所示:
DSC0001.jpg

  请点击此处输入图片描述
  从返回包信息中,可以看到关闭1001端口后,在副本集节点的状态中该节点是不可达的,重新选取产生的主节点是1002端口上启动的Mongodb实例,选举过程是这样的,当主节点挂掉之后,其他节点可以发起选举行为,只要在选举过程中某个节点得到副本集节点数一半以上的选票并且没有节点投反对票,那么该节点就可以成为主节点。(参数注释请看开始位置)在1001端口上的Mongodb实例挂掉之后,1002成为了新的主节点,可以实现故障自动切换。
  至于第二个问题,那就是主节点负责所有的读写操作造成主节点压力较大,那么在副本集中如何解决这个问题了呢?正常情况下,我们在Java中访问副本集是这样的,如下所示:
public class TestMongoDBReplSet {  
   public static void main(String[] args)  {
  
       try {
  
           List addresses = new ArrayList();
  
           ServerAddress address1 = new ServerAddress("127.0.0.1",1001);
  
           ServerAddress address2 = new ServerAddress("127.0.0.1",1002);
  
           ServerAddress address3 = new ServerAddress("127.0.0.1",1003);
  
           addresses.add(address1);
  
           addresses.add(address2);
  
           addresses.add(address3);
  
           MongoClient client = new MongoClient(addresses);
  
           DB db = client.getDB( "testdb");
  
           DBCollection coll = db.getCollection( "testdb");
  
           // 插入
  
           BasicDBObject object = new BasicDBObject();
  
           object.append("userid","001");
  
           coll.insert(object);
  
           DBCursor dbCursor = coll.find();
  
           while (dbCursor.hasNext()) {
  
               DBObject dbObject = dbCursor.next();
  
               System. out.println(dbObject.toString());
  
           }
  
       } catch (Exception e) {
  
           e.printStackTrace();
  
       }
  
   }
  
}
  但是上面不能做到在副本集中读写压力分散,在代码层面我们可以设置再访问副本集的时候只从副节点上读取数据。为了在副本集上实现读写分离,我们需要实现以下两步:
  (1)在副本节点上设置setSlaveOk;
  (2)代码层面,在读操作过程中设置从副本节点读取数据,如下所示:

  public>  public static void main(String[] args)  {
  try {
  List addresses = new ArrayList();
  ServerAddress address1 = new ServerAddress("127.0.0.1",1001);
  ServerAddress address2 = new ServerAddress("127.0.0.1",1002);
  ServerAddress address3 = new ServerAddress("127.0.0.1",1003);
  addresses.add(address1);
  addresses.add(address2);
  addresses.add(address3);
  MongoClient client = new MongoClient(addresses);
  DB db = client.getDB( "test");
  DBCollection coll = db.getCollection( "test");
  BasicDBObject object = new BasicDBObject();
  object.append("userid","001");
  ReadPreference preference = ReadPreference.secondary();
  DBObject dbObject = coll.findOne(object, null , preference);
  System. out .println(dbObject);
  } catch (Exception e) {
  e.printStackTrace();
  }
  }
  }
  上面代码中的读参数除了secondary以外,还有其他几个参数可以使用,他们的含义分别如下所示:
  primaryPreferred:大部分从主节点上读取数据,只有主节点不可用时从secondary节点读取数据。
  secondary:只从secondary节点上进行读取操作,存在的问题是secondary节点的数据会比primary节点数据“旧”。
  secondaryPreferred:优先从secondary节点进行读取操作,secondary节点不可用时从主节点读取数据;
  nearest:不管是主节点、secondary节点,从网络延迟最低的节点上读取数据。
  四.最后对使用到的参数进行了一下总结方便以后记忆和复习?
  dbpath:数据存放目录
  logpath:日志存放路径
  pidfilepath:进程文件,方便停止mongodb
  directoryperdb:为每一个数据库按照数据库名建立文件夹存放
  logappend:以追加的方式记录日志
  replSet:replica set的名字
  bind_ip:mongodb所绑定的ip地址
  port:mongodb进程所使用的端口号,默认为27017
  oplogSize:mongodb操作日志文件的最大大小。单位为Mb,默认为硬盘剩余空间的5%
  fork:以后台方式运行进程
  noprealloc:不预先分配存储
  priority:优先级,返回时0-100,数组越大,优先级越高,默认是1,0不进行选举
  如果你在Java开发工作中遇到困难,或者学习遇到瓶颈,欢迎加入我们Java总群:309603235,解决各种坑 爹的Java问题,群内有Java技术大牛,为您解决Java工作、学习中遇到的问题,欢迎菜鸟,老鸟入坑。



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-625937-1-1.html 上篇帖子: MongoDB安装部署及基本操作 下篇帖子: 如何在SAP云平台上使用MongoDB服务
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表