前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分布式概念-中心化副本控制机制

分布式概念-中心化副本控制机制

作者头像
春哥大魔王
发布2020-02-19 11:47:52
4330
发布2020-02-19 11:47:52
举报
文章被收录于专栏:服务端技术杂谈

前面的文章提到过副本是分布式系统中提升数据可用性,数据容错性,以及读吞吐的主要方式,对于多个副本数据一致性处理就是比较复杂且重要的话题。

CAP定理中我们知道,要设计满足强一致性,且在网络分区出现时还满足可用性的方案是不可能的,因此实际工程副本协议设计时,需要在可用性,一致性,分区容忍性等角度按照业务场景进行折中。

实现副本控制协议可以有中心化和去中心化两类实现方案。今天我们主要说一下中心化的副本控制机制,下一篇介绍去中心化的控制机制。

中心化的控制机制的主要思路是,建立一个中心化的协调节点进行数据操作协调,所有操作先走这个中心节点,进而实现副本更新,数据一致性的处理。

其架构方案简单清晰,所有副本相关控制操作交给中心节点完成,并发控制由一个中心节点完成,使得分布式并发控制问题简化为单机并发控制问题。

也就是在多个节点同时需要修改副本数据时,需要解决因并发造成的“写写”,“读写”等并发冲突问题,单节点场景下的并发控制总是更简单一些,一般通过加锁方式就可以解决。

分布式场景中处理并发大部分情况也是通过加锁解决的,但是分布式场景下因为没有中心化节点方便的进行统一锁管理,就需要完全分布式的锁系统,这样整个设计方案就会更复杂。

中心化节点可以很好的解决这种复杂问题,但是带来的风险是整个系统的可用性需要依赖这个中心节点,一旦中心节点不可用或是网络问题造成中断,整个系统将暂时失去服务能力,这也是中心化系统具备的单点问题。

中心化副本控制协议主要有primary-secondary协议。副本被分为两类,只有一个副本作为paimary副本,其他副本为secondary副本。primary副本作为中心节点,负责副本的数据维护,如数据更新,并发控制,协调一致性等操作。

如果让你设计一个基于primary-secondary协议的中心化控制副本系统你需要怎么做呢?

我们需要解决以下几个主要流程问题:

  1. 数据更新流程
  2. 数据读取流程
  3. primary副本如何确定,出现问题时如何切换
  4. 数据多个副本之间如何同步

数据更新流程

  • 在数据进行更新时,外部节点数据都统一交给primary副本,由其进行协调完成。
  • primary节点确定外部节点请求的更新操作数据,完成并发控制。
  • primary节点将更新操作发送给secondary节点。
  • primary更加secondary节点完成情况决定更新成功与否,进而将响应返回到外部节点。

这种方案中存在这样一个问题,如果primary节点需要同步N个secondary副本,受限于网络吞吐,每个secondary副本会占用网络出口的1/N。

所以为了解决这种问题,一些系统如GFS,采用接力同步数据的方式,即当primary将更新发送给第一个secondary副本后,第一个secondary副本发送给第二个secondary副本进行数据同步,以此类推以解决parimary网络吞吐的限制。

数据读取方式

数据读取方式的处理决定了数据一致性的强弱,如果只需要最终一致性,则读取任何副本都可以满足需求。

如果需要会话强一致性,需要为每个副本设置版本号,每次更新之后维护递增版本号,用户读取副本时验证版本号,从而实现用户读取数据在会话范围内的单调递增。

采用primary-secondary协议最困难的是实现强数据一致性的要求。

我们可以想一下,在工程实践过程中如果有强一致数据要求你会有几种方案呢?

我大概想起有三种,常用的相信大家会采用类似于读写主库的方案以解决主从同步延迟带来的一致性问题吧。

同样在primary-secondary协议中,由于数据更新流程都是由primary控制的,primary副本数据一定是最新的,如果始终只读primary副本中的数据,可以实现强一致性。

但如果读都放到了primary副本上,secondary副本将不会在提供读服务,将primary副本分散到整个集群当中,每台机器上都有一些数据的primary副本,也有另一些secondary副本,从而使得某台服务器具有读写服务能力,这样secondary完全是数据安全性的一种备份了,很大一定程度限制了分布式系统的优点。

primary-secondary协议中,primary副本也控制着secondary节点的可用性,当primary更新某个secondary副本不成功时,会将此secondary副本标记为不可用,从而用户不再读取该不可用的副本。

不可用副本可以继续尝试从primary副本同步数据,当两者完成数据同步后,primary副本将此secondary副本标记为可用副本。这样在整个集群中,这个时间段的所有副本都是可用的,也是可读的,所以在某个确定的时间段内,一个secondary副本和primary副本之间要么是一致的最新状态,要么是标记为不可用的,从而满足了强一致性的要求。

当然这种方案需要依赖于一个中心元数据管理系统,用于记录哪些副本可用,哪些副本不可用,一定程度上降低了可用性来提高一致性。

primary副本如何确定,出现问题时如何切换

primary-secondary协议中,primary副本如何确定,出现问题时如何切换是个核心问题。当原primary副本宕机时,如何在所有机器中按某种切换机制选出primary副本,使得secondary副本更新为primary副本。

通常在primary-secondary协议中,哪个副本作为primary这个信息是由元数据管理服务决定和维护的,每次做更新操作时,首先查询元数据服务获取副本primary信息,进一步执行数据更新流程。

分布式系统中对节点可靠性发现,需要依赖于探测系统对心跳的分析,所以心跳间隔存在了秒级的延迟。也就是说一旦primary异常,需要秒级发现时间,系统才可以对primary切换,也就意味着这个秒级内系统不能提供更新服务,如果primary提供读服务,这段时间内整个系统甚至不能提供读服务。所以primary-secondary协议带来的最大问题是primary切换带来的服务停顿不可用问题。

数据多个副本之间如何同步

数据不一致的secondary副本需要和primary副本完成数据同步,以达成数据一致。

数据不一致往往由于以下几种问题造成的:

  1. 由于网络异常,secondary上数据落后于primary上的数据。
  2. 在同步primary数据过程中,由于secondary内部问题造成的数据更新操作失败,比如有了多余的修改操作,造成数据问题。
  3. 系统中新增加了一个secondary副本,其完全没有数据,需要从其他副本进行数据复制。

针对于第一种情况,常见的同步方式是,回放primary上的操作日志,通常是redolog,从而追上primary上的数据进展。

对于第二种脏数据情况,比较好的做法是设计分布式协议避免脏数据,一旦发现副本存在脏数据,直接丢弃脏数据副本,此副本数据归零。还可以基于undolog方式,将脏数据删除。

第三种情况,如果新的secondary副本完全没有数据,可以直接将primary副本数据完全拷贝到此副本上,这种方案远比回放追加数据更快速有效。需要primary副本支持我们常说的snapshot功能,可以对某一刻的数据形成快照,然后拷贝数据,拷贝完成后使用回放日志方式追加快照之后的更新操作,完成增量数据同步。

今天我们主要介绍了基于primary-secondary协议的中心化副本数据复制方式,整体上我们可以看到很多一致性协议的算法和工具比如paxos,raft,zk,etcd甚至mysql等的一些影子,他们整体设计思想上存在诸多类似,只不过会有不同的设计取舍,同时在不同的业务要求下做事情的侧重点也不一样,如果意犹未尽可以基于raft自己搞一个多副本同步组件了,下一篇我们聊聊去中心化的副本控制方式。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 春哥talk 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档