@(MongoDB)[副本集|三节点]
自己测试着玩可以使用单实例mongod服务,但若部署在生产环境下,还是需要复制集或分片架构的,本文只探讨复制集搭建过程;复制集功能强大,可以实现故障自动切换、各个节点之间数据完全一致等高可用功能。
设备类型:VMware Virtual Platform
内存:8G
CPU: 4 (2个独立双核CPU)
磁盘空间:200G
OS: RHEL 7.2
MongoDB版本:3.2.10
Python版本:2.7.5
共使用3台服务器(官网建议,使用奇数个服务器)
服务器A:192.168.1.100:27018
服务器B:192.168.1.101:27018
服务器C:192.168.1.102:10001(Arbiter)
软件存放路径:/apps/mongodb/bin
数据存放路径:/data/dbdata
日志存放路径:/data/logs
keyfile存放路径:/data/keyfile
配置文件存放路径:/etc/mongodb.cnf
mongo进程存放路径:/data/pid
采用的是3节点的复制集架构
Primary + Secondary +Arbiter
如果Primary主节点down掉之后,架构会自动failover,并选举出新的Primary
官网下载地址:https://www.mongodb.com/download-center?jmp=nav
根据不同系统选择,我们选择RHEL 7 LINUX 64-bit x64,然后将程序包上传到三台Linux服务器上的/apps
路径下
$cd /apps
$ tar -zxvf mongodb-linux-x86_64-rhel70-3.2.10.tgz
$ ll
drwxrwxr-x. 3 mongo mongo 86 Dec 8 18:34 mongodb-linux-x86_64-rhel70-3.2.10
-rw-rw-r--. 1 mongo mongo 82140922 Oct 24 22:03 mongodb-linux-x86_64-rhel70-3.2.10.tgz
$ mv mongodb-linux-x86_64-rhel70-3.2.10 mongodb ---为了方便后续使用,我们重命名文档
$ systemctl stop firewalld
$ systemctl status firewalld
注:
如果想开启防火墙并配置mongo端口的话,可以参考我的《Firewalld防火墙》配置方法
需要将大内存页面transparent_hugepage参数设置为never,否则,在登录mongo shell的时候会有如下报错:
$cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
$cat /sys/kernel/mm/transparent_hugepage/defrag
[always] madvise never
如果没有下列文件则create, 并将下列代码复制进此启动文件中
$vim /etc/init.d/disable-transparent-hugepages
#!/bin/bash
### BEGIN INIT INFO
# Provides: disable-transparent-hugepages
# Required-Start: $local_fs
# Required-Stop:
# X-Start-Before: mongod mongodb-mms-automation-agent
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Disable Linux transparent huge pages
# Description: Disable Linux transparent huge pages, to improve
# database performance.
### END INIT INFO
case $1 in
start)
if [ -d /sys/kernel/mm/transparent_hugepage ]; then
thp_path=/sys/kernel/mm/transparent_hugepage
elif [ -d /sys/kernel/mm/redhat_transparent_hugepage ]; then
thp_path=/sys/kernel/mm/redhat_transparent_hugepage
else
return 0
fi
echo 'never' > ${thp_path}/enabled
echo 'never' > ${thp_path}/defrag
re='^[0-1]+$'
if [[ $(cat ${thp_path}/khugepaged/defrag) =~ $re ]]
then
# RHEL 7
echo 0 > ${thp_path}/khugepaged/defrag
else
# RHEL 6
echo 'no' > ${thp_path}/khugepaged/defrag
fi
unset re
unset thp_path
;;
esac
$ sudo chmod 755 /etc/init.d/disable-transparent-hugepages
$ sudo chkconfig --add disable-transparent-hugepages
重启服务器后检查该参数是否已经生效:
$ cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
$ cat /sys/kernel/mm/transparent_hugepage/defrag
always madvise [never]
官方的配置链接:Disable Transparent Huge Pages (THP)
有时候Linux系统默认的open files
(文件句柄)是1024, 但是mongod官网建议是64000,并且确实需要修改要不然会被坑(很不幸,我遇到了)
使用ulimit -a
可以查看到Linux系统的一些设置:
[mongo@mongodb01 ~]$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 31206
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 64000
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 64000
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
而mongod官网建议的配置如下:
- -f (file size): unlimited
- -t (cpu time): unlimited
- -v (virtual memory): unlimited [1]
- -n (open files): 64000
- -m (memory size): unlimited [1] [2]
- -u (processes/threads): 64000
可以使用命令修改上述配置参数(ulimit -n 64000
),但是服务器重启后将失效;
故为了永久生效,我们可通过修改/etc/security/limits.conf
实现,添加如下记录;
$ vim /etc/security/limits.conf
#@student - maxlogins 4
mongo soft nproc 64000
mongo hard nproc 64000
mongo soft nofile 64000
mongo hard nofile 64000
# End of file
修改成功后重启mongod生效
root#groupadd mongogrp
root#useradd -g mongogrp mongo
root#chown -R mongo:mongogrp /data
root#su mongo
把所有文件都存储在/data路径下(也可以根据自己需求进行路径修改)
$su mongo
$mkdir -p /data/dbdata/r1 ---数据文件存放
$mkdir -p /data/logs/r1_logs ---创建日志文件路径:
$mkdir -p /data/keyfile ---存放keyfile
$mkdir -p /data/pid ---mongodb进程id存放
$ vi .bash_profile
PATH=$PATH:$HOME/.local/bin:$HOME/bin:/apps/mongodb/bin ---添加上mongo程序路径
export PATH
$source .bash_profile ---使环境变量生效
在节点1上创建keyfile
之后,然后复制到其他节点
$cd /data/keyfile
$openssl rand -base64 741 > security ---新建keyfile文件
$chmod 600 security ---配置keyfile文件的只读权限
注:
后来新版本改为400的权限了。
可放在/etc
路径下, 当然也可以放到你其他路径亦可,不强求
$su root
#cd /etc
#vim mongodb.cnf`
配置文件内容如下:
(*一定注意格式,多一个空格都不行*
)
storage:
dbPath: /data/dbdata/r1
journal:
enabled: true
commitIntervalMs: 50
directoryPerDB: true
engine: wiredTiger
wiredTiger:
engineConfig:
directoryForIndexes: true
systemLog:
quiet: false
path: /data/logs/r1_logs/r1.log
destination: file
logAppend: true
processManagement:
fork: true
pidFilePath: /data/pid/r1.pid
net:
port: 27018
maxIncomingConnections: 3000
wireObjectCheck: true
#security:
#keyFile: /data/key/r1
replication:
oplogSizeMB: 10240
replSetName: rs1
#operationProfiling:
#slowOpThresholdMs: 100
#mode: slowOp
注:
keyFIle参数被注销,当复制集完成并创建完账户后再开启keyFIle参数
这只是我目前暂时使用到的一些参数,如果你有其他需求可以参考官方参数文档进行添加配置
由于是在root账号下创建的,所以我们需要修改一下所属用户
#chownmongo:mongo mongodb.cnf
#chmod 700 mongodb.cnf
#ls -l /etc/mongodb.cnf
-rwxr----. 1 mongo mongo 611 Dec 6 12:12 /etc/mongodb.cnf
以配置文件形式启动
$/apps/mongo/bin/mongod -f /etc/mongod.cnf
about to fork child process, waiting until server is ready for connections.
forked process: 1737
child process started successfully, parent exiting
注:
如果在此启动过程中有任何报错,注意仔细查看/data/logs/r1.log
日志文件),以后无论遇到任何启动问题或者其他异常,一定要学会先去看日志文件,因为更详细。
至此,此节点的实例已经启动完毕,并使用上述步骤将其余2个节点的mongod服务启动
3个节点的mongod服务都启动完之后,随意连接一个服务器的实例,进行复制集配置
(此处我们选择192.168.1.100:27018)
$mongo --port 27018
MongoDB shell version: 3.2.10
connecting to: test
>use admin
switched to db admin
> config_rs = { _id:"rs1", members:[ ---配置复制集成员
... ... {_id:0,host:"192.168.1.100:27018",priority:99},
... ... {_id:1,host:"192.168.1.101:27018",priority:1},
... ... {_id:2,host:"192.168.1.102:27018",arbiterOnly:true}
... ... ]
... ... }
> rs.initiate(config_rs) ---初始化配置,1表示成功
{ "ok" : 1 }
注:
host可以使用域名来代替IP,rs.initiate()
初始化后会进行一次选举,一般情况下priority高的节点优先被选为Primary
.
>rs.status() ---查看复制集状态
{
"set" : "rs1",
"date" : ISODate("2017-02-17T06:53:21.513Z"),
"myState" : 1,
"term" : NumberLong(1),
"heartbeatIntervalMillis" : NumberLong(2000),
"members" : [
{
"_id" : 0,
"name" : "192.168.1.100:27018",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1172,
"optime" : {
"ts" : Timestamp(1487314398, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2017-02-17T06:53:18Z"),
"electionTime" : Timestamp(1487313948, 2),
"electionDate" : ISODate("2017-02-17T06:45:48Z"),
"configVersion" : 5,
"self" : true
},
{
"_id" : 1,
"name" : "192.168.1.102:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 220,
"optime" : {
"ts" : Timestamp(1487314398, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2017-02-17T06:53:18Z"),
"lastHeartbeat" : ISODate("2017-02-17T06:53:20.655Z"),
"lastHeartbeatRecv" : ISODate("2017-02-17T06:53:20.659Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "10.26.14.24:27027",
"configVersion" : 5
},
{
"_id" : 2,
"name" : "192.168.1.103:27018",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 0,
"lastHeartbeat" : ISODate("2017-02-17T06:53:20.656Z"),
"lastHeartbeatRecv" : ISODate("2017-02-17T06:53:18.658Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "10.26.14.25:27027",
"configVersion" : 5
}
],
"ok" : 1
}
注:
“health” 为1表示节点运行正常
>use admin
>db.createUser({user:'superadmin',pwd:'123456', roles:[{role:'root', db:'admin'}]})
>db.auth("superadmin',"123456") ----认证账户
此参数有两个目的:
- 副本集成员间认证通讯
- 自动开启鉴权认证,相当于--auth
参数
所以这就是我们为什么需要先注释掉keyfile参数,等创建完账号后再开启,先开启就无法登陆到mongo实例了。
将mongodb.cnf中的keyfile注释取消
security:
keyFile: /data/key/r1
关闭三个节点的进程,并重新启动三个节点的mongod服务,然后通过命令进行登录验证:
# mongo 192.168.1.100:27018/admin -usuperadmin -p
至此,复制集架构就部署完毕了
应用层面连接副本集建议使用Connection URI方式, 这样可以实现自动failover
$mongodb://root:123456@192.168.1.100:27018,192.168.1.101:27018/admin?