http://www.sufeinet.com/plugin.php?id=keke_group

苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 8780|回复: 8

[MongoDB] 跟苏飞一起学习MongoDB副本集搭建(一)

[复制链接]
发表于 2014-7-30 14:37:33 | 显示全部楼层 |阅读模式
跟苏飞一起学习MongoDB副本集搭建(一)




    最近这几年,NoSQL数据库已得到了长足的发展,更成为了许多机构追求性能的第一选择,而在这些技术堆栈中,MongoDB无疑是人气最高的一个,
这也是我为什么选择它的原因之一。高效,稳定,安全,不失性能。

    想学习的同者就跟者我一起学习研究吧。


大家都知道NoSQL的产生就是为了解决大数据量、高扩展性、高性能、灵活数据模型、高可用性。但是光通过主从模式的架构远远达不到上面几点,由此MongoDB设计了副本集和分片的功能。这里咱们先不说分片的方向,以后我会专门写文章 说明。这里主要说的就是副本集

mongoDB官方已经不建议使用主从模式了,替代方案是采用副本集的模式,
QQ截图20140730141128.jpg
[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副本集的架构图

QQ截图20140730141531.jpg
由图可以看到客户端连接到整个副本集,不关心具体哪一台机器是否挂掉。主服务器负责整个副本集的读写,副本集定期同步数据备份,一但主节点挂掉,副本节点就会选举一个新的主服务器,这一切对于应用服务器不需要关心。我们看一下主服务器挂掉后的架构:

QQ截图20140730141538.jpg

副本集中的副本节点在主节点挂掉后通过心跳机制检测到后,就会在集群内发起主节点的选举机制,自动选举一位新的主服务器。看起来很牛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(..内容)
空是查看配置的

不过我不喜欢这种方式,我一般会使用有仲裁节点的方法。
看下图片

QQ截图20140730143226.jpg

这样可以减轻主节点的压力,而且他可以维护各个节点之前的关系,有节点出现问题时还可以参与投票

配置的时候只需要将上面的配置简单修改就行了
[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")

好处我就不多说了,负载均衡,故障转移,备份都有了。

本帖被以下淘专辑推荐:



1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2014-7-30 14:42:10 | 显示全部楼层
本帖最后由 佐υ佑 于 2014-7-30 14:44 编辑

沙发沙发,招租。。。哈哈哈,这个数据库最近很火啊
发表于 2014-7-30 14:43:32 | 显示全部楼层
受教了,学习中……
发表于 2014-7-30 14:43:34 | 显示全部楼层
我只是路过看看的。
 楼主| 发表于 2014-7-30 14:47:31 | 显示全部楼层
佐υ佑 发表于 2014-7-30 14:42
沙发沙发,招租。。。哈哈哈,这个数据库最近很火啊

这是必须的,我已经使用很久了,比SQl要强
发表于 2014-7-30 14:48:36 | 显示全部楼层
哈哈,没有接触过,应该搞个从头开始的
 楼主| 发表于 2014-7-30 15:05:36 | 显示全部楼层
inghot 发表于 2014-7-30 14:48
哈哈,没有接触过,应该搞个从头开始的

安装配置的在本分类里也有。你可以看看
发表于 2014-7-30 16:47:50 | 显示全部楼层
先学习学习,研究一下
发表于 2014-7-30 21:04:19 | 显示全部楼层
我只是路过看看的。
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-11-24 08:23

© 2014-2021

快速回复 返回顶部 返回列表