搭建一个MongoDB副本集系统

在任何服务系统中,要提供系统服务高可用,必须要解决单点故障及实现故障自动转移。mongodb的副本集提供了这样的功能,副本集由多个mongodb实例组成,其中一个为主,其他为从,解决了单点故障。另外主实例无法服务时,mongodb会重新选举主实例进行故障转移。

一、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

设置环境

vim /etc/profile

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

source /etc/profile

由于这里搭建mongodb副本集,所以至少需要三个mongodb实例,两个数据实例,一个仲裁实例,首先创建三个数据目录

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

创建配置文件,配置文件放在/data/mongodb1/conf/目录下,文件名为mongodb.conf,配置如下:

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

其他两个实例配置文件内容和位置一样,修改目录和端口就可以了,其他两个实例端口分别为:27012、27013。其中,replSet参数表示副本集名,三个实例必须配置一致。

二、启动实例

执行下面命令启动三个实例

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

三个实例启动成功后,不代表副本集已经搭建成功了,还需要进行副本集初始化。

三、初始化副本集

连接任何一个实例进行初始化

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)

上面执行成功后,可以使用rs.status()查看副本集当前状态。

上面配置文件中,_id:'test'表示副本集名称,与前面mongodb.conf配置文件中的replSet参数配置的名称要一致。

priority:2表示优先级,优先级越高,副本集初始化时会选举为主。arbiterOnly:true表示该实例为仲裁节点,不存储数据,只参与投票。

四、创建管理员用户和读写用户

连接到主实例,创建用户

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'}]
})

创建好后,可以使用show users查看所有创建的用户信息

五、为副本集增加权限认证

副本集采用keyfile文件来实现权限认证,并且副本集中的所有成员使用的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文件权限必须是X00,也就是说,不能给group和other成员分配任何权限,否则实例无法启动。

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
查看当前数据库

发现没有权限执行,使用db.auth('dba', 'dba')进行权限认证,再次执行就可以查看了。

认证后查看

创建一个数据库test,然后写入一些数据。

写入数据

退出客户端重新连接,不认证无法进行数据库读写操作。

重新连接

下面使用前面创建的rd读写用户来认证,发现认证失败。这是因为,rd用户是在admin库下面创建,所以必须要到admin库下面认证,mongodb下的用户是随着库走的。

下面连接到从实例上面,虽然用户已经认证可以了,但无法查看数据。

从实例操作

这是因为mongodb默认是从主节点读写数据的,副本节点上不允许读(更不能写入),但可以设置副本节点可以读,使用db.getMongo().setSlaveOk()命令就可以了。

设置从可读

七、PHP实现

首先连接主实例,在test库下面创建一个读写用户

# 登录管理员权限
use admin
db.auth('dba', 'dba')

# 切换到test库下创建用户
use test
db.createUser({
    user:'test',
    pwd:'test',
    roles:[{role:'readWrite', db:'test'}]
})
创建新用户

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);
}

执行结果

执行结果

最后,副本集的故障转移可以自行验证下。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容