zoukankan      html  css  js  c++  java
  • 文档型数据库mongodb介绍2-副本集

    一。 副本集介绍

         之前的文章介绍了 mongodb主从 mongodb提供了另外一种 基于副本集的集群 该方式 是一主一从的升级版  一主多从,

    仍然是主节点负责写入 从节点定时同步主节点数据 使用该种方式 从节点可以负责读取的操作 主节点负责写入 可以轻松实现读写分离

      同时该集群方式支持自动故障转移  集群中所有节点间保持心跳 发现主节点宕机后 选举一个新的主节点


    二。 副本集搭建

    查看支持的三种集群参数
      mongod --help  
      帮助中 默认的参数 dbpath都有注释 可以查看
    集群帮助如下:  

    Master/slave options (old; use replica sets instead): 主从集群 
      --master                              master mode
      --slave                               slave mode
      --source arg                          when slave: specify master as 
                                            <server:port>
      --only arg                            when slave: specify a single database 
                                            to replicate
      --slavedelay arg                      specify delay (in seconds) to be used 
                                            when applying master ops to slave
      --autoresync                          automatically resync if slave data is 
                                            stale
    
    
    Replica set options:   副本集集群
      --replSet arg                         arg is <setname>[/<optionalseedhostlist
                                            >]
      --replIndexPrefetch arg               specify index prefetching behavior (if 
                                            secondary) [none|_id_only|all]
      --enableMajorityReadConcern           enables majority readConcern
    
    
    Sharding options:  分片集群
      --configsvr                           declare this is a config db of a 
                                            cluster; default port 27019; default 
                                            dir /data/configdb
      --shardsvr                            declare this is a shard db of a 
                                            cluster; default port 27018
    环境:

    副本集名称  myrep
    主从自动选举  192.168.58.147,192.168.58.149,192.168.58.150
    										
    分别在每台机器创建数据目录和启动

    mkdir -p /data/db
    mongod --port "27017" --dbpath "/data/db" --replSet "myrep"	
    任意一台机器 使用mongo连接进入 设置集群配置

    config = { _id:"myrep", members:[
    ... {_id:0,host:"192.168.58.147:27017"},
    ... {_id:1,host:"192.168.58.149:27017"},
    ... {_id:2,host:"192.168.58.150:27017"}]
    ... }
    进入admin数据库  初始化配置

    use admin
    rs.initiate(config);
    查看状态 查询哪个是主节点  PRIMARY表示主节点  SECONDARY表示从节点
    "members" : [
                    {
                            "_id" : 0,
                            "name" : "192.168.58.147:27017",
                            "health" : 1,
                            "state" : 1,
                            "stateStr" : "PRIMARY",
                            "uptime" : 113,
                            "optime" : {
                                    "ts" : Timestamp(1509178311, 1),
                                    "t" : NumberLong(1)
                            },
                            "optimeDate" : ISODate("2017-10-28T08:11:51Z"),
                            "infoMessage" : "could not find member to sync from",
                            "electionTime" : Timestamp(1509178280, 1),
                            "electionDate" : ISODate("2017-10-28T08:11:20Z"),
                            "configVersion" : 1,
                            "self" : true
                    },
                    {
                            "_id" : 1,
                            "name" : "192.168.58.149:27017",
                            "health" : 1,
                            "state" : 2,
                            "stateStr" : "SECONDARY",
                            "uptime" : 50,
                            "optime" : {
                                    "ts" : Timestamp(1509178311, 1),
                                    "t" : NumberLong(1)
                            },
                            "optimeDurable" : {
                                    "ts" : Timestamp(1509178311, 1),
                                    "t" : NumberLong(1)
                            },
                            "optimeDate" : ISODate("2017-10-28T08:11:51Z"),
                            "optimeDurableDate" : ISODate("2017-10-28T08:11:51Z"),
                            "lastHeartbeat" : ISODate("2017-10-28T08:11:58.642Z"),
                            "lastHeartbeatRecv" : ISODate("2017-10-28T08:11:58.423Z"),
                            "pingMs" : NumberLong(0),
                            "syncingTo" : "192.168.58.150:27017",
                            "configVersion" : 1
                    },
                    {
                            "_id" : 2,
                            "name" : "192.168.58.150:27017",
                            "health" : 1,
                            "state" : 2,
                            "stateStr" : "SECONDARY",
                            "uptime" : 50,
                            "optime" : {
                                    "ts" : Timestamp(1509178311, 1),
                                    "t" : NumberLong(1)
                            },
                            "optimeDurable" : {
                                    "ts" : Timestamp(1509178311, 1),
                                    "t" : NumberLong(1)
                            },
                            "optimeDate" : ISODate("2017-10-28T08:11:51Z"),
                            "optimeDurableDate" : ISODate("2017-10-28T08:11:51Z"),
                            "lastHeartbeat" : ISODate("2017-10-28T08:11:58.648Z"),
                            "lastHeartbeatRecv" : ISODate("2017-10-28T08:11:58.797Z"),
                            "pingMs" : NumberLong(0),
                            "syncingTo" : "192.168.58.147:27017",
                            "configVersion" : 1
                    }
            ],
            "ok" : 1

    主节点为147,测试数据插入
    myrep:PRIMARY> use kkk
    switched to db kkk
    myrep:PRIMARY> db.mycol.insert(name:'zs',sex:'boy')
    2017-10-28T01:19:25.629-0700 E QUERY    [thread1] SyntaxError: missing ) after argument list @(shell):1:20
    myrep:PRIMARY> db.mycol.insert({name:'zs',sex:'boy'})
    WriteResult({ "nInserted" : 1 })
    myrep:PRIMARY> show dbs
    admin  0.000GB
    kkk    0.000GB
    local  0.000GB
    test   0.000GB
    myrep:PRIMARY> cd kkk
    2017-10-28T01:19:49.855-0700 E QUERY    [thread1] SyntaxError: missing ; before statement @(shell):1:3
    myrep:PRIMARY> use kkk
    switched to db kkk
    myrep:PRIMARY> show tables
    mycol
    myrep:PRIMARY> db.mycol.find()
    { "_id" : ObjectId("59f43d9808241ee611659c95"), "name" : "zs", "sex" : "boy" }
    149 mongo命令进入当前机器服务

    myrep:SECONDARY> db.getMongo().setSlaveOk();  设置可读
    myrep:SECONDARY> show dbs
    admin  0.000GB
    kkk    0.000GB
    local  0.000GB
    test   0.000GB
    
    发现kkk数据库已经被创建了 也就是正常同步数据

    测试关闭147 主节点
    149客户端查看集群状态

    "members" : [
                    {
                            "_id" : 0,
                            "name" : "192.168.58.147:27017",
                            "health" : 0,
                            "state" : 8,
                            "stateStr" : "(not reachable/healthy)",  不可达
                            "uptime" : 0,
                            "optime" : {
                                    "ts" : Timestamp(0, 0),
                                    "t" : NumberLong(-1)
                            },
                            "optimeDurable" : {
                                    "ts" : Timestamp(0, 0),
                                    "t" : NumberLong(-1)
                            },
                            "optimeDate" : ISODate("1970-01-01T00:00:00Z"),
                            "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
                            "lastHeartbeat" : ISODate("2017-11-01T02:42:23.164Z"),
                            "lastHeartbeatRecv" : ISODate("2017-11-01T02:42:01.859Z"),
                            "pingMs" : NumberLong(2),
                            "lastHeartbeatMessage" : "Connection refused",
                            "configVersion" : -1
                    },
                    {
                            "_id" : 1,
                            "name" : "192.168.58.149:27017",
                            "health" : 1,
                            "state" : 2,
                            "stateStr" : "SECONDARY",
                            "uptime" : 885,
                            "optime" : {
                                    "ts" : Timestamp(1509179151, 4),
                                    "t" : NumberLong(2)
                            },
                            "optimeDate" : ISODate("2017-10-28T08:25:51Z"),
                            "syncingTo" : "192.168.58.150:27017",
                            "configVersion" : 1,
                            "self" : true
                    },
                    {
                            "_id" : 2,
                            "name" : "192.168.58.150:27017",
                            "health" : 1,
                            "state" : 1,
                            "stateStr" : "PRIMARY",  切换回主节点
                            "uptime" : 838,
                            "optime" : {
                                    "ts" : Timestamp(1509179151, 4),
                                    "t" : NumberLong(2)
                            },
                            "optimeDurable" : {
                                    "ts" : Timestamp(1509179151, 4),
                                    "t" : NumberLong(2)
                            },
                            "optimeDate" : ISODate("2017-10-28T08:25:51Z"),
                            "optimeDurableDate" : ISODate("2017-10-28T08:25:51Z"),
                            "lastHeartbeat" : ISODate("2017-11-01T02:42:24.126Z"),
                            "lastHeartbeatRecv" : ISODate("2017-11-01T02:42:23.174Z"),
                            "pingMs" : NumberLong(1),
                            "electionTime" : Timestamp(1509179151, 2),
                            "electionDate" : ISODate("2017-10-28T08:25:51Z"),
                            "configVersion" : 1
                    }
            ],
            "ok" : 1
    150自动切换为主节点了 登录 150 后 执行删除kkk数据库操作
    myrep:SECONDARY> use kkk
    switched to db kkk
    myrep:PRIMARY> db.dropDatabase()
    { "dropped" : "kkk", "ok" : 1 }
    149检查

    myrep:SECONDARY> show dbs
    admin  0.000GB
    local  0.000GB
    test   0.000GB
    重启 147  (注意不要用 mongod启动 带上完整参数启动)
    mongod --port "27017" --dbpath "/data/db" --replSet "myrep"	
    检查状态发现  147的数据库kkk也删除了 检查rs.status()发现 147 自动变成了从服务器

    三。 jdbc操作

    添加maven依赖

    <dependency>
    	  <groupId>org.mongodb</groupId>
    	  <artifactId>mongo-java-driver</artifactId>
    	  <version>3.2.0</version>
    	</dependency>
    
    添加测试类 (代码和之前主从一致 只是需要设置 读取偏好)

    package mongo;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    import org.bson.Document;
    import org.junit.Test;
    
    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientOptions;
    import com.mongodb.ReadPreference;
    import com.mongodb.ServerAddress;
    import com.mongodb.client.FindIterable;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoCursor;
    import com.mongodb.client.MongoDatabase;
    import com.mongodb.client.model.Filters;
    
    public class TestMongoMs {
    	/**
    	 * 获取mongodb的连接
    	 * @return
    	 */
    	public static MongoClient getClient(){
    		//将副本集中所有的节点都加入
    		List<ServerAddress> seedList=new ArrayList<ServerAddress>();
    		seedList.add(new ServerAddress("192.168.58.150", 27017));
    		seedList.add(new ServerAddress("192.168.58.147", 27017));
    		seedList.add(new ServerAddress("192.168.58.149", 27017));
    		//设置偏好为 从节点读取数据 默认是主节点读取
    		MongoClientOptions mco=MongoClientOptions.builder().
    				readPreference(ReadPreference.secondary()).build();
    		MongoClient mc=new MongoClient(seedList,mco);
    		return mc;
    	}
    	/**
    	 * 创建集合并添加文档和document
    	 */
    	@Test
    	public void createCollection(){
    		MongoClient mc=getClient();
    		MongoDatabase database=mc.getDatabase("mydb");
    		MongoCollection<Document> mcd=database.getCollection("userInfo");
    		for(int i=0;i<=100;i++){
    			Document doc=new Document();
    			doc.append("name", "ls"+i);
    			doc.append("sex", i%2==0?"女":"男");
    			doc.append("age", new Random().nextInt(100));
    			mcd.insertOne(doc);
    		}
    	}
    	/**
    	 * 查找集合下所有文档 具体根据条件参考删除
    	 */
    	@Test
    	public void findCollection(){
    		MongoClient mc=getClient();
    		
    		MongoDatabase database=mc.getDatabase("mydb");
    		MongoCollection<Document> mcd=database.getCollection("userInfo");
    		FindIterable<Document> ft=mcd.find();
    		MongoCursor<Document> mr=ft.iterator();
    		while(mr.hasNext()){
    			Document doc=mr.next();
    			System.out.println(doc.get("name")+"--"+doc.get("sex"));
    		}
    	}
    	/**
    	 * 更新文档
    	 * updateOne更新找到的所有结果集中的第一条
    	 * updateMany是更新所有结果集
    	 */
    	@Test
    	public void updateCollection(){
    		MongoClient mc=getClient();
    		MongoDatabase database=mc.getDatabase("mydb");
    		MongoCollection<Document> mcd=database.getCollection("userInfo");
    		
    		Document doc=new Document();
    		doc.append("sex","男");
    		//只是找到所有sex=女  将sex改成男 其他字段不修改
    		mcd.updateMany(Filters.eq("sex", "女"),new Document("$set",doc));
    	}
    	/**
    	 * 根据条件删除
    	 */
    	@Test
    	public void deleteCollection(){
    		MongoClient mc=getClient();
    		MongoDatabase database=mc.getDatabase("mydb");
    		MongoCollection<Document> mcd=database.getCollection("userInfo");
    		//删除满足条件找到的第一条记录
    		mcd.deleteOne(Filters.eq("sex", "女"));
    		//两个条件都满足的所有记录都删除
    		mcd.deleteMany(Filters.and(Filters.eq("sex", "女"),Filters.eq("name", "ls")));
    	}
    }
    

    主要代码在 MongoClient实例化位置 设置偏好为 读 从从服务器 

    设置从服务器可读  db.getMongo().setSlaveOk() 

    测试java结果

    信息: Discovered replica set primary 192.168.58.147:27017
    十一月 01, 2017 4:44:33 下午 com.mongodb.diagnostics.logging.JULLogger log
    信息: Opened connection [connectionId{localValue:4, serverValue:14}] to 192.168.58.149:27017
    多次测试读取都是从 从服务器

  • 相关阅读:
    CSS3 transition 过度
    CSS3 2D转换
    jQuery 选择器
    bootstrap、qjuery、插件 、字体网页
    利用jquery.backstretch插件,背景切换
    js 背景自动切换
    Jquery
    分析动态网页请求爬取腾讯视频评论
    追女神助手v0.1
    动态加载网页的爬取总结
  • 原文地址:https://www.cnblogs.com/liaomin416100569/p/9331174.html
Copyright © 2011-2022 走看看