创建副本集
1. 副本集:副本集时一组服务器,其中有一个主服务器(primary),用于处理客户端请求;还有多个备份服务器(secondary),用于保存主服务器的数据副本。如果主服务器崩溃了,备份服务器会
自动将齐中一个成员升级为新的主服务器。
2. 几个关键概念:
1). 客户端在单个服务器上可以执行的请求,都可以发送到主节点执行(读、写、执行命令、创建索引等)
2). 客户端不能在备份节点上执行写操作
3). 默认情况下,客户端不能从备份节点中读取数据。在备份节点上显式地执行setSlaveOk之后,客户端就可以从备份节点中读取数据了。
3. 配置副本集
1). 为副本集选定一个名字,然后使用--replSet name 选项重启server-1.
mongod --replSet spock -f mongod.conf --fork
2). 使用同样的replSet和标示符(spock)再启动两个服务器作为副本集中的其他成员。命令同上。
可以将replSet选项添加到每个成员各自的mongod.conf文件中,以后启动时就会自动使用这个选项了。
3). 为了让每个mongod能够知道彼此的存在,需要创建一个配置文件,在配置文件中列出每一个成员,并且将配置文件发送给server-1,然后server-1会负责将配置文件发送给其他成员。
首先创建配置文件:
config = { "_id":"spock", "members":[{"_id":0,"host":"server-1:27017"},{"_id":0,"host":"server-2:27017"},{"_id":0,"host":"server-3:27017"}]}
"_id"字段的值就是启动时从命令行传递进来的副本集名称。一定要保证这个名称与启动时传入的名称一致。
文档剩余部分就是一个副本集成员数组。其中每个元素都需要两个字段:一个唯一的数值类型的"_id"字段,和一个主机名。
4). 将配置发送给其中一个副本集成员。为此,连接到一个有数据的服务器(sever-127017),使用config对象对副本集进行初始化:
db=(new mongo("server-1:27017")).getDB("test") // 连接到服务器
rs.initiate(config) // 初始化副本集
5). server-1会解析配置对象,然后向其他成员发送消息,提醒它们使用新的配置。所有成员都配置完成后,它们会自动选出一个主节点,然后就可以正常处理读写请求了。
4. 如果正在创建一个全新的副本集,可以将配置文件发送给副本集的任何一个成员。如果副本集中已经有了一个有数据的成员,那就必须将配置对象发送给这个拥有数据的成员。
如果拥有数据的成员不止一个,那么久无法初始化副本集。
5. 必须使用mongo shell 来配置副本集。没有其他方法可以基于配置文件对副本集进行配置。
6. rs.initiate() 命令中的rs。rs是一个全局变量,其中包含与复制相关的辅助函数。这些函数大部分都只是数据库命令的包装器。
7. 网络注意事项:副本集中所有成员都必须能够连接到其他成员。并且副本集的配置中不应该使用localhost作为主机名。
8. 修改副本集中的配置:
1). 添加:rs.add("server-4:27017")
2). 删除:rs.remove("server-4:27017") // 删除成员时,会在shell中得到很多无法连接数据库的错误信息,这是正常的。这实际说明了配置修改成功。
3). shell中使用rs.config()来查看配置是否成功。
4). shell中使用 rs.reconfig(config) 重新配置。例如修改主机名:
var config = rs.config()
config.members[1].host="server-2:27017"
rs.reconfig(config)
对于复杂的数据库配置修改,rs.reconfig通常比rs.add和rs.remove更有用,比如修改成员配置或者一次性添加或者删除多个成员。可以使用这个命令做任何合法的副本集配置修改:
只需创建想要的配置问那个然后将其传给rs.reconfig
9. 重新配置副本集时,主节点需要先退化为普通备份节点(需要命令吗?),以便接受新的配置,然后会恢复。要注意,重新配置副本集之余,副本集会暂时没有主节点,之后一切恢复正常。
10. 设计副本集两种推荐的配置方式:
1). 将"大多数"成员放在同一个数据中心。
2). 在两个数据中心各自防止数量相等的成员,在第三个地方防止一个用于决定胜负的副本集成员。
更复杂的需求需要使用不同的配置,一定要考虑清楚,出现不利情况时,副本集要如何达到大多数的要求。
11. 选举机制:当一个备份节点无法与主节点连通时,他就会联系并请求其他的副本集成员将自己选举为主节点。其他成员会做几项理想检查:自身是否能够与主节点连通?希望被选举为主节点的备份
节点的数据是否最新?有没有其他更高优先级的成员可以被选举为主节点?如果要求被选举为主节点的成员能够得到副本集中"大多数"成员的投票,他就会称为主节点。即使"大多数"成员只有一个
否决本次选举,选举就会取消。
12. 成员配置选项:
1). 选举仲裁者:仲裁者唯一作用就是参与选举。它只是为了帮助副本集满足"大多数"这个条件。启动仲裁者的命令:rs.addArb("server-5:27017")
或者 rs.add({"_id":4,"host":"server-5:27017","arbiterOnly":tue})
a. 最多只能使用一个仲裁者
b. 仲裁者的缺点:仲裁者无法复制数据
如果可能,尽可能在副本集中使用奇数个数据成员,而不要使用仲裁者。
13. 优先级:优先级用于表示一个成员渴望成为主节点的程度,优先级的取值范围可以是0-100.默认值为1。优先级为0的成员永远不能够成为主节点,这样的成员称为被动成员。
14. 隐藏成员:客户端不会向隐藏成员发送请求,隐藏成员也不会作为复制源(尽管当其他复制源不可用时隐藏成员会被使用)。因此,很多人会将不够强大的服务器或者备份服务器隐藏起来。
只有优先级为0的成员才可以被设置为隐藏,还需设置hidden:true。要将隐藏成员设置为非隐藏,需要将hidden设置为false,或者删除hidden选项。
15. 延迟备份节点:防止数据库因为认为错误而遭受毁灭性的破坏,可以使用slaveDelay设置一个延迟备份节点。slaveDelay要求成员的优先级为0.如果你的应用会将请求路由到备份节点,
应该将延迟备份节点隐藏掉,以避免请求被路由到延迟备份节点。
16. 禁用索引:有时,备份节点并不需要与主节点拥有相同的索引,甚至可以没有索引。如果某个备份节点的用途仅仅是处理数据备份或者离线的批量任务。那么你可以希望在它的成员配置中
指定"buildIndexs":false。这个选项可以阻止备份节点创建索引。另外,这个选项也要求成员优先级为0。 (恢复数据时是否影响查询?)