您的位置:首页 > 数据库 > Mongodb

MongoDB学习笔记之副本集概述

2014-07-10 14:53 295 查看
MongoDB多台服务器上保存着数据备份,确保数据安全,其中一台服务器挂掉后应用程序数据能正常提供服务。MongoDB中的数据备份是通过复制来实现的,多台服务器构成一个副本集,在副本集中只有一个主服务器和多个备份服务器。主服务器用于处理客户端的写入请求和读取请求,备份服务器保存主服务器上的数据副本,客户端不能直接向备份服务器写数据,默认情况下备份服务器也不提供数据读取服务,除非通过setSlaveOk配置。



主服务器是通过选举确定的,选举遵从大多数原则,即副本集中有一半以上的节点投赞成票时,选举才成功。一旦备份节点无法与主服务器通信时,就会向其它的副本节点发送请求,请求将自己选为主节点。备份节点在收到选举请求后,会首先查看主服务器是否存在,如果主服务器不存在或者无法连接,就会比较当前节点与请求选举的节点的版本,如果对方版本比较新,就会投赞成票,否则会投否决票。这里选举采用的是一票否决制,即只要有一个节点投否决票,这次选举是不成功的。

当主服务器挂掉,副本集内部很快会选举出一个新的主服务器。如果在选举过程中出现了同票怎么办?重新选举,直到选举结束。一般偶数个节点且平均分配在不同的数据中心,两个数据中心由于网络问题不通时容易出现同票的情况。可以对这些节点重新分配,将大多数节点放在一个数据中心(A),剩余的少部分节点放到另一个数据中心(B),即使两个数据中心不相通,大多数节点所在的数据中心会选举出一个主服务器。



另一个做法是引入一个节点放入第三个数据中心,任何一个数据中心失去联系,都可以通过新节点达到大多数条件,只不过这样做至少需要三份副本;有的应用业务量小,不需要有三份副本这么大的投入,可以引入选举仲裁者角色,选举仲裁者只负责选举,不提供其他服务,一个只有2个节点的副本集,可以通过加入选举仲裁者达到大多数。



这样做有一个隐患,如果备份节点挂掉后,由于有一个仲裁者节点存在,选举仍然满足大多数条件,这样由于没有备份结点,整个系统不健壮。当备份结点恢复后,发现它远远落后于主节点,数据同步需要花大量时间。反之,如果仲裁者也是一个备份节点,则不存在这种问题。

副本集节点间通过心跳来获取其他节点的状态,包括谁是主节点,节点的最新数据版本是什么,以及节点处于什么状态等信息。心跳的发送间隔为2秒,如果一个节点通过心跳发现另一个节点的数据比自己新,就会把这个节点做为复制源,从这个节点开始复制数据。节点之间的复制是通过oplog实现的,每个节点内部都有一个oplog,记录着每一次复制操作,有了oplog,备份节点也可以做为复制源为其他节点提供复制数据。每一次复制都是先复制数据再写oplog,有可能复制完数据后这个节点就挂了,恢复后这条数据有可能被重复复制,oplog被设计为复制多次与复制一次达到同样的效果,所以这种情况下数据并不会重复。通过status()函数可以得知当前节点正在从哪个节点复制数据。在每个节点上运行这个函数会得到一张复制图。

如果复制链太长,一个数据从主节点复制到所有节点花费的时间会很长,影响复制的效率。可以为节点指定复制源,强制节点从某个节点进行复制,需要注意防止循环复制,即多个节点复制链形成一个环,环上的节点随着时间推移数据会越来越陈旧,但让节点自己选择复制源不会出现这种情况;还可以禁用复制链让所有节点都从主节点进行复制。

如果主服务器有大量的写入操作,备份服务器还没有来得及复制,主服务器就挂了,这时有新的主服务器被选举出来,在一段时间之后,先前挂掉的主服务器恢复正常。

(1)假设挂掉的主服务器最新版本为v100,它会去主服务器上同步v100之后的操作,但是无法找到,会执行一个比较过程

(2)通过比较二者的oplog找到最近一次相同的操作,假设为v90,把v90~v100这段操作进行回滚,回滚的操作日志会被放到rollback目录下

(3)把rollback目录下的操作应用到当前主服务器上,这可能需要人工参与。

主备服务器操作有比较大的差异的原因是主服务器写入太快,MongoDB的写入操作默认是没有返回值的,可以通过getLastError命令来控制写入速度,在这个命令返回之前,写操作是阻塞的。通过这个命令可以实现写入时复制,即在客户端写入主节点时,主节点写入完成后并不立即返回,而是等复制到一定数量的备份节点后再返回。在getLastError上一般会有一个超时时间,这种情况下,写入超时并不代表写入失败。

下一节分析Mongodb分片
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mongodb NOSQL