mongodb副本集部署及springboot集成

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

一、mongodb应用安装

1、官网下载mongodb的社区版

https://www.mongodb.com/try/download/community

2、离线安装

将下载好的mongodb安装包上传至服务器指定目录病解压

1配置环境变量
export MONGO_HOME=/home/master/mongodb/mongo
export PATH=$MONGO_HOME/bin:$MONGO_HOME/sbin:$PATH

2测试环境

 mongo  --version

二、mongodb副本集部署

官方操作文档https://www.mongodb.com/docs/manual/

MongoDB中的副本集Replica Set是一组维护相同数据集的mongod服务。 副本集可提供冗余和高可用性副本集能够自动故障恢复功能的主从集群。通俗的讲就是用多台机器进行同一数据的异步同步从而使多台机器拥有同一数据的多个副本并且当主库当掉时在不需要用户干预的情况下自动切换其他备份服务器做主库。而且还可以利用副本服务器做只读服务器实现读写分离提高负载。

    • mongodb副本集类型、角色

副本集有两种类型三种角色

1)两种类型

主节点Primary类型数据操作的主要连接点可读写

从节点Secondaries类型数据冗余备份节点可以读或选举。

(2)三种角色

主要成员Primary主要接收所有写操作。就是主节点。

副本成员Replicate从主节点通过复制操作以维护相同的数据集即备份数据不可写操 作但可以读操作但需要配置。是默认的一种从节点类型。

仲裁者Arbiter不保留任何数据的副本只具有投票选举作用是非必要节点。当然也可以

将仲裁服务器维护为副本集的一部分即副本成员同时也可以是仲裁者。也是一种从节点类型。

2、副本集架构图

1冗余

复制提供冗余并提高数据可用性。 通过在不同数据库服务器上提供多个数据副本复制可提供一定级别的容错功能以防止丢失单个数据库服务器。在某些情况下复制可以提供增加的读取性能因为客户端可以将读取操作发送到不同的服务上 在不同数据中心维护数据副本可以增加分布式应用程序的数据位置和可用性。 您还可以为专用目的维护其他副本例如灾难恢复报告或备份。

2复制

副本集是一组维护相同数据集的mongod实例。 副本集包含多个数据承载节点和可选的一个仲裁节点。在承载数据的节点中一个且仅一个成员被视为主节点而其他节点被视为次要从节点。主节点接收所有写操作。 副本集只能有一个主要能够确认具有{w“most”}写入关注的写入; 虽然在某些情况下另一个mongod实例可能暂时认为自己也是主要的。主要记录其操作日志中的数据集的所有更改即oplog。辅助(副本)节点复制主节点的oplog并将操作应用于其数据集以使辅助节点的数据集反映主节点的数据集。 如果主要人员不在则符合条件的中学将举行选举以选出新的主要人员。

3主节点选举

主从集群整个集群会选出一个“主节点”当其挂掉后又在剩下的从节点中选中其他节点为“主节点”副本集总有一个活跃点(主、primary)和一个或多个备份节点(从、secondary)。

当主节点不与集合的其他成员通信时 对于超过配置的electionTimeoutMillis周期默认为 10 秒符合条件的辅助调用 选举提名自己为新的初选。群集尝试 完成新主节点的选举并恢复正常操作。副本集无法处理写入操作 直到选举成功完成。副本集可以继续 提供读取查询如果此类查询配置为在辅助数据库上运行而 主服务器处于脱机状态。集群选择新主数据库之前的中位数时间不应 通常超过 12 秒假设默认值replica configuration settings.这包括所需的时间 将主数据库标记为不能利用的和 调用并完成选举. 您可以通过修改settings.electionTimeoutMillis复制配置 选择。网络延迟等因素可能会延长所需的时间 要完成副本集选举这反过来又会影响数量 您的集群可以在没有主集群的情况下运行。这些因素是 取决于您的特定群集体系结构。降低electionTimeoutMillis默认复制配置选项10 秒 可以更快地检测主故障。

3、副本集配置部署

在一台机器上模拟3个节点

192.168.81.200:27017 Primary

192.168.81.200:28017 Secondary

192.168.81.200:29017 Arbiter

13个节点配置文件

主节点192.168.81.200:27017配置

# mongod.conf
storage:
  dbPath: /home/master/mongodb/s1/data
  journal:
    enabled: true
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /home/master/mongodb/s1/log/mongod.log
processManagement:
  timeZoneInfo: /usr/share/zoneinfo
  fork: true
  pidFilePath: /home/master/mongodb/s1/log/mongodb.pid
# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0
#security:
replication:
  #副本集名称
  replSetName: wmyrs
#sharding:

从节点192.168.81.200:28017配置

# mongod.conf
storage:
  dbPath: /home/master/mongodb/s2/data
  journal:
    enabled: true
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /home/master/mongodb/s2/log/mongod.log
processManagement:
  timeZoneInfo: /usr/share/zoneinfo
  fork: true
  pidFilePath: /home/master/mongodb/s2/log/mongodb.pid
# network interfaces
net:
  port: 28017
  bindIp: 0.0.0.0
#security:
replication:
  #副本集名称
  replSetName: wmyrs
#sharding:

仲裁节点192.168.81.200:29017配置

# mongod.conf
storage:
  dbPath: /home/master/mongodb/s3/data
  journal:
    enabled: true
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /home/master/mongodb/s3/log/mongod.log
processManagement:
  timeZoneInfo: /usr/share/zoneinfo
  fork: true
  pidFilePath: /home/master/mongodb/s3/log/mongodb.pid
# network interfaces
net:
  port: 29017
  bindIp: 0.0.0.0
#security:
replication:
  #副本集名称
  replSetName: wmyrs
#sharding:
2副本集实例启动脚本
#!/bin/bash
dir=/home/master/mongodb
ports=(27017 28017 29017)
subDir=("s1" "s2" "s3")
function sotpAndStart(){
   pidStr=`netstat -tulnp | grep  $1 | awk '{print $7}'`
   arr1=(${pidStr//\/})
   arr1_0=${arr1[0]}
   arr2=(${arr1_0//$appName/})
 
   pid=${arr2[0]}
   echo  "正在运行$appNmae port:$1 pid:$pid"
   
   if [[ -z $pid ]]; then
      echo "port:$1 $appName 实例挂起"
   else
      echo "port:$1 $appName 关闭实例"
      kill  $pid
   fi

   rm -f  $2/data/mongod.lock
   nohup  $appName  --config   $2/my.conf  >> $2/log/start.log 2>&1 &
   netstat  -tulnp | grep  $1
 
   echo "mongod...$1启动成功"
}

function start(){
   for((i=0;i<3;i++));do
     stopAndStart ${ports[i]}  $dir/${subDir[i]}
   done;
}

start

查看运行状态

ps  -ef  |  grep  mongod
(3)副本集节点设置

客户端连接mongo服务

nongo  --host  192.168.81.200 --port 27017

初始化副本集

rs.initiate()

设置主节点

rs.conf()
wmyrs:SECONDARY> rs.conf()
{
     "_id" : "wmyrs",
     "version" : 1,
     "term" : 1,
     "members" : [
        {
                "_id" : 0,
                "host" : "master:27017",
                "arbiterOnly" : false,
                "buildIndexes" : true,
                "hidden" : false,
                "priority" : 1,
                "tags" : {

                },
                "secondaryDelaySecs" : NumberLong(0),
                "votes" : 1
        }
     ],
     "protocolVersion" : NumberLong(1),
     "writeConcernMajorityJournalDefault" : true,
     "settings" : {
        "chainingAllowed" : true,
        "heartbeatIntervalMillis" : 2000,
        "heartbeatTimeoutSecs" : 10,
        "electionTimeoutMillis" : 10000,
        "catchUpTimeoutMillis" : -1,
        "catchUpTakeoverDelayMillis" : 30000,
        "getLastErrorModes" : {

        },
        "getLastErrorDefaults" : {
                "w" : 1,
                "wtimeout" : 0
        },
        "replicaSetId" : ObjectId("63db7ee718a2e77c350605f4")
     }
}

添加从节点

rs.add("192.168.81.200:28017")
{
     "ok" : 1,
     "$clusterTime" : {
        "clusterTime" : Timestamp(1675329599, 1),
        "signature" : {
                "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                "keyId" : NumberLong(0)
        }
     },
     "operationTime" : Timestamp(1675329599, 1)
}

添加仲裁节点

rs.addArb("192.168.81.200:29017")
{
     "ok" : 1,
     "$clusterTime" : {
        "clusterTime" : Timestamp(1675330868, 1),
        "signature" : {
                "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                "keyId" : NumberLong(0)
        }
     },
     "operationTime" : Timestamp(1675330868, 1)
}

如果添加仲裁节点失败在主节点执行以下命令

{
     "ok" : 1,
     "$clusterTime" : {
        "clusterTime" : Timestamp(1675330868, 1),
        "signature" : {
                "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                "keyId" : NumberLong(0)
        }
     },
     "operationTime" : Timestamp(1675330868, 1)
}

查看副本集状态

rs.status()
{
     "set" : "wmyrs",
     "date" : ISODate("2023-02-02T09:43:31.565Z"),
     "myState" : 1,
     "term" : NumberLong(1),
     "syncSourceHost" : "",
     "syncSourceId" : -1,
     "heartbeatIntervalMillis" : NumberLong(2000),
     "majorityVoteCount" : 2,
     "writeMajorityCount" : 2,
     "votingMembersCount" : 3,
     "writableVotingMembersCount" : 2,
     "optimes" : {
        "lastCommittedOpTime" : {
                "ts" : Timestamp(1675331005, 1),
                "t" : NumberLong(1)
        },
        "lastCommittedWallTime" : ISODate("2023-02-02T09:43:25.880Z"),
        "readConcernMajorityOpTime" : {
                "ts" : Timestamp(1675331005, 1),
                "t" : NumberLong(1)
        },
        "appliedOpTime" : {
                "ts" : Timestamp(1675331005, 1),
                "t" : NumberLong(1)
        },
        "durableOpTime" : {
                "ts" : Timestamp(1675331005, 1),
                "t" : NumberLong(1)
        },
        "lastAppliedWallTime" : ISODate("2023-02-02T09:43:25.880Z"),
        "lastDurableWallTime" : ISODate("2023-02-02T09:43:25.880Z")
     },
     "lastStableRecoveryTimestamp" : Timestamp(1675330985, 1),
     "electionCandidateMetrics" : {
        "lastElectionReason" : "electionTimeout",
        "lastElectionDate" : ISODate("2023-02-02T09:14:15.686Z"),
        "electionTerm" : NumberLong(1),
        "lastCommittedOpTimeAtElection" : {
                "ts" : Timestamp(1675329255, 1),
                "t" : NumberLong(-1)
        },
        "lastSeenOpTimeAtElection" : {
                "ts" : Timestamp(1675329255, 1),
                "t" : NumberLong(-1)
        },
        "numVotesNeeded" : 1,
        "priorityAtElection" : 1,
        "electionTimeoutMillis" : NumberLong(10000),
        "newTermStartDate" : ISODate("2023-02-02T09:14:15.709Z"),
        "wMajorityWriteAvailabilityDate" : ISODate("2023-02-02T09:14:15.720Z")
     },
     "members" : [
        {
                "_id" : 0,
                "name" : "master:27017",
                "health" : 1,
                "state" : 1,
                "stateStr" : "PRIMARY",
                "uptime" : 12641,
                "optime" : {
                        "ts" : Timestamp(1675331005, 1),
                        "t" : NumberLong(1)
                },
                "optimeDate" : ISODate("2023-02-02T09:43:25Z"),
                "lastAppliedWallTime" : ISODate("2023-02-02T09:43:25.880Z"),
                "lastDurableWallTime" : ISODate("2023-02-02T09:43:25.880Z"),
                "syncSourceHost" : "",
                "syncSourceId" : -1,
                "infoMessage" : "",
                "electionTime" : Timestamp(1675329255, 2),
                "electionDate" : ISODate("2023-02-02T09:14:15Z"),
                "configVersion" : 4,
                "configTerm" : 1,
                "self" : true,
                "lastHeartbeatMessage" : ""
        },
        {
                "_id" : 1,
                "name" : "192.168.81.200:28017",
                "health" : 1,
                "state" : 2,
                "stateStr" : "SECONDARY",
                "uptime" : 1412,
                "optime" : {
                        "ts" : Timestamp(1675331005, 1),
                        "t" : NumberLong(1)
                },
                "optimeDurable" : {
                        "ts" : Timestamp(1675331005, 1),
                        "t" : NumberLong(1)
                },
                "optimeDate" : ISODate("2023-02-02T09:43:25Z"),
                "optimeDurableDate" : ISODate("2023-02-02T09:43:25Z"),
                "lastAppliedWallTime" : ISODate("2023-02-02T09:43:25.880Z"),
                "lastDurableWallTime" : ISODate("2023-02-02T09:43:25.880Z"),
                "lastHeartbeat" : ISODate("2023-02-02T09:43:30.904Z"),
                "lastHeartbeatRecv" : ISODate("2023-02-02T09:43:30.921Z"),
                "pingMs" : NumberLong(0),
                "lastHeartbeatMessage" : "",
                "syncSourceHost" : "master:27017",
                "syncSourceId" : 0,
                "infoMessage" : "",
                "configVersion" : 4,
                "configTerm" : 1
        },
        {
                "_id" : 2,
                "name" : "192.168.81.200:29017",
                "health" : 1,
                "state" : 7,
                "stateStr" : "ARBITER",
                "uptime" : 142,
                "lastHeartbeat" : ISODate("2023-02-02T09:43:30.904Z"),
                "lastHeartbeatRecv" : ISODate("2023-02-02T09:43:30.932Z"),
                "pingMs" : NumberLong(0),
                "lastHeartbeatMessage" : "",
                "syncSourceHost" : "",
                "syncSourceId" : -1,
                "infoMessage" : "",
                "configVersion" : 4,
                "configTerm" : 1
        }
     ],
     "ok" : 1,
     "$clusterTime" : {
        "clusterTime" : Timestamp(1675331005, 1),
        "signature" : {
                "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                "keyId" : NumberLong(0)
        }
     },
     "operationTime" : Timestamp(1675331005, 1)
}

添加从节点读权限

rs.secondaryOk()

三、spring boot 集成mongodb

    • 添加gradle依赖

implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
// testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb:2.7.8'

2、mongo副本集连接配置

@Bean
public MongoClient mongoClient() {
    return MongoClients.create("mongodb://192.168.81.200:27017,192.168.81.200:28017,192.168.81.200:29017/wmy_blog?replicaSet=wmyrs");
}

@Bean
public MongoTemplate  mongoTemplate(){
   return new MongoTemplate(mongoClient(),"wmy_blog");
 }

3、MongoTemplate操作增删改查

文档实体类

@Document("user")
public class UserDoc {

    @MongoId
    private String docId;

    private String  name;

    private int  age;

    private String  flag;

    public UserDoc() {

    }

    public UserDoc(String name, int age, String flag) {
        this.name = name;
        this.age = age;
        this.flag = flag;
    }

    public String getDocId() {
        return docId;
    }
}

添加文档数据

public   void  addUser(){
     List<UserDoc>  list  = new ArrayList<>();
     list.add(new UserDoc("LiuPing",34,"xx"));
     list.add(new UserDoc("LiuCui",31,"lk"));
     list.add(new UserDoc("GeJiaLi",33,"yz"));
     list.add(new UserDoc("ChenYingYing",36,"xx"));
     list.add(new UserDoc("YangDuan",34,"zp"));
     list.add(new UserDoc("ZhangTing",33,"hb"));
     list.add(new UserDoc("ZhaoYang",32,"hb"));
     list.add(new UserDoc("LiQian",33,"lk"));
     list.add(new UserDoc("WangWenJiao",31,"wfd"));
     list.add(new UserDoc("WangWenJiao",31,"wfd"));
     list.add(new UserDoc("YangWanWan",33,"ay"));
     list.add(new UserDoc("ZhouYuLing",33,"sq"));
     list.add(new UserDoc("PengHui",22,"xy"));
     list.forEach(e->mongoTemplate.save(e));
}

查询文档数据

public  List<UserDoc>  basicQueryUserList(){
   BasicQuery query  =new BasicQuery("{\"age\":{\"$gt\":33},\"flag\":\"xx\"}");
   return  mongoTemplate.find(query,UserDoc.class);
}

更新文档

 public void  updateUser(UserDoc  userDoc){
    Criteria criteria = new Criteria();
    criteria.and("docId").is(userDoc.getDocId());
    Query  query  = new Query(criteria);
    Update update = new Update().rename("age", "26");
    mongoTemplate.updateMulti(query, update, "user");
 }

删除文档

public void  removeUser(UserDoc  userDoc){
   mongoTemplate.remove(userDoc);
}
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: goSpring