- 积分
- 40165
- 好友
- 记录
- 主题
- 帖子
- 听众
- 收听
|
跟苏飞一起学习MongoDB副本集搭建(一)
最近这几年,NoSQL数据库已得到了长足的发展,更成为了许多机构追求性能的第一选择,而在这些技术堆栈中,MongoDB无疑是人气最高的一个,这也是我为什么选择它的原因之一。高效,稳定,安全,不失性能。
想学习的同者就跟者我一起学习研究吧。
大家都知道NoSQL的产生就是为了解决大数据量、高扩展性、高性能、灵活数据模型、高可用性。但是光通过主从模式的架构远远达不到上面几点,由此MongoDB设计了副本集和分片的功能。这里咱们先不说分片的方向,以后我会专门写文章 说明。这里主要说的就是副本集
mongoDB官方已经不建议使用主从模式了,替代方案是采用副本集的模式,
[C#] 纯文本查看 复制代码 Replica sets replace master-slave replication for most use cases. If possible, use replica sets rather than master-slave replication for all new production deployments. This documentation remains to support legacy deployments and for archival purposes only.
主从模式其实就是一个单副本的应用,没有很好的扩展性和容错性。而副本集具有多个副本保证了容错性,就算一个副本挂掉了还有很多副本存在,
并且解决了上面第一个问题“主节点挂掉了,整个集群内会自动切换”。难怪mongoDB官方推荐使用这种模式。我们来看看mongoDB副本集的架构图
由图可以看到客户端连接到整个副本集,不关心具体哪一台机器是否挂掉。主服务器负责整个副本集的读写,副本集定期同步数据备份,一但主节点挂掉,副本节点就会选举一个新的主服务器,这一切对于应用服务器不需要关心。我们看一下主服务器挂掉后的架构:
副本集中的副本节点在主节点挂掉后通过心跳机制检测到后,就会在集群内发起主节点的选举机制,自动选举一位新的主服务器。看起来很牛X的样子,我们赶紧操作部署一下!
官方推荐的副本集机器数量为至少3个,那我们也按照这个数量配置测试。 1、准备三台机器 192.168.18.10、192.168.18.11、192.168.18.12。 192.168.18.10当作副本集主节点, 192.168.18.11、192.168.18.12作为副本集副本节点。 2、分别在每台机器上建立mongodb副本集测试文件夹 [C#] 纯文本查看 复制代码 #存放整个mongodb文件
mkdir -p /data/mongodbtest/replset
#存放mongodb数据文件
mkdir -p /data/mongodbtest/replset/data
#进入mongodb文件夹
cd /data/mongodbtest
我用的是从这里下载的最新版,大家也可以去下载 http://www.mongodb.org/downloads 然后分别启动就行了 [Shell] 纯文本查看 复制代码 E:\mongodb\mongodb\mongod.exe --port 27017 --dbpath E:\mongodb\data --replSet mongolist 大家看到了比着普通 的启动多了一个项 [Shell] 纯文本查看 复制代码 --replSet mongolist 大家记住这就是以副本集的方式启动,也只有加入这一句的Mongodb实例才能应用到副本集当中来。 mongolist 就是副本集的名称, 其他两台服务器也是以同样的方式启动。 然后我们把他们连接在一起 我们随便进入任意一个Mongodb。 然后选择Admin数据库, 注意这时候这三个实例不要有任何数据,和账户之类的,这些都要在副本集配置好之后在主节点上建立 然后执行如下命令 [Shell] 纯文本查看 复制代码 rs.initiate({
_id: "mongolist",
members: [
{
_id: 0,
host: "192.168.18.10:27017",
priority :5
},
{
_id: 1,
host: "192.168.18.11:27017",
priority: 2
},
{
_id: 2,
host: "192.168.18.12:27017",
priority: 2 //权重值1到10越大成为主节点的机会就越大
}
]
}) 这样就是把三个数据实搞成了。副本集了,就这么简单。 如果运行成功 的话一会儿会有提示,然后大家执行 [Shell] 纯文本查看 复制代码 rs.status()
如下 [Shell] 纯文本查看 复制代码 {
"set" : "repset",
"date" : ISODate("2014-07-30T14:33:21Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "192.168.18.12:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1682,
"optime" : Timestamp(1388319973, 1),
"optimeDate" : ISODate("2014-07-30T14:33:21Z"),
"lastHeartbeat" : ISODate("2014-07-30T14:33:21Z"),
"lastHeartbeatRecv" : ISODate("2014-07-30T14:33:21Z"),
"pingMs" : 1,
"syncingTo" : "192.168.1.138:27017"
},
{
"_id" : 1,
"name" : "192.168.18.11:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1682,
"optime" : Timestamp(1388319973, 1),
"optimeDate" : ISODate("2014-07-30T14:33:21Z"),
"lastHeartbeat" : ISODate("2014-07-30T14:33:21Z"),
"lastHeartbeatRecv" : ISODate("2014-07-30T14:33:21Z"),
"pingMs" : 1,
"syncingTo" : "192.168.1.138:27017"
},
{
"_id" : 2,
"name" : "192.168.18.10:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2543,
"optime" : Timestamp(1388973, 1),
"optimeDate" : ISODate("2014-07-30T14:33:21Z"),
"self" : true
}
],
"ok" : 1
}
要修改配置就执行 [Shell] 纯文本查看 复制代码 rs.config(..内容) 空是查看配置的
不过我不喜欢这种方式,我一般会使用有仲裁节点的方法。 看下图片
这样可以减轻主节点的压力,而且他可以维护各个节点之前的关系,有节点出现问题时还可以参与投票
配置的时候只需要将上面的配置简单修改就行了 [Shell] 纯文本查看 复制代码 rs.initiate({
_id: "mongolist",
members: [
{
_id: 0,
host: "192.168.18.10:27017",
priority :5
},
{
_id: 1,
host: "192.168.18.11:27017",
arbiterOnly : true
},
{
_id: 2,
host: "192.168.18.12:27017",
priority: 2 //权重值1到10越大成为主节点的机会就越大
}
]
}) arbiterOnly : true就是表示为仲裁节点 我们后期也是可以添加的。
其中的仲裁节点不存储数据,只是负责故障转移的群体投票,这样就少了数据复制的压力。是不是想得很周到啊,一看mongodb的开发兄弟熟知大数据架构体系,其实不只是主节点、副本节点、仲裁节点,还有Secondary-Only、Hidden、Delayed、Non-Voting。 Secondary-Only:不能成为primary节点,只能作为secondary副本节点,防止一些性能不高的节点成为主节点。
Hidden:这类节点是不能够被客户端制定IP引用,也不能被设置为主节点,但是可以投票,一般用于备份数据。
Delayed:可以指定一个时间延迟从primary节点同步数据。主要用于备份数据,如果实时同步,误删除数据马上同步到从节点,恢复又恢复不了。
Non-Voting:没有选举权的secondary节点,纯粹的备份数据节点。 到此整个mongodb副本集搞定了两个问题: - 主节点挂了能否自动切换连接?目前需要手工切换。
- 主节点的读写压力过大如何解决?
还有这两个问题后续解决: - 从节点每个上面的数据都是对数据库全量拷贝,从节点压力会不会过大?
- 数据压力大到机器支撑不了的时候能否做到自动扩展?
做了副本集发现又一些问题: - 副本集故障转移,主节点是如何选举的?能否手动干涉下架某一台主节点。
- 官方说副本集数量最好是奇数,为什么?
- mongodb副本集是如何同步的?如果同步不及时会出现什么情况?会不会出现不一致性?
- mongodb的故障转移会不会无故自动发生?什么条件会触发?频繁触发可能会带来系统负载加重
下面一起看一下怎么使用C#程序来访问吧。
其实不需要写什么特别的代码,还是咱们以后的代码不需要动。
只需要配置一下连接字符串就行了。
[HTML] 纯文本查看 复制代码 mongodb://192.168.18.10:27017,192.168.18.11:27017,192.168.18.12:27017/?connect=replicaSet;replicaSet=mongolist;readPreference=SecondaryPreferred;connectTimeout=30s;maxPoolSize=200
关于这里的介绍大家可以看我的文章 http://www.sufeinet.com/thread-9551-1-1.html
readPreference有几种连接的模式参考文章
我们先来看看这个对象的说明
[C#] 纯文本查看 复制代码 // 摘要:
// Represents read preference modes.
public enum ReadPreferenceMode
{
// 默认参数,只从主节点上进行读取操作;
Primary = 0,
// 大部分从主节点上读取数据,只有主节点不可用时从secondary节点读取数据。
PrimaryPreferred = 1,
// 只从secondary节点上进行读取操作,存在的问题是secondary节点的数据会比primary节点数据“旧”。
Secondary = 2,
// 优先从secondary节点进行读取操作,secondary节点不可用时从主节点读取数据;
SecondaryPreferred = 3,
// 不管是主节点、secondary节点,从网络延迟最低的节点上读取数据。
Nearest = 4,
}
应用方法[C#] 纯文本查看 复制代码 switch (strReadPreference)
{
case "Nearest":
set.ReadPreference = new ReadPreference(ReadPreferenceMode.Nearest); //优先读取secondary 不存在时读取primary
break;
case "Primary":
set.ReadPreference = new ReadPreference(ReadPreferenceMode.Primary);
break;
case "PrimaryPreferred":
set.ReadPreference = new ReadPreference(ReadPreferenceMode.PrimaryPreferred);
break;
case "Secondary":
set.ReadPreference = new ReadPreference(ReadPreferenceMode.Secondary);
break;
case "SecondaryPreferred":
set.ReadPreference = new ReadPreference(ReadPreferenceMode.SecondaryPreferred);
break;
default:
set.ReadPreference = new ReadPreference(ReadPreferenceMode.Nearest); //优先读取secondary 不存在时读取primary
break;
}
好了就这么多,大家根据需要选择吧。
如果要添加节点就使用 [Shell] 纯文本查看 复制代码 rs.add("192.168.18.99:27017",false) 默认是FAlse 如果设置为TRue表示是仲裁节点这点大家注意 一个副本集里只能有一个仲裁服务器。 如果要删除就这样 [Shell] 纯文本查看 复制代码 rs.remove("192.168.18.99:27017")
好处我就不多说了,负载均衡,故障转移,备份都有了。 |
|