在读取数据的过程中我们需要关注以下两个问题:
从哪里读,关注数据节点位置;
什么样的数据可以读(数据是否提交),关注数据的隔离性。
第一个问题由readPreference来解决
第二个问题由readConcern来解决
什么是readPreference
readPreference决定使用哪一个节点来满足正在发起的读请求。可选值包括:
- primary:只选择主节点(默认值);
- primaryPreferred:优先选择主节点,如果不可用则选择从节点;
- secondary:只选择从节点;
- secondaryPreferred:优先选择从节点,如果从节点不可用则选择主节点;
- nearest:选择最近的节点(使用ping time,针对多数据中心部署的情况)。
readPreference场景举例
readPreference与Tag
readPreference只能控制使用一类节点(按照节点的角色,不是固定的节点)。Tag则可以将节点选择控制到一个或几个节点。考虑以下场景:
一个5个节点的复制集;
3个节点硬件较好,专用于服务线上客户;
2个节点硬件较差,专用于生成报表
可以使用Tag来达到这样的控制目的:
为3个较好的节点打上{purpose:"online"};
为2个较差的节点打上{purpose:"analyse"}
在线应用读取时指定online,报表读取时指定reporting
readPreference配置
通过MongoDB的连接串参数:
mongodb://host1:27107,host2:27107,host3:27017/?replicaSet=rs&readPreference=secondary
通过MongoDB驱动程序API:
MongoCollection.withReadPreference(ReadPreferene readPref)
Mongo Shell
db.collection.find({}).readPref("secondary")
readPreference实验:从节点读
注意事项
- 指定readPreference时也应该注意高可用问题。例如将readPreference指定primary,则发生故障转移不存在primary期间将没有节点可读。如果业务允许,则应该选择primaryPreferred;
- 使用Tag时也会遇到同样的问题,如果只有一个节点拥有一个特定Tag,则在这个节点失效时将无节点可读。这在有时候是期望的结果,有时候不是。例如:
- 如果报表使用的节点失效,即使不生成报表,通常也不希望将报表负载转移到其它节点上,此时只有一个节点有报表Tag是合理的选择。
- 如果线上节点失效,通常希望有替代节点,所以应该保持多个节点有同样的Tag
- Tag有时需要与优先级 选举权综合考虑。例如做报表的节点通常不会希望它成为主节点,则优先级应该为0