1>、客户端到副本集的连接:使用副本集与使用单台服务器很像,默认情况下,驱动程序会连接到主节点,并且将所有请求都路由到主节点。应用程序可以像使用单台服务器一样进行读和写,副本集会在后台默默处理热备份。在驱动程序中使用与MongoClient等价的对象,并且提供一个希望连接到的副本种子(seed)列表。种子是副本集成员,并不需要将所有成员都列出来:驱动程序连接到某个种子服务器之后,就能够得到其他成员的地址。例如:"mongodb://server-1:27017,server-2:27017"。当主节点挂掉之后,驱动程序会尽快自动找到新的主节点,并且将请求路由到新的主节点。如果没有可达的主节点,应用程序就无法执行写操作。在选举主节点的过程中,主节点可能会暂时不可用,如果没有可达的成员能够成为主节点,主节点可能长时间不可用。默认情况下,驱动程序在这段时间内不会处理任何请求(读或写),但是,可以选择将读请求路由到备份节点。
2>、等待写入复制:如果希望不管发什么都将写入操作保存到副本集中,那么必须要确保写入操作被同步到了副本集的“大多数”。可以使用getLastError命令检查写入是否成功,也可以使用这个命令确保写入操作被复制到备份节点,参数"w"会强制要求getLastError等待,一直到给定数量的成员都执行完了最后的写入操作。mongodb有一个特殊的关键字可以传递给"w",就是majority。例如:》>db.runCommand({"getLastError":1,"w":"majority"})。在输出的信息中会有一个新字段"writtenTo",只有当使用了"w"选项并且最后的操作被复制到多个服务器时才会有这个字段。假设在执行这个命令时只有主节点和一个仲裁者节点可用,那么主节点就无法将这个写操作复制到副本集中的任何成员。getLastError并不知道应该等待多久,所以它会一直等待下去。因此,应该始终为wtimeout选项设置一个合理的值。wtimeout是getLastError可以使用的另一个选项,它的值是命令的超时时间,如果超过这个时间还么有返回,就会返回失败。例如:>db.runCommand({"getLastError":1,"w":"majority","wtimeout":1000})。如果getLastError超时,应用程序必须要对这种情况作出处理。getLastError超时并不意味着写操作失败了,仅仅表明写操作没能在指定时间内复制到足够多的成员。写操作仍然被复制到了一些成员,而且会尽快传播到其他成员。通常将"w"用于控制写入速度。mongodb的写入速度“太快”,主节点上执行完写入操作之后,备份节点还来不及跟上。阻止这种行为的一种常用方式是定期调用getLastError,将"w"参数指定为大于1的值。这样就会强制这个连接上的写操作一直等待知道复制成功。这只会阻塞这个连接上的写操作,其他连接上的写操作仍然会立即执行完成并返回。"w"的其他值:majority并不是唯一一个可以传递给getLastError的w参数的值,mongodb允许将w指定为任意整数,例如:>db.runCommand({"getLastError":1,"w":"2","wtimeout":500})这个命令会一直等待,直到写操作被复制到两个成员(主节点和一个备份节点)。注意,"w"的值包含了主节点。如果希望写操作被复制到n个备份节点,应该将w指定为n+1(包括主节点)。将w设置为1相当于没有传入w选项。使用常量数值的弊端在于,如果副本集的配置发生了变化,就需要修改你的应用程序。
3>、自定义复制:副本集允许创建自己的规则,并且可以传递给getLastError,以保证写操作被复制到所需的服务器上。创建自己的规则,可以通过在副本集配置中创建"getLstErrorMode"字段实现。每条规则的形式都是"name":{"key":number}。name就是规则的名称,名称应该能够表明这条规则所做的事情,方便客户端理解,客户端在调用getLastError时才能够正确选择自己需要的规则。key字段就是标签键的值,number是需要遵循这条规则的分组的数量,number的意思是“保证写操作复制到number个分组,每个分组内至少一台服务器上”。
4>、将读请求发送到备份节点:默认情况下,驱动程序会将所有的请求都路由到主节点,但是可以通过设置驱动程序的读取首选项(read preferences)配置其他选项。可以在读选项中设置需要将查询路由到的服务器的类型。不建议将读请求发送到备份节点:对一致性要求非常高的应用程序不应该从备份节点读取数据。出于负载的考虑,许多用户会将读请求发送给备份节点,以便实现分布式负载,过载会导致副本集性能降低,然后会导致剩余的备份节点远远落后于主节点。何时可以从备份节点读取数据?当应用程序在主节点挂掉时仍然能够执行读操作,这是最常见的将读请求发送给备份节点的原因,失去主节点时,应用程序进入只读状态。这种选项叫做主节点优先。从备份节点读取数据有一个常见的参数是获得低延迟的数据。可以将读选项设置为Nearest,以便将请求路由延迟最低的成员。如果要从一个落后的备份节点读取数据,就要牺牲一致性,另一方面,如果希望写操作返回之前被复制到所有副本集成员,就要牺牲写入速度。