MongoDB复制集简介(一)--初步认识
2013-10-12 10:57
344 查看
在NoSQL数据库中,复制功能是作为一项最基本的特性存在的。复制为数据提供了冗余,提高了数据可用性。在多台服务器拥有相同数据集的情况下,复制可以防止因一台机器故障导致数据丢失。如果拥有相同数据集的服务器分布在不同的数据中心,复制还可以提供灾难备份功能。另外,我们还可以将复制功能用于备份、报表、读写分离场景。
MongoDB作为NoSQL数据库的典型代表,既提供简单的主从式复制,也提供具有灵活的复制集功能。MongoDB复制集具有数据冗余、分离读压力、自动恢复、维护简单、支持灾难恢复等特性。
一、基本概念
主机:从客户端接收所有的写请求,同时在local数据库中oplog.rs文档集中记录所有数据变化日志。一个复制集只能有一个主机。
从机:复制主机的日志并应用到本机数据集上,以保证数据与主机同步。当主机不可用时,复制集自动选择一个从机做主机。
仲裁者:不存储数据,不能成为主机,仅仅用于有偶数个复制集,也仅仅在投票产生主机时发挥作用。
隐藏成员:具有主机数据的完整复制,但是对客户端不可见的成员。隐藏成员优先级为0,不能成为主机,但可以参与投票。
二、复制集常见架构
复制集的架构将直接影响复制集的容量和性能。一个标准的复制集一般为三个成员,具有数据冗余和容错能力,如下图所示。
当然,我们也可以搭建一个只有一个主机、一个从机、一个仲裁者的架构,如下图所示。
考虑复制集中成员个数时,一般需要考虑以下几个因素:
成员个数应为奇数,奇数个成员能够保证复制集选出一个主机。如果成员个数为偶数,应需要增加一个仲裁器。
需要考虑容错性。容错性是指复制集中最多允许几个成员不可用,但是这时复制集依然能够选出主机。拥有不同数量复制集中具有不同的容错性。
为读压力准备专门成员
在考虑成员的分布时,为灾难时能够恢复数据,至少应将一个成员分布在另一个数据中心。当复制集成员分布在多个数据中心时,应保证大多数参与选举主机的成员在一个物理数据中心,以防止网络通讯故障。
三、搭建复制集
1、启动三个节点,复制集名称为test
在shell下执行下面命令启动三个mongod进程
./mongod --dbpath /mongodb/data/db_1 --port 27117 --replSet test --logpath /mongodb/log/mongod_1.log --fork
./mongod --dbpath /mongodb/data/db_2 --port 27217 --replSet test --logpath /mongodb/log/mongod_2.log --fork
./mongod --dbpath /mongodb/data/db_3 --port 27317 --replSet test --logpath /mongodb/log/mongod_3.log --fork
使用命令ps -ef|grep mongodb,得到以下结果,确保三个mongod进程已经启动。
root 2311 1 91 05:42 ? 00:02:37 ./mongod --dbpath /mongodb/data/db_1 --port 27117 --replSet test --logpath /mongodb/log/mongod_1.log --fork
root 3244 1 39 05:44 ? 00:00:08 ./mongod --dbpath /mongodb/data/db_2 --port 27217 --replSet test --logpath /mongodb/log/mongod_2.log --fork
root 3368 1 26 05:44 ? 00:00:02 ./mongod --dbpath /mongodb/data/db_3 --port 27317 --replSet test --logpath /mongodb/log/mongod_3.log --fork
2、 初始化复制集
使用mongo shell工具连接到端口号27117的mongod:
[root@localhost bin]# ./mongo --port 27117
MongoDB shell version: 2.5.2
connecting to: 127.0.0.1:27117/test
>
执行rs.initiate()初始化复制集:
> rs.initiate()
{
"info2" : "no configuration explicitly specified -- making one",
"me" : "localhost.localdomain:27117",
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
test:SECONDARY>
我们注意到执行完rs.initiate后,shell的提示符发生了变化,表示当前shell连接的是test的从机。使用rs.conf()查看复制集当前配置:
test:SECONDARY> rs.conf()
{
"_id" : "test",
"version" : 1,
"members" : [
{
"_id" : 0,
"host" : "localhost.localdomain:27117"
}
]
}
根据rs.conf()的输出看出,当前复制集合只有一个成员,我们使用命令将其他两个成员增加进入复制集:
test:PRIMARY> rs.add("localhost.localdomain:27217")
{ "ok" : 1 }
test:PRIMARY> rs.add("localhost.localdomain:27317")
{ "ok" : 1 }
test:PRIMARY>
我们再使用rs.conf()查看一下复制集的配置,可以看到复制集合的三个成员都已经加入。
test:PRIMARY> rs.conf()
{
"_id" : "test",
"version" : 3,
"members" : [
{
"_id" : 0,
"host" : "localhost.localdomain:27117"
},
{
"_id" : 1,
"host" : "localhost.localdomain:27217"
},
{
"_id" : 2,
"host" : "localhost.localdomain:27317"
}
]
}
我们使用rs.status()查看一下复制集的状态,可以观察到端口号为27117的mongod进程为主机,其他两个为从机。
test:PRIMARY> rs.status()
{
"set" : "test",
"date" : ISODate("2013-10-12T10:16:57Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "localhost.localdomain:27117",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1053,
"optime" : Timestamp(1381572862, 1),
"optimeDate" : ISODate("2013-10-12T10:14:22Z"),
"self" : true
},
{
"_id" : 1,
"name" : "localhost.localdomain:27217",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 167,
"optime" : Timestamp(1381572862, 1),
"optimeDate" : ISODate("2013-10-12T10:14:22Z"),
"lastHeartbeat" : ISODate("2013-10-12T10:16:56Z"),
"lastHeartbeatRecv" : ISODate("2013-10-12T10:16:56Z"),
"pingMs" : 0,
"syncingTo" : "localhost.localdomain:27117"
},
{
"_id" : 2,
"name" : "localhost.localdomain:27317",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 155,
"optime" : Timestamp(1381572862, 1),
"optimeDate" : ISODate("2013-10-12T10:14:22Z"),
"lastHeartbeat" : ISODate("2013-10-12T10:16:57Z"),
"lastHeartbeatRecv" : ISODate("2013-10-12T10:16:56Z"),
"pingMs" : 0,
"syncingTo" : "localhost.localdomain:27117"
}
],
"ok" : 1
}
3、手工控制切换主机
当我们给不同的复制成员设置上优先级后,mongodb复制集将按照优先级的大小顺序选择主机,优先级数字越大,表示越有可能成为主机。我们将端口号为27317的对应成员的优先级设置为3,端口号为27217对应的成员优先级设置为2,端口号27117的对应成员优先级设置为1。
cfg = rs.conf()
cfg.members[0].priority = 1
cfg.members[1].priority = 2
cfg.members[2].priority = 3
rs.reconfig(cfg)
执行rs.status()查看复制集优先级配置变化后的复制集状态,发现端口号为27317的对应成员变为主机了,实现了按照优先级控制主机切换。
rs.status()
{
"set" : "test",
"date" : ISODate("2013-10-12T10:38:02Z"),
"myState" : 2,
"syncingTo" : "localhost.localdomain:27317",
"members" : [
{
"_id" : 0,
"name" : "localhost.localdomain:27117",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2318,
"optime" : Timestamp(1381574271, 1),
"optimeDate" : ISODate("2013-10-12T10:37:51Z"),
"errmsg" : "syncing to: localhost.localdomain:27317",
"self" : true
},
{
"_id" : 1,
"name" : "localhost.localdomain:27217",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 11,
"optime" : Timestamp(1381574271, 1),
"optimeDate" : ISODate("2013-10-12T10:37:51Z"),
"lastHeartbeat" : ISODate("2013-10-12T10:38:01Z"),
"lastHeartbeatRecv" : ISODate("2013-10-12T10:38:01Z"),
"pingMs" : 1,
"lastHeartbeatMessage" : "syncing to: localhost.localdomain:27317",
"syncingTo" : "localhost.localdomain:27317"
},
{
"_id" : 2,
"name" : "localhost.localdomain:27317",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 10,
"optime" : Timestamp(1381574271, 1),
"optimeDate" : ISODate("2013-10-12T10:37:51Z"),
"lastHeartbeat" : ISODate("2013-10-12T10:38:02Z"),
"lastHeartbeatRecv" : ISODate("2013-10-12T10:38:01Z"),
"pingMs" : 0
}
],
"ok" : 1
}
MongoDB作为NoSQL数据库的典型代表,既提供简单的主从式复制,也提供具有灵活的复制集功能。MongoDB复制集具有数据冗余、分离读压力、自动恢复、维护简单、支持灾难恢复等特性。
一、基本概念
主机:从客户端接收所有的写请求,同时在local数据库中oplog.rs文档集中记录所有数据变化日志。一个复制集只能有一个主机。
从机:复制主机的日志并应用到本机数据集上,以保证数据与主机同步。当主机不可用时,复制集自动选择一个从机做主机。
仲裁者:不存储数据,不能成为主机,仅仅用于有偶数个复制集,也仅仅在投票产生主机时发挥作用。
隐藏成员:具有主机数据的完整复制,但是对客户端不可见的成员。隐藏成员优先级为0,不能成为主机,但可以参与投票。
二、复制集常见架构
复制集的架构将直接影响复制集的容量和性能。一个标准的复制集一般为三个成员,具有数据冗余和容错能力,如下图所示。
当然,我们也可以搭建一个只有一个主机、一个从机、一个仲裁者的架构,如下图所示。
考虑复制集中成员个数时,一般需要考虑以下几个因素:
成员个数应为奇数,奇数个成员能够保证复制集选出一个主机。如果成员个数为偶数,应需要增加一个仲裁器。
需要考虑容错性。容错性是指复制集中最多允许几个成员不可用,但是这时复制集依然能够选出主机。拥有不同数量复制集中具有不同的容错性。
成员个数 | 选举主机需要的个数 | 容错性 |
3 | 2 | 1 |
4 | 3 | 1 |
5 | 3 | 2 |
6 | 4 | 2 |
在考虑成员的分布时,为灾难时能够恢复数据,至少应将一个成员分布在另一个数据中心。当复制集成员分布在多个数据中心时,应保证大多数参与选举主机的成员在一个物理数据中心,以防止网络通讯故障。
三、搭建复制集
1、启动三个节点,复制集名称为test
在shell下执行下面命令启动三个mongod进程
./mongod --dbpath /mongodb/data/db_1 --port 27117 --replSet test --logpath /mongodb/log/mongod_1.log --fork
./mongod --dbpath /mongodb/data/db_2 --port 27217 --replSet test --logpath /mongodb/log/mongod_2.log --fork
./mongod --dbpath /mongodb/data/db_3 --port 27317 --replSet test --logpath /mongodb/log/mongod_3.log --fork
使用命令ps -ef|grep mongodb,得到以下结果,确保三个mongod进程已经启动。
root 2311 1 91 05:42 ? 00:02:37 ./mongod --dbpath /mongodb/data/db_1 --port 27117 --replSet test --logpath /mongodb/log/mongod_1.log --fork
root 3244 1 39 05:44 ? 00:00:08 ./mongod --dbpath /mongodb/data/db_2 --port 27217 --replSet test --logpath /mongodb/log/mongod_2.log --fork
root 3368 1 26 05:44 ? 00:00:02 ./mongod --dbpath /mongodb/data/db_3 --port 27317 --replSet test --logpath /mongodb/log/mongod_3.log --fork
2、 初始化复制集
使用mongo shell工具连接到端口号27117的mongod:
[root@localhost bin]# ./mongo --port 27117
MongoDB shell version: 2.5.2
connecting to: 127.0.0.1:27117/test
>
执行rs.initiate()初始化复制集:
> rs.initiate()
{
"info2" : "no configuration explicitly specified -- making one",
"me" : "localhost.localdomain:27117",
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
test:SECONDARY>
我们注意到执行完rs.initiate后,shell的提示符发生了变化,表示当前shell连接的是test的从机。使用rs.conf()查看复制集当前配置:
test:SECONDARY> rs.conf()
{
"_id" : "test",
"version" : 1,
"members" : [
{
"_id" : 0,
"host" : "localhost.localdomain:27117"
}
]
}
根据rs.conf()的输出看出,当前复制集合只有一个成员,我们使用命令将其他两个成员增加进入复制集:
test:PRIMARY> rs.add("localhost.localdomain:27217")
{ "ok" : 1 }
test:PRIMARY> rs.add("localhost.localdomain:27317")
{ "ok" : 1 }
test:PRIMARY>
我们再使用rs.conf()查看一下复制集的配置,可以看到复制集合的三个成员都已经加入。
test:PRIMARY> rs.conf()
{
"_id" : "test",
"version" : 3,
"members" : [
{
"_id" : 0,
"host" : "localhost.localdomain:27117"
},
{
"_id" : 1,
"host" : "localhost.localdomain:27217"
},
{
"_id" : 2,
"host" : "localhost.localdomain:27317"
}
]
}
我们使用rs.status()查看一下复制集的状态,可以观察到端口号为27117的mongod进程为主机,其他两个为从机。
test:PRIMARY> rs.status()
{
"set" : "test",
"date" : ISODate("2013-10-12T10:16:57Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "localhost.localdomain:27117",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1053,
"optime" : Timestamp(1381572862, 1),
"optimeDate" : ISODate("2013-10-12T10:14:22Z"),
"self" : true
},
{
"_id" : 1,
"name" : "localhost.localdomain:27217",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 167,
"optime" : Timestamp(1381572862, 1),
"optimeDate" : ISODate("2013-10-12T10:14:22Z"),
"lastHeartbeat" : ISODate("2013-10-12T10:16:56Z"),
"lastHeartbeatRecv" : ISODate("2013-10-12T10:16:56Z"),
"pingMs" : 0,
"syncingTo" : "localhost.localdomain:27117"
},
{
"_id" : 2,
"name" : "localhost.localdomain:27317",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 155,
"optime" : Timestamp(1381572862, 1),
"optimeDate" : ISODate("2013-10-12T10:14:22Z"),
"lastHeartbeat" : ISODate("2013-10-12T10:16:57Z"),
"lastHeartbeatRecv" : ISODate("2013-10-12T10:16:56Z"),
"pingMs" : 0,
"syncingTo" : "localhost.localdomain:27117"
}
],
"ok" : 1
}
3、手工控制切换主机
当我们给不同的复制成员设置上优先级后,mongodb复制集将按照优先级的大小顺序选择主机,优先级数字越大,表示越有可能成为主机。我们将端口号为27317的对应成员的优先级设置为3,端口号为27217对应的成员优先级设置为2,端口号27117的对应成员优先级设置为1。
cfg = rs.conf()
cfg.members[0].priority = 1
cfg.members[1].priority = 2
cfg.members[2].priority = 3
rs.reconfig(cfg)
执行rs.status()查看复制集优先级配置变化后的复制集状态,发现端口号为27317的对应成员变为主机了,实现了按照优先级控制主机切换。
rs.status()
{
"set" : "test",
"date" : ISODate("2013-10-12T10:38:02Z"),
"myState" : 2,
"syncingTo" : "localhost.localdomain:27317",
"members" : [
{
"_id" : 0,
"name" : "localhost.localdomain:27117",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2318,
"optime" : Timestamp(1381574271, 1),
"optimeDate" : ISODate("2013-10-12T10:37:51Z"),
"errmsg" : "syncing to: localhost.localdomain:27317",
"self" : true
},
{
"_id" : 1,
"name" : "localhost.localdomain:27217",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 11,
"optime" : Timestamp(1381574271, 1),
"optimeDate" : ISODate("2013-10-12T10:37:51Z"),
"lastHeartbeat" : ISODate("2013-10-12T10:38:01Z"),
"lastHeartbeatRecv" : ISODate("2013-10-12T10:38:01Z"),
"pingMs" : 1,
"lastHeartbeatMessage" : "syncing to: localhost.localdomain:27317",
"syncingTo" : "localhost.localdomain:27317"
},
{
"_id" : 2,
"name" : "localhost.localdomain:27317",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 10,
"optime" : Timestamp(1381574271, 1),
"optimeDate" : ISODate("2013-10-12T10:37:51Z"),
"lastHeartbeat" : ISODate("2013-10-12T10:38:02Z"),
"lastHeartbeatRecv" : ISODate("2013-10-12T10:38:01Z"),
"pingMs" : 0
}
],
"ok" : 1
}
相关文章推荐
- PHP添加yaf xhprof mongodb 同理
- mongodb安装
- php对mongodb的扩展(初出茅庐)
- 作为PHP程序员应该了解MongoDB的五件事
- 基于MySQL到MongoDB简易对照表的详解
- MongoDB为用户设置访问权限
- mongodb与mysql命令详细对比
- MongoDB 语法使用小结
- mongodb在windows下的安装步骤分享
- 关于C#生成MongoDB中ObjectId的实现方法
- MongoDB 快速入门
- MongoDB学习笔记(三) 在MVC模式下通过Jqgrid表格操作MongoDB数据
- MongoDB 内存使用情况分析
- PHP操作MongoDB时的整数问题及对策说明
- PHP与MongoDB简介|安全|M+PHP应用实例详解
- MongoDB学习笔记(四) 用MongoDB的文档结构描述数据关系
- MongoDB学习笔记(五) MongoDB文件存取操作
- PHP对MongoDB[NoSQL]数据库的操作
- MySQL和MongoDB设计实例对比分析
- MongoDB常用命令小结