Mongodb副本集实现-创新互联

寿宁ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为成都创新互联公司的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18980820575(备注:SSL证书合作)期待与您的合作!

MongoDB副本集概述

以下图片摘自MongoDB官方文档:http://docs.mongodb.org/manual/core/replication-introduction/

Mongodb副本集实现

Primary节点接收客户端所有的写操作,整个副本集只会有一个primary节点。MongoDB副本集提供严格的一致性。主节点将所有的操作写入一个叫oplog的capped collection(这个collection的大小一般为磁盘剩余空间的5%,不同的系统可能不一样,详见http://docs.mongodb.org/manual/core/replica-set-oplog/)中,secondary节点通过复制oplog并执行oplog中的所有操作,因为对oplog的执行是幂等的,所以secondary节点上的数据可以保持和primary节点一样,当然这有一个“追赶”(catch up)的过程,会存在一定的落后(Lag)有时候因为网络延迟或宕机导致从节点永远赶不上主节点,这时候需要采取人为的干预了(后面会说到Resyncing Member of Replica Set)。

Mongodb副本集实现

默认所有的读操作也是走的primary节点,当然客户端可以选择从secondary节点进行读取操作以减小主节点的压力(后面会对读写分离有详细说明)。

各个节点之间是通过心跳机制来维持联系的,当主节点无法和集群中其他节点通信超过10秒,集群会从剩下的节点中选择一个secondary作为primary,这个过程叫做选举(election),每个secondary节点都有一个优先级priority来参与投票(也可以有没有投票权的secondary节点),priority值越大就越优先成为主节点(所有的节点可以有相同的优先级,默认值都是1)。election的策略不仅仅就是根据priority值来,会综合很多其他的因素。总之MongoDB通过heartbeat和election机制实现了自动的Failover:

Mongodb副本集实现

 副本集要求参与选举投票(vote)的节点数为奇数,这很容易理解。当我们实际环境中因为机器等原因限制只有两个(或偶数)的节点,这时为了实现Automatic Failover引入另一类节点:仲裁者(arbiter),仲裁者只参与投票不拥有实际的数据,因此它对物理资源要求不严格。

Mongodb副本集实现

上面已经提到了primary,secondary和arbiter,整个MongoDB副本集群中除了这三种类型的节点还有其他几种:

  • Secondary-Only:这种类型的节点和secondary节点一样拥有数据副本,但是它们在任何情形下都成为不了primary节点。

  • Hidden:这种类型的节点对客户端程序来说是不可见的,同样也不能成为primary节点,但是Hidden成员能够参与选举投票。

  • Delayed:这种类型的成员通过人为的设置,可以指定一个时间来延迟从primary节点同步数据。Delayed成员的作用在于帮助集群从一些误操作中恢复,比如管理员误删除了某个集合。不至于迅速扩散到整个集群中。因此Delayed节点必须不能成为primary节点(priority为0)并且是Hidden的。

  • Non-Voting:这就是上面提到了没有选举权的secondary节点。这种类型的节点一般当集群节点数超过12才会需要。

简单副本集的搭建

主:192.168.1.100

从:192.168.1.101,192.168.1.102

1.首先已经安装完mongodb(我们使用rpm安装)。

mongodb默认端口为:27017

2.修改两个从节点配置文件

service mongod stop  vim /etc/mongod.conf

取消注释replSet,设置其名称;并添加replIndexPrefetch项。如下:

Mongodb副本集实现

重启服务:

service mongod start

3.登录到主节点命令行中

mongo>rs.status()  {     "startupStatus" : 3,     "info" : "run rs.initiate(...) if not yet done for the set", "ok" : 0, "errmsg" : "can't get local.system.replset config from self or any seed (YCONFIG)" }

启动一个新的副本集

>rs.initiate()   { "info2" : "no configuration explicitly specified -- making one", "me" : "Centos:27017", "info" : "Config now saved locally.  Should come online in about a minute "ok" : 1 }

在Mongo客户端使用命令rs.initiate()来启动一个新的副本集。

我们可以使用rs.conf()来查看副本集的配置

查看副本集状态使用 rs.status() 命令

副本集添加成员

添加副本集的成员,我们需要使用多条服务器来启动mongo服务。进入Mongo客户端,并使用rs.add()方法来添加副本集的成员。

语法

rs.add() 命令基本语法格式如下:

>rs.add(Host_NAME:PORT)

添加两个从节点成员:

testSet:PRIMARY> rs.add("192.168.1.101") --默认27017不用指定 { "ok" : 1 } testSet:PRIMARY> rs.add("192.168.1.102") { "ok" : 1 }

此时,查看副本集状态:

testSet:PRIMARY> rs.status() { "set" : "testSet", "date" : ISODate("2017-03-22T07:58:26Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "Centos:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1293, "optime" : Timestamp(1490168420, 1), "optimeDate" : ISODate("2017-03-22T07:40:20Z"), "electionTime" : Timestamp(1490168213, 11), "electionDate" : ISODate("2017-03-22T07:36:53Z"), "self" : true }, { "_id" : 1, "name" : "192.168.1.101:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 1146, "optime" : Timestamp(1490168420, 1), "optimeDate" : ISODate("2017-03-22T07:40:20Z"), "lastHeartbeat" : ISODate("2017-03-22T07:58:25Z"), "lastHeartbeatRecv" : ISODate("2017-03-22T07:58:25Z"), "pingMs" : 1, "syncingTo" : "Centos:27017" }, { "_id" : 2, "name" : "192.168.1.102:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 1086, "optime" : Timestamp(1490168420, 1), "optimeDate" : ISODate("2017-03-22T07:40:20Z"), "lastHeartbeat" : ISODate("2017-03-22T07:58:25Z"), "lastHeartbeatRecv" : ISODate("2017-03-22T07:58:24Z"), "pingMs" : 1, "lastHeartbeatMessage" : "syncing to: Centos:27017", "syncingTo" : "Centos:27017" } ], "ok" : 1 }

测试:

在主节点创建新库,并插入新数据:

testSet:PRIMARY> show dbs; admin  (empty) local  6.075GB testSet:PRIMARY> use test switched to db test testSet:PRIMARY> show dbs admin  (empty) local  6.075GB testSet:PRIMARY> db.test.insert({"name":"菜鸟教程"}) WriteResult({ "nInserted" : 1 }) testSet:PRIMARY> show dbs admin  (empty) local  6.075GB test   0.078GB

查看从节点信息:

testSet:SECONDARY> show dbs; admin  (empty) local  6.075GB test   0.078GB testSet:SECONDARY> db.test.find() { "_id" : ObjectId("58d231485934aa983f070c99"), "name" : "菜鸟教程" }

问题及解决:
1.初始化副本集时报错:

>rs.initialte() {     ....      "errmsg" "couldn't initiate : can't find self in the replset config" ,"ok" : 0     .... }

解决:编辑hosts文件添加主机名称解析,之后重新初始化副本集。

[root@Centos ~]# vim /etc/hosts 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6 127.0.0.1 Centos

2.添加副本集成员时报错:

testSet:PRIMARY> rs.add("192.168.1.101:27017") { "errmsg" : "exception: need most members up to reconfigure, not ok : 192.1.101:27017", "code" : 13144, "ok" : 0 }

解决:由于从节点配置文件中bind绑定为127.0.0.1的ip信息,从而导致不能添加192端的ip,将其bind注释掉。

Mongodb副本集实现

3.添加完成员,查看副本集状态时,节点一直 显示如:"stateStr" : "UNKNOWN"

Mongodb副本集实现

解决:问题的原因是rs.initiate()默认将primary的host键设置成机器的主机名,如下:

Mongodb副本集实现

1)可以编辑两个从节点的hosts文件添加主节点主机名和Ip信息,如:

[root@RedHat-1 ~]# vim /etc/hosts 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.1.100 Centos

2)可以将primary的主机名改成IP地址:

cfg = rs.conf() cfg.members[0].host = "192.168.1.100:27017" rs.reconfig(cfg)

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


当前题目:Mongodb副本集实现-创新互联
网页URL:http://scyanting.com/article/ccpjsc.html