MongoDB 复制集(Replica Set)搭建

通常,为了防止单点故障应用程序需要做集群。然而在数据库中除了防止单点故障,还需要做到数据库备份,读写分离,故障转移等。而 MongoDB 的 Replica Set 恰恰都能满足这些要求。

复制集成员

Replica Set 的成员是一堆有着同样的数据内容 mongod 的实例集合,包含以下三类角色:

  1. 主节点(Primary)
    是 Replica Set 中唯一的接收写请求的节点,并将写入指令记录到 oplog 上。副本节点通过复制 oplog 的写入指令同步主节点的数据。Secondary。一个 Replica Set 有且只有Primary 节点,当Primar挂掉后,其他 Secondary 或者 Arbiter 节点会重新选举出来一个主节点。应用程序的默认读取请求也是发到 Primary节点处理的。

  2. 副本节点(Secondary)
    通过复制主节点 oplog 中的指令与主节点保持同样的数据集,当主节点挂掉的时候,参与主节点选举。

  3. 仲裁者(Arbiter)
    不存储实际应用数据,只投票参与选取主节点,但不会被选举成为主节点。

复制集搭建(3个成员)

  1. 节点目录结构说明


    节点目录结构

    其中,instance 、instance_1、instance_2 分别代表3个节点。每个节点都有相同的目录结构,包含了数据目录 data ,日志目录 logs , JavaScript 文件目录 js, 启停脚本 mongod-server.sh,节点配置文件 mongod.conf 等

  2. 节点配置文件 mongod.conf

# syslog配置
logpath=/mnt/mongodb/instance/logs/mongod.log #日志目录
logappend=true
timeStampFormat=iso8601-utc
# storage 存储配置
dbpath=/mnt/mongodb/instance/data/db #数据存储目录
directoryperdb=true
# processManagement 进程管理配置
fork=true
pidfilepath=/mnt/mongodb/instance/var/run/mongod.pid # 进程 PID 文件保存目录
# net 网络配置
bind_ip=127.0.0.1
port=27017 
# security 配置
#auth=true
# 复制集
replSet=test-set    # 复制集 name         

其中 logpath 、dbpath、 pidfilepath 需要根据节点修改到对应目录(路径中的instance 改为 instance_1或 instance_2)。此外还需要修改每个节点的 port,在我的配置当中,instance 、instance_1、instance_2 的端口分别为 27017、27018、27019。

  1. 启动三个节点
    这里启动需要用到上面提到的 mongod-server.sh 服务启停脚本(这个脚本是我自己编写的用于管理 mongod 进程启停,详细了解猛戳这里
    分别在 instance、instance_1、 instance_2 目录中执行一下命令./mongod-server.sh start
[root@iZu1qhttxe5Z instance]# ls
data  dump  js  logs  mongod.conf  mongod-server.sh  var
[root@iZu1qhttxe5Z instance]# ./mongod-server.sh start
about to fork child process, waiting until server is ready for connections.
forked process: 680
child process started successfully, parent exiting
Started [680]
[root@iZu1qhttxe5Z instance]# 

这个时候3个节点已经启动了,接下来需要初始化复制集。

  1. 初始化复制集
    选择任意的节点,进入 js 目录:
[root@iZu1qhttxe5Z js]$ ls
initiate_rs.js  user.js
[root@iZu1qhttxe5Z js]# cat initiate_rs.js 
rs.initiate()
rs.add("iZu1qhttxe5Z:27017")
rs.add("iZu1qhttxe5Z:27019")
rs.conf()
[root@iZu1qhttxe5Z js]# 

这里的 initiate_rs.js 文件适用于初始化复制集的js文件,其实这些操作可以在 mongo shell中操作,但是为了方便运维管理,所以将此操作提取到 js 文件(如何将 mongo shell 命令提出到 js 文件猛戳这里)。

执行初始化,这里选取端口 27018 的节点。

[root@iZu1qhttxe5Z instance_1]# mongo --port 27018 ./js/initiate_rs.js 
MongoDB shell version v3.4.5
connecting to: mongodb://127.0.0.1:27018/
MongoDB server version: 3.4.5
[root@iZu1qhttxe5Z instance_1]# 

连接到其中一个节点,查看是否初始化成功

test-set:SECONDARY> rs.status()
{
    "set" : "test-set",
    "date" : ISODate("2017-06-28T02:57:33.424Z"),
    ......
    },
    "members" : [
        {
            "_id" : 0,
            "name" : "10.117.225.127:27018",
            ...........
            "stateStr" : "SECONDARY",
            ...........
        },
        {
            "_id" : 1,
            "name" : "iZu1qhttxe5Z:27017",
            .............
            "stateStr" : "PRIMARY",
            ..............
        },
        {
            "_id" : 2,
            "name" : "iZu1qhttxe5Z:27019",
            .........
            "stateStr" : "SECONDARY",
            .........
        }
    ],
    "ok" : 1
}
test-set:SECONDARY> 

可以看出复制集已经初始化成功。

  1. 连接Primary节点,写入数据。
test-set:PRIMARY> use test
switched to db test
test-set:PRIMARY> show collections
test-set:PRIMARY> db.test.insert({"name":"knight"});
WriteResult({ "nInserted" : 1 })
test-set:PRIMARY> show collections
test
test-set:PRIMARY> db.test.find()
{ "_id" : ObjectId("59531cd6000e29eae22a2f83"), "name" : "knight" }
test-set:PRIMARY> 

数据插入成功,验证 SECONDARY 是否同步数据

# 27018 节点
[root@iZu1qhttxe5Z js]# mongo --port 27018
MongoDB shell version v3.4.5
connecting to: mongodb://127.0.0.1:27018/
MongoDB server version: 3.4.5
....
test-set:SECONDARY>
test-set:SECONDARY> rs.slaveOk()
test-set:SECONDARY> use test
switched to db test
test-set:SECONDARY> show collections
test
test-set:SECONDARY> db.test.find()
{ "_id" : ObjectId("59531cd6000e29eae22a2f83"), "name" : "knight" }
test-set:SECONDARY> 
[root@iZu1qhttxe5Z js]#
[root@iZu1qhttxe5Z js]#
[root@iZu1qhttxe5Z js]#
# 27019 节点
[root@iZu1qhttxe5Z js]# mongo --port 27019
MongoDB shell version v3.4.5
connecting to: mongodb://127.0.0.1:27019/
MongoDB server version: 3.4.5
....
test-set:SECONDARY> rs.slaveOk()
test-set:SECONDARY> use test
switched to db test
test-set:SECONDARY> db.test.find()
{ "_id" : ObjectId("59531cd6000e29eae22a2f83"), "name" : "knight" }
test-set:SECONDARY> 
  1. 默认情况下,Secondary不能读和写, 需要执行 rs.slaveOk()(或者执行db.getMongo().setSlaveOk())。
test-set:SECONDARY> use test
switched to db test
test-set:SECONDARY> db.test.find()
Error: error: {
    "ok" : 0,
    "errmsg" : "not master and slaveOk=false",
    "code" : 13435,
    "codeName" : "NotMasterNoSlaveOk"
}
test-set:SECONDARY> 

References:

MongoDB 执行 js 文件
MongoDB 启停脚本

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

推荐阅读更多精彩内容