当前位置:Gxlcms > 数据库问题 > MongoDB高可用集群配置方案

MongoDB高可用集群配置方案

时间:2021-07-01 10:21:17 帮助过:7人阅读

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.121192.168.252.122192.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
                        
                    

人气教程排行