readConcern,一致性和可用性之间的平衡

在mongodb中,在副本集或分配进行读取的时候,readConcern用于控制一致性和隔离性。

通过结合writeConcerns和readConcern,就可以控制一致性和可用性之间的级别,比如可以放宽一致性从而提高可用性。

readConcern和readPreference的区别:

  • readPreference,用于决定去那个节点读取数据
  • readConcern,用于控制读取到何种隔离级别的数据,需要各个节点配合使用

readConcern级别

readConcern提供了五种readConcern级别

对于非事务性操作来说,只要关注三个级别就可以了(local、available、majority),顺便说一句mongodb的多文档事务是比较难理解的,而且官方也说了,能不用事务就不要用。

本文重点讲解和副本集有关操作的readConcern,不涉及分片、事务、因果一致性的内容。

1:local

表示不管副本集大部分成员是不是都写入了,只要当前节点有数据就会返回,读性能比较好,但读取的数据将来可能会回滚。

2:available

和local类似,只是在分片上有些区别,available可能会读取目前还不属于本节点的数据。

3:majority

保证读取到的数据都是经过大部分副本集成员确认过的,读取到的数据不会回滚,什么是回滚呢?primary节点写入数据成功后,但它要同步数据给其他secondary节点的时候挂了,此时这个数据将来会被回滚。

需要注意的是,majority表示得到的数据是经过确认的,但不代表是最新的数据。

Regardless of the read concern level, the most recent data on a node may not reflect the most recent version of the data in the system.

测试

如果理解了readPreference,那么理解readConcern就很顺利了。

db.test.find().readPref("secondary").readConcern("local")
db.test.find().readPref("secondary").readConcern("majority")

PHP例子:

$client = new MongoDB\Client("mongodb://:27018,:27017,:27017", [
        'readPreference' => 'secondary',
        'readConcernLevel'=>'majority'
    ]);

其他

1:readConcern选项

对于非多文档事务来说,可以作为mongodb方法和命令的选项来使用,比如:

db.collection.find().readConcern(<level>)

2:事务和readConcern

在事务中,必须设置事务级别(transaction-level)的readConcern,单个操作的readConcern会被忽略。

能够在事务开始的时候设置readConcern:

  • 对于多文档事务来说,支持snapshot、local、majority三种级别
  • 多文档事务中的write命令能够支持事务级别的readConcern

如果在事务开始初,没有指定,则使用 session-level 级别的readConcern,如果不是事务操作,则使用 client-level 的readConcern。

3:因果一致性会话和readConcern

这个概念( Causally Consistent Sessions )还不是很理解,涉及到readConcern:

  • 只支持local、majority级别
  • 如果事务中包含因果一致性,则snapshot也能使用

4:支持readConcern的操作,并不是所有的命令都支持readConcern的各个级别。

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章