primary-secondary 协议是什么?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在primary-secondary 类型的协议中,副本被分为两大类,其中有且仅有一个副本作为primary 副本, 除primary 以外的副本都作为secondary 副本。维护primary 副本的节点作为中心节点,中心节点负 责维护数据的更新、并发控制、协调副本的一致性。
Primary-secondary 类型的协议一般要解决四大类问题:数据更新流程、数据读取方式、Primary 副本的确定和切换、数据同步(reconcile)。
数据更新基本流程 1. 数据更新都由primary 节点协调完成。 2. 外部节点将更新操作发给primary 节点 3. primary 节点进行并发控制即确定并发更新操作的先后顺序 4. primary 节点将更新操作发送给secondary 节点 5. primary 根据secondary 节点的完成情况决定更新是否成功并将结果返回外部节点
在工程实践中,如果由primary 直接同时发送给其他N 个副本发送数据,则每个 secondary 的更新吞吐受限于primary 总的出口网络带宽,最大为primary 网络出口带宽的1/N。为了 解决这个问题,有些系统(例如,GFS),使用接力的方式同步数据,即primary 将更新发送给第一 个secondary 副本,第一个secondary 副本发送给第二secondary 副本,依次类推。
数据读取方式 数据读取方式也与一致性高度相关。如果只需要最终一致性,则读取任何副本都可以满足需求。如果需要会 话一致性,则可以为副本设置版本号,每次更新后递增版本号,用户读取副本时验证版本号,从而 保证用户读到的数据在会话范围内单调递增。使用primary-secondary 比较困难的是实现强一致性。
将副本分散到集群中个,假设primary 也是随机的确定的,那么每台机器 上都有一些数据的primary 副本,也有另一些数据段的secondary 副本。从而某台服务器实际都提供 读写服务。 - 由primary 控制节点secondary 节点的可用性。当primary 更新某个secondary 副本不成功 时,primary 将该secondary 副本标记为不可用,从而用户不再读取该不可用的副本。不可用的 secondary 副本可以继续尝试与primary 同步数据,当与primary 完成数据同步后,primary 可以副本 标记为可用。这种方式使得所有的可用的副本,无论是primary 还是secondary 都是可读的,且在一 个确定的时间内,某secondary 副本要么更新到与primary 一致的最新状态,要么被标记为不可用, 从而符合较高的一致性要求。这种方式依赖于一个中心元数据管理系统,用于记录哪些副本可用, 哪些副本不可用。某种意义上,该方式通过降低系统的可用性来提高系统的一致性。
primary 副本的确定与切换 在primary-secondary 类型的协议中,另一个核心的问题是如何确定primary 副本,尤其是在原 primary 副本所在机器出现宕机等异常时,需要有某种机制切换primary 副本,使得某个secondary 副本成为新的primary 副本。
通常的,在primary-secondary 类型的分布式系统中,哪个副本是primary 这一信息都属于元信 息,由专门的元数据服务器维护。执行更新操作时,首先查询元数据服务器获取副本的primary 信 息,从而进一步执行数据更新流程。
由于分布式系统中可靠的发现节点异常是需要一定的探测时间的,这样的探测时间通常是10 秒级别,这也意味着一旦primary 异常,最多需要10 秒级别的 发现时间,系统才能开始primary 的切换,在这10 秒时间内,由于没有primary,系统不能提供更 新服务,如果系统只能读primary 副本,则这段时间内甚至不能提供读服务。从这里可以看到, primary-backup 类副本协议的最大缺点就是由于primary 切换带来的一定的停服务时间。
数据同步 不一致的secondary 副本需要与primary 进行同步(reconcile)。
通常不一致的形式有三种:一、由于网络分化等异常,secondary 上的数据落后于primary 上的 数据。二、在某些协议下,secondary 上的数据有可能是脏数据,需要被丢弃。所谓脏数据是由于 primary 副本没有进行某一更新操作,而secondary 副本上反而进行的多余的修改操作,从而造成 secondary 副本数据错误。三、secondary 是一个新增加的副本,完全没有数据,需要从其他副本上 拷贝数据。
对于第一种secondary 数据落后的情况,常见的同步方式是回放primary 上的操作日志(通常是 redo 日志),从而追上primary 的更新进度。对于脏数据的情况, 较好的做法是设计的分布式协议不产生脏数据。如果协议一定有产生脏数据的可能,则也应该使得 产生脏数据的概率降到非常低得情况,从而一旦发生脏数据的情况可以简单的直接丢弃有脏数据的 副本,这样相当于副本没有数据。另外,也可以设计一些基于undo 日志的方式从而可以删除脏数据。 如果secondary 副本完全没有数据,则常见的做法是直接拷贝primary 副本的数据,这种方法往往比 回放日志追更新进度的方法快很多。但拷贝数据时primary 副本需要能够继续提供更新服务,这就 要求primary 副本支持快照(snapshot)功能。即对某一刻的副本数据形成快照,然后拷贝快照,拷贝 完成后使用回放日志的方式追快照形成后的更新操作。