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

[经验分享] MongoDB副本集学习(一):概述和环境搭建

[复制链接]

尚未签到

发表于 2015-7-6 10:03:43 | 显示全部楼层 |阅读模式
MongoDB副本集概述
  以下图片摘自MongoDB官方文档:http://docs.mongodb.org/manual/core/replication-introduction/
DSC0000.png
  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.png
  
  默认所有的读操作也是走的primary节点,当然客户端可以选择从secondary节点进行读取操作以减小主节点的压力(后面会对读写分离有详细说明)。
  各个节点之间是通过心跳机制来维持联系的,当主节点无法和集群中其他节点通信超过10秒,集群会从剩下的节点中选择一个secondary作为primary,这个过程叫做选举(election),每个secondary节点都有一个优先级priority来参与投票(也可以有没有投票权的secondary节点),priority值越大就越优先成为主节点(所有的节点可以有相同的优先级,默认值都是1)。election的策略不仅仅就是根据priority值来,会综合很多其他的因素。总之MongoDB通过heartbeat和election机制实现了自动的Failover:
DSC0002.png
  
  副本集要求参与选举投票(vote)的节点数为奇数,这很容易理解。当我们实际环境中因为机器等原因限制只有两个(或偶数)的节点,这时为了实现Automatic Failover引入另一类节点:仲裁者(arbiter),仲裁者只参与投票不拥有实际的数据,因此它对物理资源要求不严格。
DSC0003.png
  上面已经提到了primary,secondary和arbiter,整个MongoDB副本集群中除了这三种类型的节点还有其他几种:


  • Secondary-Only:这种类型的节点和secondary节点一样拥有数据副本,但是它们在任何情形下都成为不了primary节点。
  • Hidden:这种类型的节点对客户端程序来说是不可见的,同样也不能成为primary节点,但是Hidden成员能够参与选举投票。
  • Delayed:这种类型的成员通过人为的设置,可以指定一个时间来延迟从primary节点同步数据。Delayed成员的作用在于帮助集群从一些误操作中恢复,比如管理员误删除了某个集合。不至于迅速扩散到整个集群中。因此Delayed节点必须不能成为primary节点(priority为0)并且是Hidden的。
  • Non-Voting:这就是上面提到了没有选举权的secondary节点。这种类型的节点一般当集群节点数超过12才会需要。
  

简单副本集的搭建
  官方建议的最小化的副本集为Three Member Sets,一个primary和两个secondary。我们先就搭建一个这样的测试环境。
DSC0004.png
  首先建立三个数据目录和日志目录:



1.    cd /usr/local/mongodb-2.4.1/data/
2.    mkdir -p rs0-0 rs0-1 rs0-2
3.    cd /usr/local/mongodb-2.4.1/log/
4.    mkdir -p rs0-0 rs0-1 rs0-2
  然后我们以守护进程的方式启动三个mongod进程,端口分别是37017,37018和37019:



1.    ./bin/mongod --fork --dbpath data/rs0-0/ --logpath log/rs0-0/rs0-0.log --rest --replSet rs0 --port 37017
2.    ./bin/mongod --fork --dbpath data/rs0-1/ --logpath log/rs0-1/rs0-1.log --rest --replSet rs0 --port 37018
3.    ./bin/mongod --fork --dbpath data/rs0-2/ --logpath log/rs0-2/rs0-2.log --rest --replSet rs0 --port 37019
  跟启普通的mongod进程基本相同,不同的跟了--replSet选项,rs0是该副本集的名称。--rest参数是打开web监控页面,比如我们这里监听37017端口,则打开http://192.168.129.129:38017/(mongod端口加上1000)就可以看到这个mongodb数据库进程的信息,如果是副本集就能查看整个副本集的相关信息。
  
  然后我们用mongo shell连上端口为37017的mongod:



1.    ./bin/mongo -port 37017
2.    use admin
  接着我们需要初始化一个Replica Set:首先创建一个副本集配置对象:



1.    rsconf={
2.        "_id" : "rs0",
3.        "members" : [
4.            {
5.                "_id" : 0,
6.                "host" : "192.168.129.129:37017"
7.            }
8.        ]
9.    }
  然后用rs.initiate()进程初始化:



1.    rs.initiate(rsconf)
2.    {
3.        "info" : "Config now saved locally.  Should come online in about a minute.",
4.        "ok" : 1
5.    }
  
  添加成员
  通过rs.add()将另外两个mongod添加到副本集当中:



1.    rs0:PRIMARY> rs.add("192.168.129.129:37018")
2.    { "ok" : 1 }
3.    rs0:PRIMARY> rs.add("192.168.129.129:37019")
4.    { "ok" : 1 }
  会发现37017这个mongod默认就是PRIMARY节点了。通过rs.conf()可以查看集群的配置情况:



1.    rs0:PRIMARY> rs.conf()
2.    {
3.        "_id" : "rs0",
4.        "version" : 3,
5.        "members" : [
6.            {
7.                "_id" : 0,
8.                "host" : "192.168.129.129:37017"
9.            },
10.            {
11.                "_id" : 1,
12.                "host" : "192.168.129.129:37018"
13.            },
14.            {
15.                "_id" : 2,
16.                "host" : "192.168.129.129:37019"
17.            }
18.        ]
19.    }
  
  修改priority
  副本中所有的secondary节点都有一个priority值,为任意的浮点数,该值越大则该节点在election中越优先成为primary节点,通过下面的命令修改该值,目前primary节点是37017:



1.    rs0:PRIMARY> cfg=rs.conf()
2.    {
3.        "_id" : "rs0",
4.        "version" : 7,
5.        "members" : [
6.            {
7.                "_id" : 0,
8.                "host" : "192.168.129.129:37017"
9.            },
10.            {
11.                "_id" : 1,
12.                "host" : "192.168.129.129:37018"
13.            },
14.            {
15.                "_id" : 2,
16.                "host" : "192.168.129.129:37019"
17.            }
18.        ]
19.    }
  我们将37019节点的priority设置成2:



1.    rs0:PRIMARY> cfg=rs.conf()
2.    cfg.members[2].priority = 2
3.    2
  这里数组的索引2其实跟rs.conf查看到的每个成员的_id不是一回事。
  然后执行:



1.    rs0:PRIMARY> rs.reconfig(cfg)
  注意:执行rs.reconfig()命令会强制整个副本集集群进行一次election,这样priority较高的37019节点便成了primary节点:
DSC0005.png
  整个election过程需要一点时间,在这之间整个集群的所有节点都是secondary
  
  添加仲裁者
  首先需要启动一个作为arbiter的mongod进程,端口40000,虽然arbiter不持有数据但是仍然需要数据目录来保存一些配置信息:



1.    mkdir –p data/rs0-arb
2.    mkdir –p log/rs0-arb
3.    ./bin/mongod --fork --dbpath data/rs0-arb/ --logpath log/rs0-arb/rs0-arb.log --rest --replSet rs0 --port 40000
  然后进入primary节点执行下面命令添加arbiter:



1.    rs0:PRIMARY> rs.addArb("192.168.129.129:40000")
2.    { "ok" : 1 }
3.    rs0:PRIMARY> rs.conf()
4.    {
5.        "_id" : "rs0",
6.        "version" : 6,
7.        "members" : [
8.            {
9.                "_id" : 0,
10.                "host" : "192.168.129.129:37017"
11.            },
12.            {
13.                "_id" : 1,
14.                "host" : "192.168.129.129:37018"
15.            },
16.            {
17.                "_id" : 2,
18.                "host" : "192.168.129.129:37019"
19.            },
20.            {
21.                "_id" : 3,
22.                "host" : "192.168.129.129:40000",
23.                "arbiterOnly" : true
24.            }
25.        ]
26.    }
  仲裁节点的作用
  通过实际测试发现,当整个副本集集群中达到50%的节点(包括仲裁节点)不可用的时候,剩下的节点只能成为secondary节点,整个集群只能读不能写。比如集群中有1个primary节点,2个secondary节点,加1个arbit节点时:当两个secondary节点挂掉了,那么剩下的原来的primary节点也只能降级为secondary节点;当集群中有1个primary节点,1个secondary节点和1个arbit节点,这时即使primary节点挂了,剩下的secondary节点也会自动成为primary节点。因为仲裁节点不复制数据,因此利用仲裁节点可以实现最少的机器开销达到两个节点热备的效果。
  
  移除成员
  移除一个成员使用rs.remove()命令:



1.    rs0:PRIMARY> rs.remove("192.168.129.129:37019")
2.    Sun Aug 11 12:19:22.754 DBClientCursor::init call() failed
3.    Sun Aug 11 12:19:22.874 JavaScript execution failed: Error: error doing query: failed at src/mongo/shell/query.js:L78
4.    Sun Aug 11 12:19:22.909 trying reconnect to 127.0.0.1:37017
5.    Sun Aug 11 12:19:22.909 reconnect 127.0.0.1:37017 ok
  需要注意的是:虽然有错误信息,但其实操作已经成功了。参看官方的文档:
DSC0006.png
  每改变一次集群的配置,副本集的version都会加1。我们重新将37019加入rs0这次提示信息有点不一样:



1.    rs0:PRIMARY> rs.add("192.168.129.129:37019")
2.    { "down" : [ "192.168.129.129:37019" ], "ok" : 1 }
  我们打开http://192.168.129.129:38017/可以看到整个副本集的相关信息:
DSC0007.png
  
  至此一个简单的用于开发和测试Three Member Sets就搭建完成了。下节会在此基础上做一些简单的数据测试。
  

运维网声明 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-83731-1-1.html 上篇帖子: MongoDB权威指南(1)- Getting Started 下篇帖子: MongoDB源码概述——启动处理
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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