复制集技术相比较传统的Master-Slave模式好处在于多了容错机制。所以MongoDB的复制集技术主要为用户解决了两大问题:第一就是primary节点挂了,其余的secondary节点会自动选举出一个新的primary节点,继续服务。第二,各个secondary节点会自动从primary节点拿数据同步。至于读写分离,还需要用户在使用复制集时编写一些读写分离的基础操作模块。
MongoDB使用Bully算法实行选举,但是要求系统中参加选举的节点个数必须为奇数,否则无法选举,所以如果说我们系统恰好只有偶数个节点,只能加入一种特殊的节点仲裁节点,这种节点只能用于选举凑数,本身不可以存储任何的数据,这就是仲裁节点的作用。
正常情况下,各个节点之间都会间歇性的发送心跳来探测彼此,如果primary挂掉,那么周围的节点就无法收到来自primary节点的心跳,当时间超过一个阈值,该节点就会认为primary挂了,这个节点就可以发起一次选举,以下就是bully算法的过程:
当节点A发现primary挂了,A就会发起选举,发送选举信息给id比自己大的节点,然后等待这些节点回复,那些接受到该信息的节点会查看选举信息,如果发现收到了来自比自己id小的节点发来的信息,就会接管他消息,给A一个回复,那么A收到这个回复以后,就知道系统中有比自己id更大的节点存在,那么他就会推出选举。之前id更高的节点会继续上述过程,直到某一个节点,他发送出去的选举信息没有任何人回复,说明他此时就是系统中现存的id最大的节点,那么他就会宣布自己的选举获胜者,其余的节点收到该信息就会更新自己的信息。这就是bully算法的大致思想,实际实现时,这里的id其实就代表了优先级,可以按照具体的应用场景来设置优先级,比如mongodb中有priority,这个属性就会被考虑到优先级里。也只是容错机制的基础。
MongoDB实现复制是采用一种基于日志的异步复制方式。primary节点的各种更新操作会被记录到oplog中,secondary节点根据primary的oplog日志同步数据。具体分为两步
1.intil syn:当节点第一次进入集群时,执行inti syn,会把primary的数据复制到自己的本地数据库,这个过程也会分为几步,第一步肯定会比较耗时,要复制全部的数据,会根据primary数据库中类似快照的东西复制,但是在这个期间,primary可能有新的update,那么该节点就需要在复制结束以后,再根据primary的oplog来复制新的更新。
2.steady syn:稳步复制,会周期性得读取primary的oplog到本地,然后更新本地数据。这里有一个问题就是,oplog日志大小是固定的,所以很有可能primary更新太快,导致从数据库跟不上,一旦发生这种情况,复制就无法继续了,只能执行一次initi syn了,而且,需要把oplog日志的大小调大才行。
还有一个问题是,primary本地的oplog还没有发送到从服务器priamry就挂掉了,之后primary连回来,这时该数据库已经是从库了,它的数据就会与其他数据库的数据不一致,这时候需要回滚那部分数据才行。
标签:bully,选举,MongoDB,primary,id,算法,复制,oplog,节点 From: https://blog.51cto.com/u_15873544/5844598