环境:
OS:CentOS 7
DB:2.6.5
机器角色:
192.168.56.91 host01 主
192.168.56.92 host02 从
192.168.56.93 host03 从
---------------------------------------安装部署---------------------------------------
1.安装数据库
每个节点都安装数据库,安装方法一样
[root@pxc01 soft]#tar -xvf mongodb-linux-x86_64-2.6.5.tgz
[root@pxc01 soft]#mv mongodb-linux-x86_64-2.6.5 /opt/mongodb256
[root@pxc01 soft]#cd /opt/mongodb256
[root@pxc01 soft]#mkdir data ##数据文件目录
[root@pxc01 soft]#mkdir log ##日志文件目录
[root@pxc01 soft]#mkdir key ##认证文件目录
[root@pxc01 soft]#mkdir conf ##配置文件目录
2.创建配置文件mongo.cnf
每个节点的配置文件如下,只有port参数不一样,其他都一样
节点2参数port=10002,节点3参数port=10003
port = 10001
fork = true
dbpath = /opt/mongodb265/data
logpath = /opt/mongodb265/log/logs
logappend = true
shardsvr = true
replSet = repltest
##keyFile=/opt/mongodb265/key/keyfile
##auth = true
这里keyFile和auth先注释,因为等部署完初始化完集群后再启用
3.生产认证密钥文件
[root@pxc01 key]# cd /opt/mongodb265/key
[root@pxc01 key]# openssl rand -base64 741 >>keyfile
[root@pxc01 key]# chmod 700 keyfile
4.将节点1上的整个目录都拷贝到另外的机器
[root@pxc01 opt]# scp -r ./mongodb265 root@192.168.56.92:/opt/
[root@pxc01 opt]# scp -r ./mongodb265 root@192.168.56.93:/opt/
5.启动
在每台机器上执行如下命令启动
[root@pxc01 bin]# ./mongod -f /opt/mongodb265/conf/mongo.cnf
[root@pxc02 bin]# ./mongod -f /opt/mongodb265/conf/mongo.cnf
[root@pxc03 bin]# ./mongod -f /opt/mongodb265/conf/mongo.cnf
查看启动日志
018-03-29T01:47:39.125-0400 [initandlisten] waiting for connections on port 10003
2018-03-29T01:47:39.129-0400 [rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)
2018-03-29T01:47:39.129-0400 [rsStart] replSet info you may need to run replSetInitiate -- rs.initiate() in the shell -- if that is not already done
2018-03-29T01:47:40.130-0400 [rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)
2018-03-29T01:47:41.131-0400 [rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)
2018-03-29T01:47:42.132-0400 [rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)
提示需要初始化副本集
6.初始化副本集
登录其中任何一个节点执行操作
>config = { _id:"repltest", members:[{_id:0,host:"192.168.56.91:10001"},{_id:1,host:"192.168.56.92:10002"},{_id:2,host:"192.168.56.93:10003"}]}
>rs.initiate(config);
> rs.initiate(config);
{
"ok" : 0,
"errmsg" : "couldn't initiate : need all members up to initiate, not ok : 192.168.56.93:10003"
}
注意要是其中的节点防火墙没有关闭的化,会无法初始化,关闭防火墙后继续
> rs.initiate(config);
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
到这里要是不需要带认证的副本集的化,就配置完成了,下面的部署我们继续配置带认证的
7.创建用户
在节点1上创建sa用户
use admin
db.createUser({user:"sa",pwd:"123456",roles:["root"]}); --创建用户
db.auth("sa","123456"); --设置用户登陆权限,密码一定要和创建用户时输入的密码相同
show users; --查看创建的用户
登录另外的两个节点,查看是否完成同步
repltest:SECONDARY>db.getMongo().setReadPref('secondaryPreferred');
repltest:SECONDARY>rs.slaveOk();
repltest:SECONDARY> use admin;
repltest:SECONDARY> show users;
{
"_id" : "admin.sa",
"user" : "sa",
"db" : "admin",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
可以看到另外的节点已经同步过来
8.关闭集群启用认证参数
采用localhost登录进行关闭数据库,每个节点操作一致,可以先停掉2个从库后再停主库
停掉从库2
[root@pxc03 bin]# ./mongo localhost:10002
repltest:SECONDARY> use admin
repltest:SECONDARY> db.shutdownServer()
停掉从库3
[root@pxc03 bin]# ./mongo localhost:10002
repltest:SECONDARY> use admin
repltest:SECONDARY> db.shutdownServer()
最后停主库
[root@pxc03 bin]# ./mongo localhost:10001
repltest:SECONDARY> use admin
repltest:SECONDARY> db.shutdownServer()
9.修改配置文件启用认证
port = 10001
fork = true
dbpath = /opt/mongodb265/data
logpath = /opt/mongodb265/log/logs
logappend = true
shardsvr = true
replSet = repltest
keyFile=/opt/mongodb265/key/keyfile
auth = true
将之前注释的两行,启用
keyFile=/opt/mongodb265/key/keyfile
auth = true
10.再次启动数据库
[root@pxc01 bin]# ./mongo 192.168.56.91:10001
MongoDB shell version: 2.6.5
connecting to: 192.168.56.91:10001/test
repltest:PRIMARY> show databases;
2018-03-29T02:43:09.756-0400 listDatabases failed:{
"ok" : 0,
"errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }",
"code" : 13
} at src/mongo/shell/mongo.js:47
0
repltest:PRIMARY> use admin
switched to db admin
repltest:PRIMARY> db.auth("sa","123456"); ##需要认证才能执行数据库命令
1
11.在从节点上设置可读
repltest:SECONDARY> db.getMongo().setSlaveOk(); ##该方法只针对当前的会话有效,要使每次登陆有效
需要若如下的配置:
创建/etc/mongorc.js文件,将rs.slaveOk()写到到该文件,每个机器都做同样的配置,然后重新启动
[root@pxc01 etc]# more mongorc.js
rs.slaveOk();
--------------------------导入数据--------------------------------
将之前备份的json导出文件导入到副本集里
./mongoimport -h 192.168.56.91:10001 -u sa -p 123456 -d hxl -c person2 --authenticationDatabase=admin /opt/person.dat
-------------------------模拟主库宕机---------------------------
查看当前的主库:
repltest:PRIMARY> rs.status()
{
"set" : "repltest",
"date" : ISODate("2018-03-29T09:59:09Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "192.168.56.91:10001",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 11891,
"optime" : Timestamp(1522308291, 10655),
"optimeDate" : ISODate("2018-03-29T07:24:51Z"),
"electionTime" : Timestamp(1522305672, 1),
"electionDate" : ISODate("2018-03-29T06:41:12Z"),
"self" : true
},
{
"_id" : 1,
"name" : "192.168.56.92:10002",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 11882,
"optime" : Timestamp(1522308291, 10655),
"optimeDate" : ISODate("2018-03-29T07:24:51Z"),
"lastHeartbeat" : ISODate("2018-03-29T09:59:08Z"),
"lastHeartbeatRecv" : ISODate("2018-03-29T09:59:07Z"),
"pingMs" : 1,
"syncingTo" : "192.168.56.91:10001"
},
{
"_id" : 2,
"name" : "192.168.56.93:10003",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 11869,
"optime" : Timestamp(1522308291, 10655),
"optimeDate" : ISODate("2018-03-29T07:24:51Z"),
"lastHeartbeat" : ISODate("2018-03-29T09:59:08Z"),
"lastHeartbeatRecv" : ISODate("2018-03-29T09:59:08Z"),
"pingMs" : 1,
"syncingTo" : "192.168.56.91:10001"
}
],
"ok" : 1
}
发现当前主库为192.168.56.91:10001,我们模拟主库宕机
repltest:PRIMARY> use admin
repltest:PRIMARY> db.shutdownServer()
从另外的节点查看当前的集群的状态
repltest:SECONDARY> rs.status()
{
"set" : "repltest",
"date" : ISODate("2018-03-29T10:01:12Z"),
"myState" : 2,
"syncingTo" : "192.168.56.93:10003",
"members" : [
{
"_id" : 0,
"name" : "192.168.56.91:10001",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : Timestamp(1522308291, 10655),
"optimeDate" : ISODate("2018-03-29T07:24:51Z"),
"lastHeartbeat" : ISODate("2018-03-29T10:01:11Z"),
"lastHeartbeatRecv" : ISODate("2018-03-29T10:00:38Z"),
"pingMs" : 0
},
{
"_id" : 1,
"name" : "192.168.56.92:10002",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 12005,
"optime" : Timestamp(1522308291, 10655),
"optimeDate" : ISODate("2018-03-29T07:24:51Z"),
"infoMessage" : "syncing to: 192.168.56.93:10003",
"self" : true
},
{
"_id" : 2,
"name" : "192.168.56.93:10003",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 11991,
"optime" : Timestamp(1522308291, 10655),
"optimeDate" : ISODate("2018-03-29T07:24:51Z"),
"lastHeartbeat" : ISODate("2018-03-29T10:01:12Z"),
"lastHeartbeatRecv" : ISODate("2018-03-29T10:01:12Z"),
"pingMs" : 1,
"electionTime" : Timestamp(1522317643, 1),
"electionDate" : ISODate("2018-03-29T10:00:43Z")
}
],
"ok" : 1
}
发现当前的主库已经变为:192.168.56.93:10003
---------------外部程序访问副本集例子(认证模式+读写分离)--------------------------------
-
package com.hxl;
-
-
import java.util.ArrayList;
-
import java.util.List;
-
-
import com.mongodb.BasicDBObject;
-
import com.mongodb.DB;
-
import com.mongodb.DBCollection;
-
import com.mongodb.DBObject;
-
import com.mongodb.MongoClient;
-
import com.mongodb.MongoCredential;
-
import com.mongodb.ReadPreference;
-
import com.mongodb.ServerAddress;
-
-
public class MongoTest {
-
-
public static void main(String[] args) {
-
try {
-
ServerAddress sa = new ServerAddress("192.168.56.91", 10001);
-
ServerAddress sa1 = new ServerAddress("192.168.56.92", 10002);
-
ServerAddress sa2 = new ServerAddress("192.168.56.93", 10003);
-
-
List<ServerAddress> sends = new ArrayList<ServerAddress>();
-
sends.add(sa);
-
sends.add(sa1);
-
sends.add(sa2);
-
-
List<MongoCredential> mongoCredentialList = new ArrayList<MongoCredential>();
-
/*
-
* 带认证模式 createMongoCRCredential各参数 用户名:sa 数据库:admin 在admin库下验证 密码:
-
* 123456
-
*/
-
mongoCredentialList.add(MongoCredential.createMongoCRCredential(
-
"sa", "admin", "123456".toCharArray()));
-
DB mongoDB = new MongoClient(sends, mongoCredentialList)
-
.getDB("hxl");
-
-
if (null != mongoDB) {
-
System.out.println("Connect to database successfully");
-
} else {
-
System.out.println("Connect to database failed");
-
}
-
DBCollection coll = mongoDB.getCollection("person2");
-
-
/*
-
* 查看文档person2信息 repltest:PRIMARY> db.person2.findOne() { "_id" :
-
* ObjectId("5aa9ca3bc375f6207b4b82ce"), "name" : "hxl0", "age" : 0
-
* }
-
*/
-
-
BasicDBObject object = new BasicDBObject();
-
object.append("name", "hxl0");
-
-
/*
-
* primary:默认参数,只从主节点上进行读取操作;
-
* primaryPreferred:大部分从主节点上读取数据,只有主节点不可用时从secondary节点读取数据.
-
* secondary
-
* :只从secondary节点上进行读取操作,存在的问题是secondary节点的数据会比primary节点数据旧.
-
* secondaryPreferred:优先从secondary节点进行读取操作,secondary节点不可用时从主节点读取数据;
-
* nearest:不管是主节点、secondary节点,从网络延迟最低的节点上读取数据.
-
*/
-
ReadPreference preference = ReadPreference.primary();
-
-
DBObject dbObject = coll.findOne(object, null, preference);
-
-
System.out.println(dbObject);
-
-
} catch (Exception e) {
-
throw new RuntimeException("连接MongoDB数据库错误", e);
-
}
-
}
-
-
}