Mongodb 笔记 —- Replica Set-3-Rollback,WrireConcern, Secondary读

Mongodb 笔记 —- Replica Set-3-Rollback,WrireConcern, Secondary读

4 6 月, 2019 阅读 609 字数 2187 评论 0 喜欢 0

Rollback

如果一个primary在插入过程中,出现down机,且插入的数据有一部分secondary没有来得及通过oplog同步。那么down机的primary(old primary)拥有的数据版本即是最新的(version L)。同时,因为down机,自然也会通过选举产生新的primary(new primary)。

选出的new primary自然拥有相对老的数据(version O)。这时候,new primary 会继续接受新的请求。

假设,没有down机,正常数据版本变化应该是:version O -> L -> N

而:new primary 的数据版本变化是: version O -> N`

这里也就出现了2个问题:

1.数据出现了断层

2.old primary如果作为secondary回到集群,带了version L 的数据,会出现数据差异(N`与L的差异)。这里,也就是需要ROLLBACK的原因了。

mongodb会根据old primary和new primary之间oplog的差异,自动进行rollback来使old primary和new primary同步。

  1. 解决数据断层:被old primary rollback的数据会存放到一个单独的rollbakc files里面,可以通过人工操作来恢复它(O->L的数据)。
  2. 当rollback超过30分钟或者大于300MB,rollback会失败。

为了防止roll back 的发生,我们可以使用write concern。(会显著降低写性能)

Write concern

write concern即把“写”操作,在集群多个节点上执行成功才返回结果。

wtimeout :限定时间内完成。否则返回失败。
  • 0代表不设定时间
  • 如果设定了超时,发生超时,超时前的写操作不会回滚(应用程序需要自行安排逻辑处理超时)

在majority数量节点上写入:

db.products.insertOne(      

{ “_id”: 10, “item”: “envelopes”, “qty”: 100, type: “Self-Sealing” },      

{ writeConcern: { “w” : “majority”, “wtimeout” : 100 } }   — majority

);

在指定数量节点上写入:

db.products.insertOne(  

 { “_id”: 10, “item”: “envelopes”, “qty”: 100, type: “Self-Sealing” }, 

  { writeConcern: { “w” : 2, “wtimeout” : 100 } }   —- primary and one secondary(计算原则为:n+1,n个secondary + 1个primary)

);

Hidden,?delayed, and?priority 0?可以成为w: N的对象。

在指定分组数量上写入: N组,写入每个组的至少一个节点。

var config = rs.config()

> config.members[0].tags = {“dc” : “us-east”}

> config.members[1].tags = {“dc” : “us-east”}

> config.members[2].tags = {“dc” : “us-east”}

> config.members[5].tags = {“dc” : “us-west”}

> config.members[6].tags = {“dc” : “us-west”}

config.settings = {}

> config.settings.getLastErrorModes = [{“eachDC” : {“dc” : 2}}]

> rs.reconfig(config)

db.products.insertOne( { “_id”: 10, “item”: “envelopes”, “qty”: 100, type: “Self-Sealing” }, { writeConcern: { “w” : “eachDC”, wtimeout : 1000 } });

Delayed secondaries 只会在设置的slaveDelay 时间之后才会返回写入成功。

从Replica Set读数据

读的方式:
  1. primary —默认方式,只从primary读,primary down集群无法读。
  2. primary preferred —优先从primary读,primary down,从secondary读
  3. secondary —只 从 secondary 读, secondary全down集群无法读
  4. secondary prefrred —优先从 secondary 读, secondary全down,从 primary 读
  5. Nearest — 从ping time延迟最低的节点读数据
  6. 直接连接到某个节点,从某个节点读取数据。(比如某个secondary,有自己额外的索引,且不要求数据一致性,可以利用那个索引优化一些读)

Multi-document transactions?的读操作只能读?primary.

使用secondary来分担读任务的缺点:
  1. 因为同步的不一致或者不及时,读到的很可能不是最新的数据。
  2. 如果是集群来分担读的话,很可能造成一个点垮了之后,任务分给其他节点,然后其他节点又造成超负荷,最后整个集群彻底崩塌。(如果没崩塌,你回复跨掉的节点如果需要再同步,也会给其他节点造成负担。)  —-sharding 时用来分担读任务更好的方案。

发表回复

蜀ICP备15005542号