MongoDB 副本集

中文翻译叫做副本集,不过我并不喜欢把英文翻译成中文,总是感觉怪怪的。其实简单来说就是集
群当中包含了多份数据,保证主节点挂掉了,备节点能继续提供数据服务,提供的前提就是数据需要和
主节点一致。

Mongodb(M)表示主节点,Mongodb(S)表示备节点,Mongodb(A)表示仲裁节点。主备节点存储数
据,仲裁节点不存储数据。客户端同时连接主节点与备节点,不连接仲裁节点。

默认设置下,主节点提供所有增删查改服务,备节点不提供任何服务。但是可以通过设置使备节点
提供查询服务,这样就可以减少主节点的压力,当客户端进行数据查询时,请求自动转到备节点上。这
个设置叫做Read Preference Modes,同时Java 客户端提供了简单的配置方式,可以不必直接对数
据库进行操作。

仲裁节点是一种特殊的节点,它本身并不存储数据,主要的作用是决定哪一个备节点在主节点挂掉之后
提升为主节点,所以客户端不需要连接此节点。这里虽然只有一个备节点,但是仍然需要一个仲裁节点
来提升备节点级别。我开始也不相信必须要有仲裁节点,但是自己也试过没仲裁节点的话,主节点挂了
备节点还是备节点,所以咱们还是需要它的。
介绍完了集群方案,那么现在就开始搭建了。

1.建立数据文件夹

一般情况下不会把数据目录建立在mongodb 的解压目录下,不过这里方便起见,就建在mongodb 解压
目录下吧。

#三个目录分别对应主,备,仲裁节点
mkdir -p /opt/mongodb/replset/master
mkdir -p /opt/mongodb/replset/slaver
mkdir -p /opt/mongodb/replset/arbiter

2.建立配置文件
由于配置比较多,所以我们将配置写到文件里。
vi /opt/mongodb/replset/master/mongodb.cfg

dbpath=/opt/mongodb/replset/master/data
logpath=/opt/mongodb/replset/master/logs/mongodb.log
logappend=true
replSet=shard002
bind_ip=47.107.182.164
port=27017
fork=true

vi /opt/mongodb/replset/slave/mongodb.cfg

dbpath=/opt/mongodb/replset/slave/data
logpath=/opt/mongodb/replset/slave/logs/mongodb.log
logappend=true
replSet=shard002
bind_ip=120.78.181.181
port=27017
fork=true

vi /opt/mongodb/replset/arbiter/mongodb.cfg

dbpath=/opt/mongodb/replset/arbiter/data
logpath=/opt/mongodb/replset/arbiter/logs/mongodb.log
logappend=true
replSet=shard002
bind_ip=112.74.170.31
port=27017
fork=true

参数解释:
dbpath:数据存放目录
logpath:日志存放路径
logappend:以追加的方式记录日志
replSet:replica set 的名字
bind_ip:mongodb 所绑定的ip 地址
port:mongodb 进程所使用的端口号,默认为27017
fork:以后台方式运行进程

3、分发到集群下的其他机器

#将从节点配置发送到120.78.181.181
scp -r /opt/mongodb/replset/slave
root@120.78.181.181:/opt/mongodb/replset
#将仲裁节点配置发送到112.74.170.31
scp -r /opt/mongodb/replset/arbiter
root@112.74.170.31:/opt/mongodb/replset

4.启动mongodb
进入每个mongodb 节点的bin 目录下

#登录47.107.182.164 启动主节点
monood -f /opt/mongodb/replset/master/mongodb.cfg
#登录120.78.181.181 启动从节点
mongod -f /opt/mongodb/replset/slave/mongodb.cfg
#登录112.74.170.31 启动仲裁节点
mongod -f /opt/mongodb/replset/arbiter/mongodb.cfg

注意配置文件的路径一定要保证正确,可以是相对路径也可以是绝对路径。

5.配置主,备,仲裁节点

可以通过客户端连接mongodb,也可以直接在三个节点中选择一个连接mongodb。

#ip 和port 是某个节点的地址
mongo 47.107.182.164:27017
use admin
cfg={_id:"shard002",members:[{_id:0,host:'47.107.182.164:27017',pri
ority:9},{_id:1,host:'120.78.181.181:27017',priority:1},{_id:2,host
:'112.74.170.31:27017',arbiterOnly:true}]};
#使配置生效
rs.initiate(cfg)

注意:cfg 是相当于设置一个变量,可以是任意的名字,当然最好不要是mongodb 的关键字,conf,
config 都可以。最外层的_id 表示replica set 的名字,members 里包含的是所有节点的地址以及优
先级。优先级最高的即成为主节点,即这里的47.107.182.164:27017。特别注意的是,对于仲裁节
点,需要有个特别的配置——arbiterOnly:true。这个千万不能少了,不然主备模式就不能生效。
配置的生效时间根据不同的机器配置会有长有短,配置不错的话基本上十几秒内就能生效,有的配
置需要一两分钟。如果生效了,执行rs.status()命令会看到如下信息:

{
    "set" : "testrs",
    "date" : ISODate("2013-01-05T02:44:43Z"),
    "myState" : 1,
    "members" : [
       {
        "_id" : 0,
        "name" : "47.107.182.164:27004",
        "health" : 1,
        "state" : 1,
        "stateStr" : "PRIMARY",
        "uptime" : 200,
        "optime" : Timestamp(1357285565000, 1),
        "optimeDate" :
        ISODate("2017-12-22T07:46:05Z"),
        "self" : true
      },
      {
        "_id" : 1,
        "name" : "120.78.181.181:27003",
        "health" : 1,
        "state" : 2,
        "stateStr" : "SECONDARY",
        "uptime" : 200,
        "optime" : Timestamp(1357285565000, 1),
        "optimeDate" :
        ISODate("2017-12-22T07:46:05Z"),
        "lastHeartbeat" :
        ISODate("2017-12-22T02:44:42Z"),
        "pingMs" : 0
      },
      {
        "_id" : 2,
        "name" : "112.74.170.31:27005",
        "health" : 1,
        "state" : 7,
        "stateStr" : "ARBITER",
        "uptime" : 200,
        "lastHeartbeat" :
        ISODate("2017-12-22T02:44:42Z"),
        "pingMs" : 0
      }
    ],
   "ok" : 1
}

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

"stateStr" : "STARTUP"

同时可以查看对应节点的日志,发现正在等待别的节点生效或者正在分配数据文件。
现在基本上已经完成了集群的所有搭建工作。至于测试工作,可以留给大家自己试试。一个是往主
节点插入数据,能从备节点查到之前插入的数据(查询备节点可能会遇到某个问题,可以自己去网上查
查看)。二是停掉主节点,备节点能变成主节点提供服务。三是恢复主节点,备节点也能恢复其备的角
色,而不是继续充当主的角色。二和三都可以通过rs.status()命令实时查看集群的变化。