设为首页 收藏本站
查看: 2214|回复: 0

[经验分享] Mongodb副本集实现

[复制链接]

尚未签到

发表于 2018-10-25 10:03:39 | 显示全部楼层 |阅读模式
MongoDB副本集概述
  以下图片摘自MongoDB官方文档:http://docs.mongodb.org/manual/core/replication-introduction/
DSC0000.jpg

  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)。
DSC0001.jpg

  默认所有的读操作也是走的primary节点,当然客户端可以选择从secondary节点进行读取操作以减小主节点的压力(后面会对读写分离有详细说明)。
  各个节点之间是通过心跳机制来维持联系的,当主节点无法和集群中其他节点通信超过10秒,集群会从剩下的节点中选择一个secondary作为primary,这个过程叫做选举(election),每个secondary节点都有一个优先级priority来参与投票(也可以有没有投票权的secondary节点),priority值越大就越优先成为主节点(所有的节点可以有相同的优先级,默认值都是1)。election的策略不仅仅就是根据priority值来,会综合很多其他的因素。总之MongoDB通过heartbeat和election机制实现了自动的Failover:
DSC0002.jpg

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

  上面已经提到了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项。如下:

  重启服务:
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注释掉。

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

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

  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)



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-626217-1-1.html 上篇帖子: CentOS 7 yum方式快速安装MongoDB 下篇帖子: mongodb运维碰到的一些故障笔记
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

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