MongoDB复制集搭建(3.4.17版)

==版本==

mongodb-linux-x86_64-rhel70-3.4.17.tgz

 

==准备==

3个节点,我这里的IP及hostname分别是:

10.11.2.52 dscn49

10.11.2.53 dscn50

10.11.2.54 dscn51

 

同时节点需要完成:

1、关闭防火墙

2、SSH互信

 

==节点规划==

dscn49:PRIMARY

dscn50:SECONDARY

dscn51:ARBITER

 

==安装步骤==

1、上传压缩包

使用ftp工具上传mongodb安装包并解压缩至

/home/hadmin/mongodb

 

2、创建文件夹

配置文件存放路径:mkdir /home/hadmin/mongodb/conf

数据文件存储目录:mkdir /home/hadmin/data/mongodb

日志文件存储路径:mkdir /home/hadmin/data/mongodb/log

 

3、创建MongoDB启动配置文件

配置文件: 

/home/hadmin/mongodb/conf/mongo.conf

 

配置文件内容:

#端口号
port=27017

#数据文件存储路径
dbpath=/home/hadmin/data/mongodb

#日志文件存储路径
logpath=/home/hadmin/data/mongodb/log/mongodb.log

#使用追加的方式写日志
logappend=true

#以守护进程的方式启动,即在后台运行
fork=true

#最大连接数
maxConns=5000

#是否启用身份验证
auth=false

#复制集名称
replSet=repl1

 

配置文件截图:

注意:复制名称的replSet的“S”需要大写。

 

4、配置Linux系统环境变量

vim /etc/profile

source /etc/profile

 

5、同样的配置在其他两个节点完成。

可以通过scp命令,把配置好的mongodb文件夹拷贝到其他两个节点。

scp -r /home/hadmin/mongodb dscn50:/home/hadmin

scp -r /home/hadmin/mongodb dscn51:/home/hadmin

 

==启动==

在dscn49上运行命令:mongod --config /home/hadmin/mongodb/conf/mongodb.conf

在dscn50上运行命令:mongod --config /home/hadmin/mongodb/conf/mongodb.conf

在dscn51上运行命令:mongod --config /home/hadmin/mongodb/conf/mongodb.conf

 

启动成功是可以看到如下日志:

about to fork child process, waiting until server is ready for connections.
forked process: 220682
child process started successfully, parent exiting

 

可以用ps -ef  | grep mongo来查看进程ID。

好,通过上面一顿猛如虎的操作之后,MongoDB集群就启动起来了。

 

==初始化复制集==

启动三个节点的mongodb服务后,开始把他们初始化为副本集。

在想设置primary的节点上运行客户端mongo

 

复制集初始化命令:

config_repl1={_id:"repl1", members:[{_id:0, host:"dscn49:27017", priority:1}, {_id:1, host:"dscn50:27017"}, {_id:2, host:"dscn51:27017", arbiterOnly:true}]}
rs.initiate(config_repl1);

 

正常初始化复制集之后,可以看到

第一个节点变更为PRIMARY。

第二个节点变更为SECONDARY。

第三个节点变更为ARBITER。(仲裁几点)

 

==数据同步测试==

首先向PRIMRY(主节点)写入一条数据,

use qch
db.say.insert({"text":"Hello World"})

插入后可以使用db.say.find()查看一下插入结果。

 

进入SECONDARY(副节点)查看数据是否同步。

默认情况下SECONDARY节点不能读写,要设定slaveOK为true才可以从SECONDARY节点读取数据。

replSet里只能有一个Primary节点,只能在Primary写数据,不能在SECONDARY写数据

如果为设置slaveOK为true,会看到报错信息:

repl1:SECONDARY> db.say.find()
Error: error: {
    "ok" : 0,
    "errmsg" : "not master and slaveOk=false",
    "code" : 13435,
    "codeName" : "NotMasterNoSlaveOk"
}
repl1:SECONDARY>

 

 设置slaveOk之后,查看结果,可以看到数据已经正常同步。

 

==故障切换测试==

副本集还有个重要的功能就是故障切换,

如果把主节点关闭,看看副节点是否能接替主节点进行工作。

 

1、关闭主节点

命令:

use admin
db.shutdownServer()

 

2、去副节点查看状态

repl1:PRIMARY> rs.status()
{
    "set" : "repl1",
    "date" : ISODate("2018-09-26T03:16:42.857Z"),
    "myState" : 1,
    "term" : NumberLong(2),
    "syncingTo" : "",
    "syncSourceHost" : "",
    "syncSourceId" : -1,
    "heartbeatIntervalMillis" : NumberLong(2000),
    "optimes" : {
        "lastCommittedOpTime" : {
            "ts" : Timestamp(1537931731, 1),
            "t" : NumberLong(1)
        },
        "appliedOpTime" : {
            "ts" : Timestamp(1537931793, 1),
            "t" : NumberLong(2)
        },
        "durableOpTime" : {
            "ts" : Timestamp(1537931793, 1),
            "t" : NumberLong(2)
        }
    },
    "members" : [
        {
            "_id" : 0,
            "name" : "dscn49: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("2018-09-26T03:16:42.484Z"),
            "lastHeartbeatRecv" : ISODate("2018-09-26T03:15:32.439Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "Connection refused",
            "syncingTo" : "",
            "syncSourceHost" : "",
            "syncSourceId" : -1,
            "infoMessage" : "",
            "configVersion" : -1
        },
        {
            "_id" : 1,
            "name" : "dscn50:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 1105,
            "optime" : {
                "ts" : Timestamp(1537931793, 1),
                "t" : NumberLong(2)
            },
            "optimeDate" : ISODate("2018-09-26T03:16:33Z"),
            "syncingTo" : "",
            "syncSourceHost" : "",
            "syncSourceId" : -1,
            "infoMessage" : "could not find member to sync from",
            "electionTime" : Timestamp(1537931742, 1),
            "electionDate" : ISODate("2018-09-26T03:15:42Z"),
            "configVersion" : 1,
            "self" : true,
            "lastHeartbeatMessage" : ""
        },
        {
            "_id" : 2,
            "name" : "dscn51:27017",
            "health" : 1,
            "state" : 7,
            "stateStr" : "ARBITER",
            "uptime" : 941,
            "lastHeartbeat" : ISODate("2018-09-26T03:16:42.465Z"),
            "lastHeartbeatRecv" : ISODate("2018-09-26T03:16:40.992Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "",
            "syncingTo" : "",
            "syncSourceHost" : "",
            "syncSourceId" : -1,
            "infoMessage" : "",
            "configVersion" : 1
        }
    ],
    "ok" : 1
}
repl1:PRIMARY>

可以看到

dscn49变为:not reachable/healthy

dscn50变为:PRIMARY

 

==Java程序连接MongoDB副本集测试==

程序如下:

Github路径:https://github.com/quchunhui/tod-train-1.0/blob/master/mongodb/src/main/java/examples/TextMongoDBReplSet.java

public class TextMongoDBReplSet {
    public static void main(String[] args) {
        List<ServerAddress> addresses = new ArrayList<>();
        ServerAddress address1 = new ServerAddress("10.11.2.52", 27017);
        ServerAddress address2 = new ServerAddress("10.11.2.53", 27017);
        ServerAddress address3 = new ServerAddress("10.11.2.54", 27017);
        addresses.add(address1);
        addresses.add(address2);
        addresses.add(address3);

        MongoClient client = new MongoClient(addresses);
        MongoDatabase db = client.getDatabase("qch");
        MongoCollection<Document> coll = db.getCollection("say");

        Document doc = new Document();
        doc.append("morning", "Good Morning");
        coll.insertOne(doc);

        FindIterable<Document> fi = coll.find();
        for (Document rs : fi) {
            System.out.println(rs.toString());
        }
    }
}

 

运行代码,可以看到如下运行结果

 

进入数据库,查看插入结果,也可以看到正常插入。

 

==可能遇到的问题==

1、Connection refused

在初始化集群的时候,可能出现Connection refused的拒绝访问的错误,如下图:

 

解决办法

在配置文件中增加bind_ip=0.0.0.0

bind_ip标识允许连接的客户端IP地址,此处设为0.0.0.0,表示允许所有机器连接。也可设置特定机器的IP。

 

--END--

posted @ 2018-09-26 11:25  大墨垂杨  阅读(923)  评论(0编辑  收藏  举报