Replica set搭建過程
@(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
部署:
1、下載mongodb
官網下載地址:https://www.mongodb.com/download-center?jmp=nav
根據不同系統選擇,我們選擇RHEL 7 LINUX 64-bit x64,然後將程序包上傳到三臺Linux服務器上的/apps
路徑下
1.1、解壓mongodb壓縮包
$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 ---爲了方便後續使用,我們重命名文檔
1.2、關閉防火牆
$ systemctl stop firewalld
$ systemctl status firewalld
注:
如果想開啓防火牆並配置mongo端口的話,可以參考我的《Firewalld防火牆》配置方法
1.3、關閉大內存頁面
需要將大內存頁面transparent_hugepage參數設置爲never,否則,在登錄mongo shell的時候會有如下報錯:
1.3.1 先查看參數值:
$cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
$cat /sys/kernel/mm/transparent_hugepage/defrag
[always] madvise never
1.3.2 配置transparent_hugepage啓動服務
如果沒有下列文件則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
1.3.3 授權服務,並設置開機啓動
$ sudo chmod 755 /etc/init.d/disable-transparent-hugepages
$ sudo chkconfig --add disable-transparent-hugepages
1.3.4 檢查結果
重啓服務器後檢查該參數是否已經生效:
$ 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)
1.4、修改open files
有時候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生效
2、創建用戶mongo
root#groupadd mongogrp
root#useradd -g mongogrp mongo
root#chown -R mongo:mongogrp /data
root#su mongo
3、創建mongodb所需路徑
把所有文件都存儲在/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存放
4、設置環境變量
$ vi .bash_profile
PATH=$PATH:$HOME/.local/bin:$HOME/bin:/apps/mongodb/bin ---添加上mongo程序路徑
export PATH
$source .bash_profile ---使環境變量生效
5、創建keyfile文件
在節點1上創建keyfile
之後,然後複製到其他節點
$cd /data/keyfile
$openssl rand -base64 741 > security ---新建keyfile文件
$chmod 600 security ---配置keyfile文件的只讀權限
注:
後來新版本改爲400的權限了。
6、新建配置文件mongodb.cnf
可放在/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參數
這只是我目前暫時使用到的一些參數,如果你有其他需求可以參考官方參數文檔進行添加配置
6.1 變更配置文件權限
由於是在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
7、啓動mongod
以配置文件形式啓動
$/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服務啓動
8、配置複製集成員
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表示節點運行正常
9、新建管理員賬號
>use admin
>db.createUser({user:'superadmin',pwd:'123456', roles:[{role:'root', db:'admin'}]})
>db.auth("superadmin',"123456") ----認證賬戶
10、開啓keyfile認證
此參數有兩個目的:
- 副本集成員間認證通訊
- 自動開啓鑑權認證,相當於--auth
參數
所以這就是我們爲什麼需要先註釋掉keyfile參數,等創建完賬號後再開啓,先開啓就無法登陸到mongo實例了。
將mongodb.cnf中的keyfile註釋取消
security:
keyFile: /data/key/r1
關閉三個節點的進程,並重新啓動三個節點的mongod服務,然後通過命令進行登錄驗證:
# mongo 192.168.1.100:27018/admin -usuperadmin -p
至此,複製集架構就部署完畢了
11、Client端連接
應用層面連接副本集建議使用Connection URI方式, 這樣可以實現自動failover
$mongodb://root:123456@192.168.1.100:27018,192.168.1.101:27018/admin?