搭建一個MongoDB副本集系統(tǒng)

在任何服務系統(tǒng)中,要提供系統(tǒng)服務高可用,必須要解決單點故障及實現(xiàn)故障自動轉(zhuǎn)移。mongodb的副本集提供了這樣的功能,副本集由多個mongodb實例組成,其中一個為主,其他為從,解決了單點故障。另外主實例無法服務時,mongodb會重新選舉主實例進行故障轉(zhuǎn)移。

一、mongodb實例啟動準備

下載解壓

cd /usr/local
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.4.6.tgz
tar -xvf mongodb-linux-x86_64-3.4.6.tgz
mv mongodb-linux-x86_64-3.4.6  mongodb

設置環(huán)境

vim /etc/profile

export MONGODB_HOME=/usr/local/mongodb
export PATH=$MONGODB/bin:$PATH

source /etc/profile

由于這里搭建mongodb副本集,所以至少需要三個mongodb實例,兩個數(shù)據(jù)實例,一個仲裁實例,首先創(chuàng)建三個數(shù)據(jù)目錄

mkdir  -p /data/mongodb1
mkdir  -p /data/mongodb1/{log,conf}
touch  /data/mongodb1/log/mongodb.log


mkdir  -p /data/mongodb2
mkdir  -p /data/mongodb2/{log,conf}
touch  /data/mongodb2/log/mongodb.log

mkdir  -p /data/mongodb3
mkdir  -p /data/mongodb3/{log,conf}
touch  /data/mongodb3/log/mongodb.log

創(chuàng)建配置文件,配置文件放在/data/mongodb1/conf/目錄下,文件名為mongodb.conf,配置如下:

dbpath=/data/mongodb1
logpath=/data/mongodb1/log/mongodb.log
logappend=true
noprealloc=true
port=27011
fork=true
replSet=test

其他兩個實例配置文件內(nèi)容和位置一樣,修改目錄和端口就可以了,其他兩個實例端口分別為:27012、27013。其中,replSet參數(shù)表示副本集名,三個實例必須配置一致。

二、啟動實例

執(zhí)行下面命令啟動三個實例

mongod  -f  /data/mongodb1/conf/mongodb.conf
mongod  -f  /data/mongodb2/conf/mongodb.conf
mongod  -f  /data/mongodb3/conf/mongodb.conf

三個實例啟動成功后,不代表副本集已經(jīng)搭建成功了,還需要進行副本集初始化。

三、初始化副本集

連接任何一個實例進行初始化

mongo --port 27011

use admin
config={
    _id:'test',
    members:[
        {_id:1, host:'localhost:27011',priority:2},
        {_id:2, host:'localhost:27012',priority:1},
        {_id:3, host:'localhost:27013',arbiterOnly:true}
    ]
}

rs.initiate(config)

上面執(zhí)行成功后,可以使用rs.status()查看副本集當前狀態(tài)。

上面配置文件中,_id:'test'表示副本集名稱,與前面mongodb.conf配置文件中的replSet參數(shù)配置的名稱要一致。

priority:2表示優(yōu)先級,優(yōu)先級越高,副本集初始化時會選舉為主。arbiterOnly:true表示該實例為仲裁節(jié)點,不存儲數(shù)據(jù),只參與投票。

四、創(chuàng)建管理員用戶和讀寫用戶

連接到主實例,創(chuàng)建用戶

mongo --port 27011 

use admin

db.createUser({
    user:'dba',
    pwd:'dba',
    roles:[{role:"userAdminAnyDatabase", db:"admin"}, {role:"readWriteAnyDatabase", db:"admin"}]
})

db.createUser({
    user:'rd',
    pwd:'rd',
    roles:[{role:'readWrite', db:'test'}]
})

創(chuàng)建好后,可以使用show users查看所有創(chuàng)建的用戶信息

五、為副本集增加權(quán)限認證

副本集采用keyfile文件來實現(xiàn)權(quán)限認證,并且副本集中的所有成員使用的keyfile必須一樣。

# 生成keyfile文件
openssl rand -base64 90 > /data/mongodb1/conf/keyfile

cp /data/mongodb1/conf/keyfile  /data/mongodb2/conf/keyfile
cp /data/mongodb1/conf/keyfile  /data/mongodb3/conf/keyfile

另外需要注意,keyfile文件權(quán)限必須是X00,也就是說,不能給group和other成員分配任何權(quán)限,否則實例無法啟動。

chmod 400 /data/mongodb1/conf/keyfile
chmod 400 /data/mongodb2/conf/keyfile
chmod 400 /data/mongodb3/conf/keyfile

生成好keyfile之后,將keyfile寫入mongodb.conf配置文件中,在mongodb.conf配置文件中增加如下配置:

keyFile=/data/mongodb1/conf/keyfile

其他實例做同樣修改,重啟所有實例。
在配置文件中開啟了keyFile,就不需要開啟auth認證,因為開啟keyFile,就默認開啟了auth。

六、驗證

連接主實例

mongo --port 27011
查看當前數(shù)據(jù)庫

發(fā)現(xiàn)沒有權(quán)限執(zhí)行,使用db.auth('dba', 'dba')進行權(quán)限認證,再次執(zhí)行就可以查看了。

認證后查看

創(chuàng)建一個數(shù)據(jù)庫test,然后寫入一些數(shù)據(jù)。

寫入數(shù)據(jù)

退出客戶端重新連接,不認證無法進行數(shù)據(jù)庫讀寫操作。

重新連接

下面使用前面創(chuàng)建的rd讀寫用戶來認證,發(fā)現(xiàn)認證失敗。這是因為,rd用戶是在admin庫下面創(chuàng)建,所以必須要到admin庫下面認證,mongodb下的用戶是隨著庫走的。

下面連接到從實例上面,雖然用戶已經(jīng)認證可以了,但無法查看數(shù)據(jù)。

從實例操作

這是因為mongodb默認是從主節(jié)點讀寫數(shù)據(jù)的,副本節(jié)點上不允許讀(更不能寫入),但可以設置副本節(jié)點可以讀,使用db.getMongo().setSlaveOk()命令就可以了。

設置從可讀

七、PHP實現(xiàn)

首先連接主實例,在test庫下面創(chuàng)建一個讀寫用戶

# 登錄管理員權(quán)限
use admin
db.auth('dba', 'dba')

# 切換到test庫下創(chuàng)建用戶
use test
db.createUser({
    user:'test',
    pwd:'test',
    roles:[{role:'readWrite', db:'test'}]
})
創(chuàng)建新用戶

php代碼如下:

<?php

$m = new MongoClient(
    "mongodb://test:test@192.168.99.100:27012,192.168.99.100:27011/test", 
    array(
        'connectTimeoutMS' => 100, 
        'readPreference' =>  MongoClient::RP_PRIMARY_PREFERRED,
    )
);

$db = $m->test; 
$collection = $db->person;

$collection->insert(array(
    'name' => 'li',
    'age'  => 22,
));

$cursor = $collection->find();

foreach ($cursor as $document) {
    var_dump($document);
}

執(zhí)行結(jié)果

執(zhí)行結(jié)果

最后,副本集的故障轉(zhuǎn)移可以自行驗證下。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容