当想副本集插入数据是,写入副本集的“大多数”成员被认为是安全写入。
当希望确保写操作被复制到每个数据中心中的至少一台服务器上,或者被复制在到可见节点的“大多数”服务器上时,应该创建新的规则。
副本集允许创建自己的新规则,并却可以传递给getLastError,以保证写操作被复制到所欲的服务器上。
1.保证复制到每个数据中心的一台服务器上
对于不用数据中心之间更容易发生网络故障;相对于数据中心同等数量的服务器管挂掉,整个数据中心挂掉的可能性更高。
因此,你很可能希望保证将写操作复制到每个数据中心,这样,玩意某个数据中心掉线了,其他每个数据中心都有一份最新的本地数据副本。
要实现此机制
第一步:按照数据中心对成员进行分类。可以在副本集配置中添加一个tags字段。
var config = rs.config()
config.members[0].tages = {“dc”:”us_east”}
config.members[0].tages = {“dc”:”us_east”}
config.members[0].tages = {“dc”:”us_east”}
config.members[0].tages = {“dc”:”us_west”}
config.members[0].tages = {“dc”:”us_west”}
config.members[0].tages = {“dc”:”us_west”}
config.settings = {}
config.settings.getErrorModes = [{“eachDC”:{“dc”:2}}]
rs.reconfig(config)
设置完成。
第二步:对写操作应用
db.foo.insert({“x”:1})
db.runCommand({“getLastError”:1,”w”:”eachDC”,”wtimeout”:1000})
2.保证复制到可见节点中的“大多数”
注意:隐藏节点不用设置标签。
要实现此机制
第一步:按照数据中心对成员进行分类。可以在副本集配置中添加一个tags字段。
var config = rs.config() //标签中属性的值为分组的关键
config.members[0].tages = {“dc”:”A”}
config.members[0].tages = {“dc”:”B”}
config.members[0].tages = {“dc”:”C”}
config.members[0].tages = {“dc”:”D”}
config.members[0].tages = {“dc”:”E”}
config.members[0].tages = {“dc”:”F”}
config.settings = {}
config.settings.getErrorModes = [{“visibleMajority”:{“dc”:4}}]
rs.reconfig(config)
设置完成。
第二步:对写操作应用
db.foo.insert({“x”:1})
db.runCommand({“getLastError”:1,”w”:”visibleMajority”,”wtimeout”:1000})
规则是非常强大的副本集配置方式,虽然他理解和设计起来都很复杂,除非有非常特殊的复制要求,否则使用“w”:“majority”就已经可以了。
3.将读请求发送到备份节点
可以通过是设置驱动程序的读取首选项(read preferences)配置其它选项,可以再读取首选项中设置需要将查询路由到的服务器的类型。
使用Secondary或者Secondary preferred读选项。
如果对数据一致性要求高,则最好不要这么做。
处于负载的考虑,会使整个副本集的可用性降低到不可忍受的范围,当一个备份节点出现问题时,当他恢复时,会向其他复制节点复制数据,导致其他节点过载,导致性能变慢,副本集性能进一步降低,然后强制其他成员承担更多负载,导致副本集所有成员过载,形成恶性死循环。
使用分片做分布式负载 通常是一个更好的选择。