数据读取的一致性,在数据库中是非常重要的, 在MONGODB 中大部分都是以复制集的方式体现的,而这就牵扯到一个问题, 数据读取的一致性的问题.
假设我有三台MONGODB的复制集,其中我的主库写入了一条数据,并且我读取了这条数据,而不幸的是此时主库DOWN,而数据还未复制到从库,并且很快主库恢复了正常,此时这条数据就是脏数据.
为了避免这样的极端的情况MONGODB 在3.2版本后,提出了一个概念 read concern ,其中本意是你读到的数据是不能被回滚的,必须是在MONGODB 中的大多数都被写入的数据.
如果想配置这个选择项需要在配置文件中加入
enableMajorityReadConcern: true
这里需要关注2个问题
1 如果我打开了 read concern 我读取的数据一定是最新的吗? 回答是不一定,可能是最新的,也可能不是最新的数据
2 read concern 影响系统的性能吗?
关于第一个问题,在数据读取时,会对数据在整体集群中的占比进行一个判断,如果的确是大多数节点都有此数据,那就能读出这个数据,否则这个数据就不能被读出.
关于第二个问题, 的确对有的复制集合架构有冲击
上面这段话,表明如果你的MONGODB 是使用的 PRIMARY ,SECONDARY , ARBITER的结构,如果你的从库DOWN机,并且你还设置了 read concern,则你的这个大多数就不在成立了,此时你的cache 的压力会猛增, 所以注意如果你使用 PSA的架构,那就不太建议你打开这个READ CONCERN.
并且还有提示,如果你不使用这个功能则可以保证你的系统运行是平稳的,那么问题就来了,如果我不使用这个功能, 但我想保证在极端的情况下,我的数据不会因为回滚而造成 dirty read.
此时就回到我们的题目, 用WRITE CONCERN 来解决这个问题, 上期我们讲了Write Concern 在写入数据的时候,可以设置 W:number, 此时如果你的复制集合有三个节点,那么很轻松的我们可以将一些关键的数据写入的时候,将write concern 改变为 W:2, 这样我们就可以保证我们的集群的数据在极端的情况下不会被回滚,并且读取数据降低是脏读的可能性.
同时使用这个方法,还能避免一些数据一致性的问题,举例我有三个节点,我读取数据在一个从库,而恰巧这个从库还为得到主库的数据,那么我读取数据就会产生,主库或者另外一个从库明明有这个数据,但这个从库就是没有的问题, 那对于这样的数据,我们可以将 w:3 来解决,保证写入的数据在三个节点都落地,那我们读取的时候必然不会碰到上面有可能读数据读不到的情况. (当然风险和性能方面的铤而走险就需要均衡利弊了)
所以,read concern 本身是可以不去设置,但我们可以通过write concern 来弥补一些我们需要数据在多节点一致性的问题. 如果您有什么好的建议,还请不吝赐教.