规划MongoDB复制集

规划MongoDB复制集

  1. 大多数

要设计自己的一个复制集,需要熟悉下一些复制集的概念,其中最重要的一个概念是大多数(majority)。所谓大多数就是指该一个复制集的过半成员。

一个复制集的主节点只有在能连接大多数成员的前提下才能成为主节点,一个复制集也需要大多数成员才能选举一个主节点,一次写操作也只有被复制到大多数成员的情况下才能保证其安全。

需要注意的是,一个复制集不管有多少节点不可用,这个大多数都是指复制集的所有成员数量的过半。

<table> <caption> 什么是大多数 </caption> <tr> <th>复制集的成员数量 </th> <th>大多数</th> </tr> <tr> <td>1</td> <td>1</td> </tr> <tr> <td>2</td> <td>2</td> <tr> <tr> <td>3</td> <td>2</td> <tr> <tr> <td>4</td> <td>3</td> </tr> <tr> <td>5</td> <td>3</td> </tr> <tr> <td>6</td> <td>4</td> </tr> <tr> <td>7</td>\ <td>4</td> </tr> </table>

举个例子:假设又一个5成员的复制集,其中3个节点宕机,因为其他两个节点都不能联系到集群中的大多数成员,所以它们无法选举出主节点,如果其中一个节点是主节点,也会降级成为辅助节点。

为什么会这样呢?因为也可能是另外一种情况,3个节点跟其他两个节点失去连接,但又彼此可以联系,这时这3个节点就可以选举出一个主节点了。这种情况可能发生在复制集被分配在不同的机房或者网络段。

所以在规划复制集的时候,就需要保证我们可以随时可以得到一个主节点。一般有两种方式:

  1. 将复制集的大多数节点放在一个数据中心,这样只要这个数据中心没有问题,主节点就很有可能没有问题。

  2. 将相等数量的节点分别放在两个数据中心,同时还需要在第三个数据中心放一些节点来保证能选举出一个主节点。

  3. 怎么选主节点


当一个辅助节点不能连接主节点时,它就会联系其他辅助节点,并提名自己成为主节点。此时其他节点就会做些检查:主节点是否只去联系?主节点候选者是否有最新的数据?还有没有优先级更高的节点存在?

如果主节点候选者获取了大多数成员的"ayes"应答,那么它就成为了主节点。如果有个节点知道任何主节点候选人不能成为主节点的原因,它会否决这次选举。只要有一个节点否决了选举,这次选举就会取消。

一个主节点候选者有最新的数据复制,至少要跟其他节点的最新数据一致。假设,主节点候选者的最新复制操作是op123,但有个节点的最新操作是op124,那么这次选举将被取消。

所有的复制集成员都只会提名自己为主节点,而不会推荐其他人成为候选者。但所有的节点都可以投票。

  1. 创建选举仲裁者(Arbiter)

有时候用户只想部署2个节点,一个主节点+一个副节点,并不想花费多余的精力去管理额外的节点。但双节点的架构是脆弱的,这意味着如果主节点宕机时,副节点也不能成为主节点。为了解决这种情况,MongoDB提供了一种特殊的角色:仲裁者。

仲裁者只用来参与选举,不能复制数据,也不能被客户端连接。因为仲裁者没有普通节点的义务与责任,只是用来选举,可以将其部署在普通的机器上,并放置在单独的机房,从而置身之外。

按照如下步骤创建一个仲裁者:

  1. 启动一个mongod进程,要有--replSet参数。

  2. 在mongo shell执行以下命令:

     rs.addArb("server-5:27017")
    

或者:

	rs.add({"_id" : 4, "host" : "

er-5:27017", "arbiterOnly" : true})

一个仲裁者一旦被加入集群,就永远是个仲裁者,不能将其配置成普通节点,也不能将普通节点配置成仲裁者。

尽量不要使用仲裁者节点,要用最多就只用一个。一个复制集的成员越多,选举花费的时间就越多。仲裁者通常是用来保证一个复制集的成员数量是奇数。

在正常情况下,如果能使用普通的数据节点就不要使用仲裁节点。假设一个3节点复制集,一个主节点,一个副节点,一个仲裁节点。假设副节点完全报废,当你添加新节点后,从主节点同步数据可能会造成很大负荷。

  1. 优先级

优先级的范围是0~100,优先级为0的节点永远不能成为主节点,这类节点被成为被动节点。默认的优先级是1. 在满足大多数链接跟最新数据的情况下,优先级最高的节点一定会被选为主节点。

例如,用命令将一个优先级为1.5的节点加入复制集中:

> rs.add({"_id" : 4, "host" : "server-4:27017", "priority" : 1.5})

假设其他节点的优先级是1,一旦server-4的节点与其他节点同步后,当前的主节点会降级,server-4会成为主节点。

另外,修改后的配置数据必须发送到会成为主节点的那个节点,否则配置不会生效。例如一个3节点的复制集: server-1,server-2, server-3,其中server-1优先级是1.5,假设我们给于server-2更高的优先级2,如下:

> db = (new Mongo('server-1:27017')).getDB('test')
> config = rs.config()
> config.members[1].priority = 2
> rs.reconfig(config)

这个是不会起作用的,db必须是指向server-2的。

  1. 隐藏节点

客户端不会向隐藏节点发请求,请求节点也不会成为优先的数据源,仅仅在必要的情况下,这些节点才会被客户端访问。

隐藏节点的优先级是必须是0.

要隐藏一个节点,在mongo shell输入如下命令:

> var config = rs.config()
> config.members[2].hidden = 0
> config.members[2].priority = 0
> rs.reconfig(config)

当配置生效后,用db.isMaster()方法是看不到隐藏节点的,但rs.config()和rs.status()方法任然可以。

  1. 同步延迟副节点

主节点的数据因为种种原因被破坏,如果所有的节点都随时将数据同步过来,那么数据就无法恢复了,为了解决这个问题,就需要延迟某些节点的同步时间,使其晚点同步主节点数据,这种节点叫做延迟节点。

延迟节点的priority必须是0,同时设置slaveDelay属性,该属性的值是已秒为单位的整数,如果客户端允许访问副节点,那么最好将延迟节点隐藏起来。

  1. 无索引节点

如果你的副节点只是用来备份数据,那么就没必要为其创建索引数据,修改其属性buildIndexes为false,就可以阻止该节点创建索引。

要注意,一旦一个节点被配置为不能创建索引,它就再也不能创建索引了。要消除这种效果,只有将其从复制集删除,清除数据,再将其添加到复制集,然后重新同步数据。

最后,这种节点的priority也必须是0.

转载于:https://my.oschina.net/bluven/blog/372251

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值