热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MongoDB配置主从复制和集群复制的方法

一、主从复制一般数据库都会用到这种最通用的模式——主从模式。这种方式简单灵活,可用于备份、故障恢复,读扩展。为了平衡负载,一般通过读写分离模式,即主库写、从库读。假设我们有两台MongoDB服务器,10.11.20.140和10.11.20.139。如果要配置主从复制

一、主从复制

一般数据库都会用到这种最通用的模式——主从模式。这种方式简单灵活,可用于备份、故障恢复,读扩展。为了平衡负载,一般通过读写分离模式,即主库写、从库读。

假设我们有两台MongoDB服务器,10.11.20.140和10.11.20.139。如果要配置主从复制,可参考如下实现:

Master(10.11.20.140):

Java代码  

port = 27017  

dbpath = /data/db  

logpath = /var/log/mongodb.log  

logappend = true   

journal = true  

pidfile = /var/run/mongodb.pid  

fork = true  

master = true  

注意:

master=true

Slave(10.11.20.139):

Java代码  

port=27017  

dbpath = /data/db  

logpath = /var/log/mongodb.log  

logappend = true   

journal = true  

fork = true  

slave = true  

source = 10.11.20.140:27017  

注意:

slave=true

source=10.11.20.140:27017

上述配置,即可完成Master-Slave

简单测试下,在Master(10.11.20.140)上写数据,在Slave(10.11.20.139)上读出。

Master写入:

mongo 10.11.20.140:27017
MongoDB shell version: 2.0.7
connecting to: 10.11.20.140:27017/test
> db.test.save( { a: 1 } )

Slave 读出:

mongo 10.11.20.139:27017
MongoDB shell version: 2.0.7
connecting to: 10.11.20.139:27017/test
> db.test.find()
{ "_id" : ObjectId("502cccaf2d44738c3b181391"), "a" : 1 }
>

完成主从同步!

注意:如果这是配置了“auth = false”,主从同步可能失败。

二、集群复制

主从复制虽然可以承受一定的负载压力,但这种方式仍然是一个单点,如果主库挂了,数据写入就成了风险。如果,当主库挂掉的时候,可以在访问ip不变的前提下,自动将从库作为主库使用,是不是就能避免这种风险?貌似这又涉及到Linux上的服务KeepAlive等等。

在Mongodb中,提供了一种优于主从模式的集群复制(ReplicateSet)。最理想的模式是,节点之间不分特定的主从。任何一个节点都可以是主节点primary,而其他节点都是secondary,甚至可以通过投票方式选出主节点。

假设我们拥有3台Mongodb,192.168.158.130、192.168.158.131和192.168.158.132。我们希望这3台Mongodb能够构建ReplicateSet模式,可以依照如下操作实现:

1. 配置副本集

假设我们这里的副本集定为snowolf,需要在mongodb配置文件中进行如下配置:

   然后,我们启动这两台Mongodb,查看状态

$ mongo 192.168.158.130  

MongoDB shell version: 2.0.4  

connecting to: 192.168.158.130/test  

> rs.status()  

{  

        "startupStatus" : 3,  

        "info" : "run rs.initiate(...) if not yet done for the set",  

        "errmsg" : "can't get local.system.replset config from self or any seed (EMPTYCONFIG)",  

        "ok" : 0  

}  

>   

    这时候,复制集群还没有达到可用,需要进一步配置。

2. 配置成员

   这里可以在任一节点进行,通过rs.initiate(cfg)完成配置。

   先配置一个中间变量:

> cfg={_id:'snowolf',members:[   

... {_id:0,host:'192.168.158.130:27017'},  

... {_id:1,host:'192.168.158.131:27017'}]  

... }  

{  

        "_id" : "snowolf",  

        "members" : [  

                {  

                        "_id" : 0,  

                        "host" : "192.168.158.130:27017"  

                },  

                {  

                        "_id" : 1,  

                        "host" : "192.168.158.131:27017"  

                }  

        ]  

}  

 接下来,需要让配置生效:

> rs.initiate(cfg)  

{  

        "info" : "Config now saved locally.  Should come online in about a minute.",  

        "ok" : 1  

}  

如果如上所示,说明配置成功。

这时候,再看看当前的状态:

> rs.status()  

{  

        "set" : "snowolf",  

        "date" : ISODate("2013-11-14T08:33:58Z"),  

        "myState" : 1,  

        "members" : [  

                {  

                        "_id" : 0,  

                        "name" : "192.168.158.130:27017",  

                        "health" : 1,  

                        "state" : 1,  

                        "stateStr" : "PRIMARY",  

                        "optime" : {  

                                "t" : 1384417894000,  

                                "i" : 1  

                        },  

                        "optimeDate" : ISODate("2013-11-14T08:31:34Z"),  

                        "self" : true  

                },  

                {  

                        "_id" : 1,  

                        "name" : "192.168.158.131:27017",  

                        "health" : 1,  

                        "state" : 2,  

                        "stateStr" : "SECONDARY",  

                        "uptime" : 137,  

                        "optime" : {  

                                "t" : 1384417894000,  

                                "i" : 1  

                        },  

                        "optimeDate" : ISODate("2013-11-14T08:31:34Z"),  

                        "lastHeartbeat" : ISODate("2013-11-14T08:33:57Z"),  

                        "pingMs" : 348  

                }  

        ],  

        "ok" : 1  

}  

 我们在一开始,并没有强制设定哪个IP是primary节点,哪个是secondary节点。这完全由Mongodb集群来决定。

这时在命令行下,提示符也发生了变化。

Primary节点:

Secondary节点:

别急,这时候还没有大功告成,如果直接在secondary上操作,会发生如下错误:

SECONDARY> db.t.find()  

error: { "$err" : "not master and slaveok=false", "code" : 13435 }  

需要告知Mongodb集群,从哪台机器上进行读操作:

SECONDARY> rs.slaveOk()  

not master and slaveok=false  

 这时就不会有刚才的错误了。

测试:

在primary节点写入操作:

PRIMARY> db.t.insert({uid:12345})  

PRIMARY> db.t.find()  

{ "_id" : ObjectId("52848f782c6dd18b00fdf65d"), "uid" : 12345 }  

 在secondary节点读操作:

SECONDARY> db.t.find()  

{ "_id" : ObjectId("52848f782c6dd18b00fdf65d"), "uid" : 12345 }  

 似乎大功告成,如果这时候我们把primary节点停掉,在secondary节点执行写操作,就会发生如下错误提示:

SECONDARY> db.t.insert({uid:12345})  

not master  

如果只有2台Mongodb,配置复制集群还不够安全,需要1个外在角色调整各个节点的角色。

这些节点包括:

statndard 常规节点,存储一份完整的数据副本,参与投票,可以成为活跃节点,即primary节点

passive 只做存储,参与投票

arbiter 仲裁者只投票,不复制数据,也不能成为活跃节点

现在,我们可以增加一个仲裁节点,只负责仲裁,不做数据存储。

PRIMARY> rs.addArb("192.168.158.132:27017")  

{ "ok" : 1 }  

 这时候,再看各个节点的状态,也发生了变化:

PRIMARY> rs.status()  

{  

        "set" : "snowolf",  

        "date" : ISODate("2013-11-14T09:07:39Z"),  

        "myState" : 1,  

        "members" : [  

                {  

                        "_id" : 0,  

                        "name" : "192.168.158.130:27017",  

                        "health" : 1,  

                        "state" : 2,  

                        "stateStr" : "SECONDARY",  

                        "uptime" : 390,  

                        "optime" : {  

                                "t" : 1384420036000,  

                                "i" : 1  

                        },  

                        "optimeDate" : ISODate("2013-11-14T09:07:16Z"),  

                        "lastHeartbeat" : ISODate("2013-11-14T09:07:39Z"),  

                        "pingMs" : 1  

                },  

                {  

                        "_id" : 1,  

                        "name" : "192.168.158.131:27017",  

                        "health" : 1,  

                        "state" : 1,  

                        "stateStr" : "PRIMARY",  

                        "optime" : {  

                                "t" : 1384420036000,  

                                "i" : 1  

                        },  

                        "optimeDate" : ISODate("2013-11-14T09:07:16Z"),  

                        "self" : true  

                },  

                {  

                        "_id" : 2,  

                        "name" : "192.168.158.132:27017",  

                        "health" : 1,  

                        "state" : 7,  

                        "stateStr" : "ARBITER",  

                        "uptime" : 23,  

                        "optime" : {  

                                "t" : 1384419192000,  

                                "i" : 1  

                        },  

                        "optimeDate" : ISODate("2013-11-14T08:53:12Z"),  

                        "lastHeartbeat" : ISODate("2013-11-14T09:07:38Z"),  

                        "pingMs" : 295147904  

                }  

        ],  

        "ok" : 1  

}  

 如果这时候,我们把primary节点停掉,是否还会影响集群的稳定性?

由于存在arbiter节点,如果primary节点宕掉,剩余的secondary会被选为primary节点,继续提供服务。


推荐阅读
  • 如何在U8系统中连接服务器并获取数据
    本文介绍了如何在U8系统中通过不同的方法连接服务器并获取数据,包括使用MySQL客户端连接实例的方法,如非SSL连接和SSL连接,并提供了详细的步骤和注意事项。 ... [详细]
  • 本文详细介绍了如何搭建一个高可用的MongoDB集群,包括环境准备、用户配置、目录创建、MongoDB安装、配置文件设置、集群组件部署等步骤。特别关注分片、读写分离及负载均衡的实现。 ... [详细]
  • Java虚拟机及其发展历程
    Java虚拟机(JVM)是每个Java开发者日常工作中不可或缺的一部分,但其背后的运作机制却往往显得神秘莫测。本文将探讨Java及其虚拟机的发展历程,帮助读者深入了解这一关键技术。 ... [详细]
  • 随着Linux操作系统的广泛使用,确保用户账户及系统安全变得尤为重要。用户密码的复杂性直接关系到系统的整体安全性。本文将详细介绍如何在CentOS服务器上自定义密码规则,以增强系统的安全性。 ... [详细]
  • 本文介绍了如何使用Node.js通过两种不同的方法连接MongoDB数据库,包括使用MongoClient对象和连接字符串的方法。每种方法都有其特点和适用场景,适合不同需求的开发者。 ... [详细]
  • H5技术实现经典游戏《贪吃蛇》
    本文将分享一个使用HTML5技术实现的经典小游戏——《贪吃蛇》。通过H5技术,我们将探讨如何构建这款游戏的两种主要玩法:积分闯关和无尽模式。 ... [详细]
  • 软件测试行业深度解析:迈向高薪的必经之路
    本文深入探讨了软件测试行业的发展现状及未来趋势,旨在帮助有志于在该领域取得高薪的技术人员明确职业方向和发展路径。 ... [详细]
  • 调试利器SSH隧道
    在开发微信公众号或小程序的时候,由于微信平台规则的限制,部分接口需要通过线上域名才能正常访问。但我们一般都会在本地开发,因为这能快速的看到 ... [详细]
  • PHP面试题精选及答案解析
    本文精选了新浪PHP笔试题及最新的PHP面试题,并提供了详细的答案解析,帮助求职者更好地准备PHP相关的面试。 ... [详细]
  • 一家位于长沙的知名网络安全企业,现面向全国诚聘高级后端开发工程师,特别欢迎具有一线城市经验的技术精英回归故乡,共创辉煌。 ... [详细]
  • 服务器虚拟化存储设计,完美规划储存与资源,部署高性能虚拟化桌面
    规划部署虚拟桌面环境前,必须先估算目前所使用实体桌面环境的工作负载与IOPS性能,并慎选储存设备。唯有谨慎估算贴近实际的IOPS性能,才能 ... [详细]
  • 本文详细介绍如何安装和配置DedeCMS的移动端站点,包括新版本安装、老版本升级、模板适配以及必要的代码修改,以确保移动站点的正常运行。 ... [详细]
  • Asynchronous JavaScript and XML (AJAX) 的流行很大程度上得益于 Google 在其产品如 Google Suggest 和 Google Maps 中的应用。本文将深入探讨 AJAX 在 .NET 环境下的工作原理及其实现方法。 ... [详细]
  • JavaScript 跨域解决方案详解
    本文详细介绍了JavaScript在不同域之间进行数据传输或通信的技术,包括使用JSONP、修改document.domain、利用window.name以及HTML5的postMessage方法等跨域解决方案。 ... [详细]
  • 吴石访谈:腾讯安全科恩实验室如何引领物联网安全研究
    腾讯安全科恩实验室曾两次成功破解特斯拉自动驾驶系统,并远程控制汽车,展示了其在汽车安全领域的强大实力。近日,该实验室负责人吴石接受了InfoQ的专访,详细介绍了团队未来的重点方向——物联网安全。 ... [详细]
author-avatar
江苏蓝凯-我家在装修_708
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有