问题综述:(在读取数据的过程中需要关注以下两个问题)
第一个问题是由 readPreference 来解决的。
readPreference 在很早的版本就有了。
readPreference 以下五个可选值:
场景举例:
readPreference 与 Tag
readPreference 配置
通过 MongoDB 的连接串参数:
mongodb://host1:27017,host2:27017,host3:27017/?replicatSet=rs&readPreference=secondary
通过 MongoDB驱动程序API:
MongoCollection.withReadPreference(ReadPreference readPref)
db.collection.find({...}).readPref("secondary")
readPreference 实验:从节点读
主节点写入{x:1},观察该数据在各个节点立即可见。
注意事项:
第二个问题是由 readConcern 来解决。
在 readPreference 选择了指定的节点后,readConcern 决定这个节点上的数据哪些是可读的,类似于关系数据库的隔离级别。
可选值包括:
注意事项:
readConcern: "majority"
实验:readConcern: "majority" vs "local"
安装3节点复制集。
注意在配置文件内 replication 的参数 enableMajorityReadConcern 需要打开。
replication:
replSetName: rs0
enableMajorityReadConcern: true
将复制集中两个从节点使用 db.fsyncLock() 锁住写入(模拟同步高延迟)。
db.test.save({"a":1}) # 主节点:写入。
db.fsyncLock() # 两个从节点:分别执行。
db.test.find().readConcern("local")
db.test.find().readConcern("majority") # 此时会阻塞
db.fsyncUnlock() # 在一个从节点上解除写锁。
db.test.find().readConcern("majority") # 这次可以成功读取。
结论:
readConcern: majority 与 脏读
readConcern 如何实现安全的读写分离
考虑如下场景:
向主节点写入一条数据,立即在从节点读取这条数据。
错误方式:
db.orders.insert({old:101,sku:"kite",q:1})
db.orders.find({old:101}).readPref("secondary")
db.orders.insert({old:101,sku:"kite",q:1}, {writeConcern:{w:"majority"}})
db.orders.find({old:101}).readPref("secondary").readConcern("majority")
小测试
readConcern:"linearizable" 略
readConcern:"snapshot"
MongoDB的事务(2/3) 读操作 readPreference 和 readConcern
原文:https://www.cnblogs.com/sweetXiaoma/p/14602327.html