美文网首页运维架构设计微服务
MongoDB高可用集群配置的方案

MongoDB高可用集群配置的方案

作者: 小波同学 | 来源:发表于2019-02-24 22:36 被阅读131次

    高可用性即HA(High Availability)指的是通过尽量缩短因日常维护操作(计划)和突发的系统崩溃(非计划)所导致的停机时间,以提高系统和应用的可用性。

    高可用集群的解决方案

    计算机系统的高可用在不同的层面上有不同的表现:

    (1)网络高可用

    由于网络存储的快速发展,网络冗余技术被不断提升,提高IT系统的高可用性的关键应用就是网络高可用性,网络高可用性与网络高可靠性是有区别的,网络高可用性是通过匹配冗余的网络设备实现网络设备的冗余,达到高可用的目的。
    比如冗余的交换机,冗余的路由器等

    (2)服务器高可用

    服务器高可用主要使用的是服务器集群软件或高可用软件来实现。

    (3)存储高可用

    使用软件或硬件技术实现存储的高度可用性。其主要技术指标是存储切换功能,数据复制功能,数据快照功能等。当一台存储出现故障时,另一台备用的存储可以快速切换,达一存储不停机的目的。

    MongoDB的高可用集群配置

    高可用集群,即High Availability Cluster,简称HA Cluster。
    集群(cluster)就是一组计算机,它们作为一个整体向用户提供一组网络资源。
    这些单个的计算机系统 就是集群的节点(node)。
    搭建高可用集群需要合理的配置多台计算机之间的角色,数据恢复,一致性等,主要有以下几种方式:

    (1)主从方式 (非对称方式)

    主机工作,备机处于监控准备状况;当主机宕机时,备机接管主机的一切工作,待主机恢复正常后,按使用者的设定以自动或手动方式将服务切换到主机上运行,数据的一致性通过共享存储系统解决。

    (2)双机双工方式(互备互援)

    两台主机同时运行各自的服务工作且相互监测情况,当任一台主机宕机时,另一台主机立即接管它的一切工作,保证工作实时,应用服务系统的关键数据存放在共享存储系统中。

    (3)集群工作方式(多服务器互备方式)

    多台主机一起工作,各自运行一个或几个服务,各为服务定义一个或多个备用主机,当某个主机故障时,运行在其上的服务就可以被其它主机接管。

    MongoDB集群配置的几种方案也遵循了这几种解决办法。

    Master-Slave主从结构

    image

    主从架构一般用于备份或者做读写分离。一般有一主一从设计和一主多从设计。

    由两种角色构成:

    (1)主(Master)

    可读可写,当数据有修改的时候,会将oplog同步到所有连接的salve上去。

    (2)从(Slave)

    只读不可写,自动从Master同步数据。

    特别的,对于Mongodb来说,并不推荐使用Master-Slave架构,因为Master-Slave其中Master宕机后不能自动恢复,推荐使用Replica Set,后面会有介绍,除非Replica的节点数超过50,才需要使用Master-Slave架构,正常情况是不可能用那么多节点的。

    还有一点,Master-Slave不支持链式结构,Slave只能直接连接Master。Redis的Master-Slave支持链式结构,Slave可以连接Slave,成为Slave的Slave。

    下面为主从配置高可用方案搭建过程(此高可用方案不推荐使用,只做参考):

    1)机器环境
    182.48.115.238    master-node
    182.48.115.236    slave-node
     
    两台机器都关闭防火墙和selinux
    mongodb的安装参考:https://www.jianshu.com/p/5ed4ab8f60cc
     
    2)主从配置
    .............master-node节点配置.............
    [root@master-node ~]# vim /usr/local/mongodb/mongodb.conf
    port=27017
    bind_ip = 182.48.115.238
    dbpath=/usr/local/mongodb/data
    logpath=/usr/local/mongodb/log/mongo.log
    logappend=true
    journal = true
    fork = true
    master = true        //确定自己是主服务器
    
    [root@master-node ~]# nohup /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf &
     
    [root@master-node ~]# ps -ef|grep mongodb
    root     15707 15514 23 16:45 pts/2    00:00:00 /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf
    root     15736 15514  0 16:45 pts/2    00:00:00 grep mongodb
    [root@master-node ~]# lsof -i:27017
    COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    mongod  15707 root    7u  IPv4 153114      0t0  TCP 182.48.115.238:27017 (LISTEN)
     
    由于mongodb.conf里绑定了本机的ip地址182.48.115.238,所以连接mongodb的时候必须用这个ip地址,不能使用默认的127.0.0.1,也就是说:
    [root@master-node ~]# mongo 182.48.115.238:27017     //这样才能连接mongodb
    [root@master-node ~]# mongo 或者 mongodb 127.0.0.1:27017    // 这样不能连接mongodb
    
    .............slave-node节点配置.............
    [root@slave-node ~]# vim /usr/local/mongodb/mongodb.conf
    port=27017
    dbpath=/usr/local/mongodb/data
    logpath=/usr/local/mongodb/log/mongo.log
    logappend=true
    journal = true
    fork = true
    bind_ip = 182.48.115.236            //确定主数据库端口
    source = 182.48.115.238:27017      //确定主数据库端口
    slave = true               //确定自己是从服务器
     
    [root@slave-node ~]# nohup /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf &
     
    [root@slave-node ~]# ps -ef|grep mongo
    root     26290 26126  8 16:47 pts/0    00:00:00 /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf
    root     26316 26126  0 16:47 pts/0    00:00:00 grep mongo
    [root@slave-node ~]# lsof -i:27017
    COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    mongod  26290 root    7u  IPv4 663904      0t0  TCP slave-node1:27017 (LISTEN)
    mongod  26290 root   25u  IPv4 663917      0t0  TCP slave-node1:51060->slave-node2:27017 (ESTABLISHED)
    

    Relica Set副本集方式

    Mongodb的Replica Set即副本集方式主要有两个目的,一个是数据冗余做故障恢复使用,当发生硬件故障或者其它原因造成的宕机时,可以使用副本进行恢复。

    另一个是做读写分离,读的请求分流到副本上,减轻主(Primary)的读压力。

    1.Primary和Secondary搭建的Replica Set

    image

    Replica Set是mongod的实例集合,它们有着同样的数据内容。包含三类角色:

    (1)主节点(Primary)

    接收所有的写请求,然后把修改同步到所有Secondary。一个Replica Set只能有一个Primary节点,当Primary挂掉后,其他Secondary或者Arbiter节点会重新选举出来一个主节点。默认读请求也是发到Primary节点处理的,需要转发到Secondary需要客户端修改一下连接配置。

    (2)副本节点(Secondary)

    与主节点保持同样的数据集。当主节点挂掉的时候,参与选主。

    (3)仲裁者(Arbiter)

    不保有数据,不参与选主,只进行选主投票。使用Arbiter可以减轻数据存储的硬件需求,Arbiter跑起来几乎没什么大的硬件资源需求,但重要的一点是,在生产环境下它和其他数据节点不要部署在同一台机器上。

    注意,一个自动failover的Replica Set节点数必须为奇数,目的是选主投票的时候要有一个大多数才能进行选主决策。

    (4)选主过程

    其中Secondary宕机,不受影响,若Primary宕机,会进行重新选主:

    image

    2.使用Arbiter搭建Replica Set

    偶数个数据节点,加一个Arbiter构成的Replica Set方式:

    image

    Relica Set副本集方式整体大概如图:


    下面为副本集高可用方案搭建过程(此高可用方案也不推荐使用,只做参考):
    1)机器环境
    182.48.115.236 master-node(主节点)
    182.48.115.237 slave-node1(从节点)
    182.48.115.238 slave-node2(从节点)

    MongoDB 安装目录:/usr/local/mongodb
    MongoDB 数据库目录:/usr/local/mongodb/data
    MongoDB 日志目录:/usr/local/mongodb/log/mongo.log
    MongoDB 配置文件:/usr/local/mongodb/mongodb.conf

    对以上三台服务器部署Mongodb的副本集功能,定义副本集名称为:hqmongodb
    关闭三台服务器的iptables防火墙和selinux

    2)确保三台副本集服务器上的配置文件完全相同(即三台机器的mongodb.conf配置一样,除了配置文件中绑定的ip不一样)。下面操作在三台节点机上都要执行:

    编写配置文件,不同的机器修改bind_ip就可以了

    [root@master-node ~]# cat /usr/local/mongodb/mongodb.conf
    port=27017
    bind_ip = 182.48.115.236                 //这个最好配置成本机的ip地址。否则后面进行副本集初始化的时候可能会失败!           
    dbpath=/usr/local/mongodb/data
    logpath=/usr/local/mongodb/log/mongo.log
    pidfilepath=/usr/local/mongodb/mongo.pid
    fork=true
    logappend=true
    shardsvr=true
    directoryperdb=true
    oplogSize=10000
    noprealloc=true
    #auth=true
    #keyFile =/usr/local/mongodb/keyfile
    replSet =shard002
    

    ........................具体配置........................

      # master.conf
      dbpath=/opt/mongodb/data/master
      logpath=/opt/mongodb/logs/master.log
      pidfilepath=/opt/mongodb/logs/master.pid
      directoryperdb=true
      logappend=true
      replSet=ynzw
      bind_ip=10.211.55.10
      port=27017
      oplogSize=10000
      fork=true
      noprealloc=true
    
    
      # slaver1.conf
      dbpath=/opt/mongodb/data/slaver1
      logpath=/opt/mongodb/logs/slaver1.log
      pidfilepath=/opt/mongodb/logs/slaver1.pid
      directoryperdb=true
      logappend=true
      replSet=ynzw
      bind_ip=10.211.55.10
      port=27018
      oplogSize=10000
      fork=true
      noprealloc=true
    
    
      # slaver2.conf
      dbpath=/opt/mongodb/data/slaver2
      logpath=/opt/mongodb/logs/slaver2.log
      pidfilepath=/opt/mongodb/logs/slaver2.pid
      directoryperdb=true
      logappend=true
      replSet=ynzw
      bind_ip=10.211.55.10
      port=27019
      oplogSize=10000
      fork=true
      noprealloc=true
    
    
      # arbiter.conf
      dbpath=/opt/mongodb/data/arbiter
      logpath=/opt/mongodb/logs/arbiter.log
      pidfilepath=/opt/mongodb/logs/arbiter.pid
      directoryperdb=true
      logappend=true
      replSet=ynzw
      bind_ip=10.211.55.10
      port=27020
      oplogSize=10000
      fork=true
      noprealloc=true
    

    启动4个节点

     /opt/mongodb/bin/mongod -f /opt/mongodb/conf/master.conf
     /opt/mongodb/bin/mongod -f /opt/mongodb/conf/slaver1.conf
     /opt/mongodb/bin/mongod -f /opt/mongodb/conf/slaver2.conf
     /opt/mongodb/bin/mongod -f /opt/mongodb/conf/arbiter.conf
    

    配置主,备,仲裁节点
    客户端连接master、slaver中任意一个节点mongodb

    /opt/mongodb/bin/mongo 10.211.55.10:27017  #ip和port是某个节点的地址
    

    开始配置

    > use admin
    > cfg = {_id: "ynzw",members:[{_id: 0,host: '10.211.55.10:27017',priority: 3},{_id: 1,host: '10.211.55.10:27018',priority: 2},{_id: 2,host: '10.211.55.10:27019',priority: 1},{_id: 3,host: '10.211.55.10:27020',arbiterOnly: true}]};
    > rs.initiate(cfg)    #使配置生效
    

    cfg是可以任意的名字,当然最好不要是mongodb的关键字,conf,config都可以。最外层的_id表示replica set的名字,members里包含的是所有节点的地址以及优先级。优先级最高的即成为主节点,即这里的10.211.55.10:27017。特别注意的是,对于仲裁节点,需要有个特别的配置——arbiterOnly:true。这个千万不能少了,不然主备模式就不能生效。

    检验
    配置的生效时间根据不同的机器配置会有长有短,配置不错的话基本上十几秒内就能生效,有的配置需要一两分钟。如果生效了,执行rs.status()命令会看到如下信息:

     ynzw:SECONDARY> rs.status()
      {
              "set" : "ynzw",
              "date" : ISODate("2017-05-26T06:47:32.069Z"),
              "myState" : 1,
              "term" : NumberLong(8),
              "heartbeatIntervalMillis" : NumberLong(2000),
              "members" : [
                      {
                              "_id" : 0,
                              "name" : "10.211.55.10:27017",
                              "health" : 1,
                              "state" : 1,
                              "stateStr" : "PRIMARY",
                              "uptime" : 24,
                              "optime" : {
                                      "ts" : Timestamp(1495781239, 2),
                                      "t" : NumberLong(8)
                              },
                              "optimeDate" : ISODate("2017-05-26T06:47:19Z"),
                              "electionTime" : Timestamp(1495781239, 1),
                              "electionDate" : ISODate("2017-05-26T06:47:19Z"),
                              "configVersion" : 1,
                              "self" : true
                      },
                      {
                              "_id" : 1,
                              "name" : "10.211.55.10:27018",
                              "health" : 1,
                              "state" : 2,
                              "stateStr" : "SECONDARY",
                              "uptime" : 18,
                              "optime" : {
                                      "ts" : Timestamp(1495781239, 2),
                                      "t" : NumberLong(8)
                              },
                              "optimeDate" : ISODate("2017-05-26T06:47:19Z"),
                              "lastHeartbeat" : ISODate("2017-05-26T06:47:31.424Z"),
                              "lastHeartbeatRecv" : ISODate("2017-05-26T06:47:31.247Z"),
                              "pingMs" : NumberLong(0),
                              "syncingTo" : "10.211.55.10:27017",
                              "configVersion" : 1
                      },
                      {
                              "_id" : 2,
                              "name" : "10.211.55.10:27019",
                              "health" : 1,
                              "state" : 2,
                              "stateStr" : "SECONDARY",
                              "uptime" : 18,
                              "optime" : {
                                      "ts" : Timestamp(1495781239, 2),
                                      "t" : NumberLong(8)
                              },
                              "optimeDate" : ISODate("2017-05-26T06:47:19Z"),
                              "lastHeartbeat" : ISODate("2017-05-26T06:47:31.424Z"),
                              "lastHeartbeatRecv" : ISODate("2017-05-26T06:47:31.734Z"),
                              "pingMs" : NumberLong(0),
                              "syncingTo" : "10.211.55.10:27018",
                              "configVersion" : 1
                      },
                      {
                              "_id" : 3,
                              "name" : "10.211.55.10:27020",
                              "health" : 1,
                              "state" : 7,
                              "stateStr" : "ARBITER",
                              "uptime" : 18,
                              "lastHeartbeat" : ISODate("2017-05-26T06:47:31.424Z"),
                              "lastHeartbeatRecv" : ISODate("2017-05-26T06:47:30.437Z"),
                              "pingMs" : NumberLong(0),
                              "configVersion" : 1
                      }
              ],
              "ok" : 1
      }
      ynzw:PRIMARY> 
    

    如果配置正在生效,其中会包含如下信息:"stateStr" : "RECOVERING"

    附录
    mongodb配置文件具体属性解释

     dbpath:数据存放目录
     logpath:日志存放路径
     pidfilepath:进程文件,方便停止mongodb
     directoryperdb:为每一个数据库按照数据库名建立文件夹存放
     logappend:以追加的方式记录日志
     replSet:replica set的名字
     bind_ip:mongodb所绑定的ip地址
     port:mongodb进程所使用的端口号,默认为27017
     oplogSize:mongodb操作日志文件的最大大小。单位为Mb,默认为硬盘剩余空间的5%
     fork:以后台方式运行进程
     noprealloc:不预先分配存储
    

    Sharding分片技术

    当数据量比较大的时候,我们需要把数据分片运行在不同的机器中,以降低CPU、内存和IO的压力,Sharding就是数据库分片技术。

    MongoDB分片技术类似MySQL的水平切分和垂直切分,数据库主要由两种方式做Sharding:垂直扩展和横向切分。

    垂直扩展的方式就是进行集群扩展,添加更多的CPU,内存,磁盘空间等。

    横向切分则是通过数据分片的方式,通过集群统一提供服务:

    image

    (1)MongoDB的Sharding架构

    image

    (2)MongoDB分片架构中的角色

    A.数据分片(Shards)

    用来保存数据,保证数据的高可用性和一致性。可以是一个单独的mongod实例,也可以是一个副本集。

    在生产环境下Shard一般是一个Replica Set,以防止该数据片的单点故障。所有Shard中有一个PrimaryShard,里面包含未进行划分的数据集合:

    image

    B.查询路由(Query Routers)

    路由就是mongos的实例,客户端直接连接mongos,由mongos把读写请求路由到指定的Shard上去。

    一个Sharding集群,可以有一个mongos,也可以有多mongos以减轻客户端请求的压力。

    C.配置服务器(Config servers)

    保存集群的元数据(metadata),包含各个Shard的路由规则。

    Sharding分片技术(混合模式)高可用方案的大体架构图:

    Sharding分片技术(混合模式)高可用方案架构下向mongodb写数据的流程图:

    Sharding分片技术(混合模式)高可用方案架构下向mongodb读数据的流程图:

    下面为Sharding分片高可用方案搭建过程(推荐使用此方案):

    1、MongoDB机器信息

    192.168.252.121 192.168.252.122 192.168.252.123
    mongos mongos mongos
    config server config server config server
    shard server1 主节点 shard server1 副节点 shard server1 仲裁
    shard server2 仲裁 shard server2 主节点 shard server2 副节点
    shard server3 副节点 shard server3 仲裁 shard server3 主节点

    端口分配:

    mongos:20000
    config:21000
    shard1:27001
    shard2:27002
    shard3:27003
    

    下载并且安装

    wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-amazon-3.6.2.tgz
    tar -xzvf mongodb-linux-x86_64-amazon-3.6.2.tgz  -C /usr/local/
    

    所有版本二进制文件,自行下载

    https://www.mongodb.org/dl/win32/x86_64-2008plus-ssl?_ga=2.87139544.1567998244.1517190032-1153843332.1517190032&_gac=1.204211492.1517212002.EAIaIQobChMI44v9_9b82AIV1AcqCh0lcABIEAAYASAAEgKI1_D_BwE
    

    改名

    cd /usr/local/
    mv  mongodb-linux-x86_64-amazon-3.6.2 mongodb
    

    分别在每台机器建立conf、mongos、config、shard1、shard2、shard3六个目录,因为mongos不存储数据,只需要建立日志文件目录即可。

    mkdir -p /usr/local/mongodb/conf \
    mkdir -p /usr/local/mongodb/mongos/log \
    mkdir -p /usr/local/mongodb/config/data \
    mkdir -p /usr/local/mongodb/config/log \
    mkdir -p /usr/local/mongodb/shard1/data \
    mkdir -p /usr/local/mongodb/shard1/log \
    mkdir -p /usr/local/mongodb/shard2/data \
    mkdir -p /usr/local/mongodb/shard2/log \
    mkdir -p /usr/local/mongodb/shard3/data \
    mkdir -p /usr/local/mongodb/shard3/log
    

    配置环境变量

    vi /etc/profile
    # MongoDB 环境变量内容
    export MONGODB_HOME=/usr/local/mongodb
    export PATH=$MONGODB_HOME/bin:$PATH
    

    使立即生效

    source /etc/profile
    

    2、config server配置服务器

    mongodb3.4以后要求配置服务器也创建副本集,不然集群搭建不成功。
    (三台机器)添加配置文件

    vi /usr/local/mongodb/conf/config.conf
    
    ## 配置文件内容
    pidfilepath = /usr/local/mongodb/config/log/configsrv.pid
    dbpath = /usr/local/mongodb/config/data
    logpath = /usr/local/mongodb/config/log/congigsrv.log
    logappend = true
     
    bind_ip = 0.0.0.0
    port = 21000
    fork = true
     
    #declare this is a config db of a cluster;
    configsvr = true
    
    #副本集名称
    replSet = configs
     
    #设置最大连接数
    maxConns = 20000
    

    启动三台服务器的config server

    mongod -f /usr/local/mongodb/conf/config.conf
    

    登录任意一台配置服务器,初始化配置副本集
    连接 MongoDB

    mongo --port 21000
    

    config 变量

    config = {
        _id : "configs",
        members : [
        {_id : 0, host : "192.168.252.121:21000" },
        {_id : 1, host : "192.168.252.122:21000" },
        {_id : 2, host : "192.168.252.123:21000" }
        ]
    }
    

    初始化副本集

    rs.initiate(config)
    

    其中,"_id" : "configs"应与配置文件中配置的 replicaction.replSetName 一致,"members" 中的 "host" 为三个节点的 ip 和 port
    响应内容如下

    > config = {
    ... _id : "configs",
    ... members : [
    ... {_id : 0, host : "192.168.252.121:21000" },
    ... {_id : 1, host : "192.168.252.122:21000" },
    ... {_id : 2, host : "192.168.252.123:21000" }
    ... ]
    ... }
    {
        "_id" : "configs",
        "members" : [
            {
                "_id" : 0,
                "host" : "192.168.252.121:21000"
            },
            {
                "_id" : 1,
                "host" : "192.168.252.122:21000"
            },
            {
                "_id" : 2,
                "host" : "192.168.252.123:21000"
            }
        ]
    }
    > rs.initiate(config);
    {
        "ok" : 1,
        "operationTime" : Timestamp(1517369899, 1),
        "$gleStats" : {
            "lastOpTime" : Timestamp(1517369899, 1),
            "electionId" : ObjectId("000000000000000000000000")
        },
        "$clusterTime" : {
            "clusterTime" : Timestamp(1517369899, 1),
            "signature" : {
                "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                "keyId" : NumberLong(0)
            }
        }
    }
    configs:SECONDARY>
    

    此时会发现终端上的输出已经有了变化。

    //从单个一个
    >
    //变成了
    configs:SECONDARY>
    

    查询状态

    configs:SECONDARY> rs.status()
    

    3. 配置分片副本集

    3.1 设置第一个分片副本集

    (三台机器)设置第一个分片副本集
    配置文件

    vi /usr/local/mongodb/conf/shard1.conf
    
    #配置文件内容
    #——————————————–
    pidfilepath = /usr/local/mongodb/shard1/log/shard1.pid
    dbpath = /usr/local/mongodb/shard1/data
    logpath = /usr/local/mongodb/shard1/log/shard1.log
    logappend = true
    
    bind_ip = 0.0.0.0
    port = 27001
    fork = true
     
    #副本集名称
    replSet = shard1
     
    #declare this is a shard db of a cluster;
    shardsvr = true
     
    #设置最大连接数
    maxConns = 20000
    

    启动三台服务器的shard1 server

    mongod -f /usr/local/mongodb/conf/shard1.conf
    

    登陆任意一台服务器,初始化副本集(除了192.168.252.123)
    连接 MongoDB

    mongo --port 27001
    

    使用admin数据库

    use admin
    

    定义副本集配置

    config = {
        _id : "shard1",
         members : [
             {_id : 0, host : "192.168.252.121:27001" },
             {_id : 1, host : "192.168.252.122:27001" },
             {_id : 2, host : "192.168.252.123:27001" , arbiterOnly: true }
         ]
     }
    

    初始化副本集配置

    rs.initiate(config)
    

    响应内容如下

    > use admin
    switched to db admin
    > config = {
    ...     _id : "shard1",
    ...      members : [
    ...          {_id : 0, host : "192.168.252.121:27001" },
    ...          {_id : 1, host : "192.168.252.122:27001" },
    ...          {_id : 2, host : "192.168.252.123:27001" , arbiterOnly: true }
    ...      ]
    ...  }
    {
        "_id" : "shard1",
        "members" : [
            {
                "_id" : 0,
                "host" : "192.168.252.121:27001"
            },
            {
                "_id" : 1,
                "host" : "192.168.252.122:27001"
            },
            {
                "_id" : 2,
                "host" : "192.168.252.123:27001",
                "arbiterOnly" : true
            }
        ]
    }
    > rs.initiate(config)
    { "ok" : 1 }
    

    此时会发现终端上的输出已经有了变化。

    //从单个一个
    >
    //变成了
    shard1:SECONDARY>
    

    查询状态

    shard1:SECONDARY> rs.status()
    

    3.2 设置第二个分片副本集

    设置第二个分片副本集
    配置文件

    vi /usr/local/mongodb/conf/shard2.conf
    
    #配置文件内容
    #——————————————–
    pidfilepath = /usr/local/mongodb/shard2/log/shard2.pid
    dbpath = /usr/local/mongodb/shard2/data
    logpath = /usr/local/mongodb/shard2/log/shard2.log
    logappend = true
    
    bind_ip = 0.0.0.0
    port = 27002
    fork = true
     
    #副本集名称
    replSet=shard2
     
    #declare this is a shard db of a cluster;
    shardsvr = true
     
    #设置最大连接数
    maxConns=20000
    

    启动三台服务器的shard2 server

    mongod -f /usr/local/mongodb/conf/shard2.conf
    

    连接 MongoDB

    mongo --port 27002
    

    使用admin数据库

    use admin
    

    定义副本集配置

    config = {
        _id : "shard2",
         members : [
             {_id : 0, host : "192.168.252.121:27002"  , arbiterOnly: true },
             {_id : 1, host : "192.168.252.122:27002" },
             {_id : 2, host : "192.168.252.123:27002" }
         ]
     }
    

    初始化副本集配置

    rs.initiate(config)
    

    响应内容如下

    > use admin
    switched to db admin
    > config = {
    ...     _id : "shard2",
    ...      members : [
    ...          {_id : 0, host : "192.168.252.121:27002"  , arbiterOnly: true },
    ...          {_id : 1, host : "192.168.252.122:27002" },
    ...          {_id : 2, host : "192.168.252.123:27002" }
    ...      ]
    ...  }
    {
        "_id" : "shard2",
        "members" : [
            {
                "_id" : 0,
                "host" : "192.168.252.121:27002",
                "arbiterOnly" : true
            },
            {
                "_id" : 1,
                "host" : "192.168.252.122:27002"
            },
            {
                "_id" : 2,
                "host" : "192.168.252.123:27002"
            }
        ]
    }
    > rs.initiate(config)
    { "ok" : 1 }
    shard2:SECONDARY> rs.status()
    

    3.3 设置第三个分片副本集

    vi /usr/local/mongodb/conf/shard3.conf
    
    #配置文件内容
    #——————————————–
    pidfilepath = /usr/local/mongodb/shard3/log/shard3.pid
    dbpath = /usr/local/mongodb/shard3/data
    logpath = /usr/local/mongodb/shard3/log/shard3.log
    logappend = true
    
    bind_ip = 0.0.0.0
    port = 27003
    fork = true
    
    #副本集名称
    replSet=shard3
     
    #declare this is a shard db of a cluster;
    shardsvr = true
     
    #设置最大连接数
    maxConns=20000
    

    启动三台服务器的shard3 server

    mongod -f /usr/local/mongodb/conf/shard3.conf
    

    登陆任意一台服务器,初始化副本集(除了192.168.252.121)

    mongo --port 27003
    

    使用admin数据库

    use admin
    

    定义副本集配置

    config = {
        _id : "shard3",
         members : [
             {_id : 0, host : "192.168.252.121:27003" },
             {_id : 1, host : "192.168.252.122:27003" , arbiterOnly: true},
             {_id : 2, host : "192.168.252.123:27003" }
         ]
     }
    

    初始化副本集配置

    rs.initiate(config)
    

    响应内容如下

    > use admin
    switched to db admin
    > config = {
    ...     _id : "shard3",
    ...      members : [
    ...          {_id : 0, host : "192.168.252.121:27003" },
    ...          {_id : 1, host : "192.168.252.122:27003" , arbiterOnly: true},
    ...          {_id : 2, host : "192.168.252.123:27003" }
    ...      ]
    ...  }
    {
        "_id" : "shard3",
        "members" : [
            {
                "_id" : 0,
                "host" : "192.168.252.121:27003"
            },
            {
                "_id" : 1,
                "host" : "192.168.252.122:27003",
                "arbiterOnly" : true
            },
            {
                "_id" : 2,
                "host" : "192.168.252.123:27003"
            }
        ]
    }
    > rs.initiate(config)
    { "ok" : 1 }
    shard3:SECONDARY> rs.status()
    

    3.4 配置路由服务器 mongos

    (三台机器)先启动配置服务器和分片服务器,后启动路由实例启动路由实例:

    vi /usr/local/mongodb/conf/mongos.conf
    
    #内容
    pidfilepath = /usr/local/mongodb/mongos/log/mongos.pid
    logpath = /usr/local/mongodb/mongos/log/mongos.log
    logappend = true
    
    bind_ip = 0.0.0.0
    port = 20000
    fork = true
    
    #监听的配置服务器,只能有1个或者3个 configs为配置服务器的副本集名字
    configdb = configs/192.168.252.121:21000,192.168.252.122:21000,192.168.252.123:21000
     
    #设置最大连接数
    maxConns = 20000
    

    启动三台服务器的mongos server

    mongos -f /usr/local/mongodb/conf/mongos.conf
    

    4. 串联路由服务器

    目前搭建了mongodb配置服务器、路由服务器,各个分片服务器,不过应用程序连接到mongos路由服务器并不能使用分片机制,还需要在程序里设置分片配置,让分片生效。
    登陆任意一台mongos

    mongo --port 20000
    

    使用admin数据库

    use  admin
    

    串联路由服务器与分配副本集

    sh.addShard("shard1/192.168.252.121:27001,192.168.252.122:27001,192.168.252.123:27001");
    sh.addShard("shard2/192.168.252.121:27002,192.168.252.122:27002,192.168.252.123:27002");
    sh.addShard("shard3/192.168.252.121:27003,192.168.252.122:27003,192.168.252.123:27003");
    

    查看集群状态

    sh.status()
    

    响应内容如下

    mongos> sh.status()
    --- Sharding Status --- 
      sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5a713a37d56e076f3eb47acf")
      }
      shards:
            {  "_id" : "shard1",  "host" : "shard1/192.168.252.121:27001,192.168.252.122:27001",  "state" : 1 }
            {  "_id" : "shard2",  "host" : "shard2/192.168.252.122:27002,192.168.252.123:27002",  "state" : 1 }
            {  "_id" : "shard3",  "host" : "shard3/192.168.252.121:27003,192.168.252.123:27003",  "state" : 1 }
      active mongoses:
            "3.6.2" : 3
      autosplit:
            Currently enabled: yes
      balancer:
            Currently enabled:  yes
            Currently running:  no
            Failed balancer rounds in last 5 attempts:  0
            Migration Results for the last 24 hours: 
                    No recent migrations
      databases:
            {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
    
    mongos>
    

    5. 启用集合分片生效

    目前配置服务、路由服务、分片服务、副本集服务都已经串联起来了,但我们的目的是希望插入数据,数据能够自动分片。连接在mongos上,准备让指定的数据库、指定的集合分片生效。
    登陆任意一台mongos

    mongo --port 20000
    

    使用admin数据库

    use  admin
    

    指定testdb分片生效,如下图:

    db.runCommand( { enablesharding :"testdb"});
    
    或
    
    mongos> sh.enablesharding("testdb")
    
    sh.enablesharding("testdb")

    指定数据库里需要分片的集合和片键,哈希name分片,如下图:

    db.runCommand( { shardcollection : "testdb.table1",key : {"name": "hashed"} } );
    
    或
    
    mongos> sh.shardcollection("testdb.table1", {"name": "hashed"})
    
    sh.shardcollection("testdb.table1", {"name": "hashed"})

    通过命令查看mongodb路由服务器上的shards集合会有数据展示,如下图:


    shards数据

    通过命令查看mongodb路由服务器上的chunks集合会有数据展示,如下图:


    chunks数据

    我们设置testdb的 table1 表需要分片,根据 id 或name自动分片到 shard1 ,shard2,shard3 上面去。要这样设置是因为不是所有mongodb 的数据库和表 都需要分片!
    测试分片配置结果
    连接 MongoDB 路由服务

    mongo  127.0.0.1:20000
    

    切换到 testdb 数据库

    use  testdb;
    

    插入测试数据

    for(i=1;i<=100000;i++){db.table1.insert({"id":i,"name":"penglei"})};
    

    总条数

    db.table1.aggregate([{$group : {_id : "$name", totle : {$sum : 1}}}])
    

    查看分片情况如下

    • shard1: "count": 33755

    • shard2: "count": 33143,

    • shard3: "count": 33102

    结论数据基本均匀

    db.table1.stats();
    
    mongos> db.table1.stats();
    {
        "sharded": true,
        "capped": false,
        "ns": "testdb.table1",
        "count": 100000,
        "size": 5200000,
        "storageSize": 1519616,
        "totalIndexSize": 3530752,
        "indexSizes": {
            "_id_": 892928,
            "id_hashed": 2637824
        },
        "avgObjSize": 52,
        "nindexes": 2,
        "nchunks": 6,
        "shards": {
            "shard1": {
                "ns": "testdb.table1",
                "size": 1755260,
                "count": 33755,
                "avgObjSize": 52,
                "storageSize": 532480,
                "capped": false,
                "wiredTiger": {
                ...省略很多
                }
            },
            "shard2": {
                "ns": "testdb.table1",
                "size": 1723436,
                "count": 33143,
                "avgObjSize": 52,
                "storageSize": 479232,
                "capped": false,
                "wiredTiger": {
                ...省略很多
                }
            },
            "shard3": {
                "ns": "testdb.table1",
                "size": 1721304,
                "count": 33102,
                "avgObjSize": 52,
                "storageSize": 507904,
                "capped": false,
                "wiredTiger": {
                ...省略很多
                }
            }
        },
        "ok": 1,
        "$clusterTime": {
            "clusterTime": Timestamp(1517488062, 350),
            "signature": {
                "hash": BinData(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                "keyId": NumberLong(0)
            }
        },
        "operationTime": Timestamp(1517488062, 350)
    }
    mongos> 
    

    分组查看总数量是:100000

    mongos> db.table1.aggregate([{$group : {_id : "$name", totle : {$sum : 1}}}])
    { "_id" : "penglei", "totle" : 100000 }
    mongos>
    

    后期运维

    参考

    手把手教你 MongoDB 的安装与详细使用(一)

    http://www.ymq.io/2018/01/26/MongoDB-1/

    手把手教你 MongoDB 的安装与详细使用(二)

    http://www.ymq.io/2018/01/29/MongoDB-2/

    创建索引

    db.table1.createIndex({"name":1})
    db.table1.getIndexes()
    
    
    image.png image.png image.png

    启动

    mongodb的启动顺序是,先启动配置服务器,在启动分片,最后启动mongos.

    mongod -f /usr/local/mongodb/conf/config.conf
    mongod -f /usr/local/mongodb/conf/shard1.conf
    mongod -f /usr/local/mongodb/conf/shard2.conf
    mongod -f /usr/local/mongodb/conf/shard3.conf
    mongod -f /usr/local/mongodb/conf/mongos.conf
    

    启动报错

    about to fork child process, waiting until server is ready for connections.
    forked process: 1303
    child process started successfully, parent exiting
    [root@node1 ~]# mongod -f /usr/local/mongodb/conf/shard1.conf
    about to fork child process, waiting until server is ready for connections.
    forked process: 1384
    

    删除 mongod.lock

    cd /usr/local/mongodb/shard1/data
    rm -rf mongod.lock
    

    关闭

    #debian、ubuntu系统下:
    
    apt-get install psmisc
    
    #centos或、rhel系统下:
    
    yum install psmisc
    

    关闭时,直接killall杀掉所有进程

    killall mongod
    killall mongos
    

    参考:

    百度百科-高可用集群

    MongoDB 教程

    https://www.cnblogs.com/binyue/p/5901328.html

    Runoob 教程:http://www.runoob.com/mongodb/mongodb-tutorial.html

    MongoDB 官网地址:https://www.mongodb.com

    MongoDB 官方英文文档:https://docs.mongodb.com/manual

    MongoDB 各平台下载地址:https://www.mongodb.com/download-center#community

    MongoDB 安装 https://docs.mongodb.com/manual/tutorial/install-mongodb-enterprise-on-ubuntu

    mongodb高可用具体配置参考:

    Mongodb主从复制 及 副本集+分片集群梳理:
    https://www.cnblogs.com/nulige/p/7613721.html

    搭建 MongoDB分片(sharding) / 分区 / 集群环境:https://www.jianshu.com/p/66e7ba201545

    相关文章

      网友评论

        本文标题:MongoDB高可用集群配置的方案

        本文链接:https://www.haomeiwen.com/subject/elliyqtx.html