分布式系统你会设计了吗?不会阿里架构师来教你设计(2)
例如系统中3个数据o p q, 每个数据段有三个副本,系统中有4台机器: 优点: 恢复效率:高。可以整个集群同时拷贝 可用性:好。机器donw机的压力分散到整个集群 工程中完全按照数据段建立副本会引起元数据开销增大,这种做法是将数据段组成一个大数据段。 2.1.6 本地化计算 如果计算节点和存储节点位于不同的物理机器,开销很大,网络带宽会成为系统的瓶颈;将计算调度到与存储节点在同一台物理机器上的节点计算,称为计算本地化。 2.2 基本副本协议 2.2.1 中心化副本控制协议 中心化副本控制协议的基本思路:由一个中心节点协调副本数据的更新、维护副本之间一致性,并发控制 并发控制:多个节点同时需要修改副本数据时,需要解决的“写写”、“读写”等并发冲突 单机系统使用加锁等方式进行并发控制,中心化协议也可以使用。缺点是过分依赖中心节点。 2.2.2 primary-secondary协议 这是一种常用的中心化副本控制协议,有且仅有一个节点作为primary副本。有4个问题需要解决: (1) 数据更新基本流程 由primary协调完成更新 外部节点将更新操作发给primary节点 primary节点进行并发控制并确定并发更新操作的先后顺序 primary节点将更新操作发送给secondary节点 primary根据secondary节点的完成情况决定更新是否成功,然后将结果返回外部节点 其中第4步,有些系统如GFS使用接力的方式同步数据,primary -> secondary1 ->secondary2,避免primary的带宽称为瓶颈。 (2) 数据读取方式 方法一:由于数据更新流程都是由primary控制的,primary副本上数据一定最新。所以永远只读primary副本的数据能够实现强一致性。为了避免机器浪费,可以使用之前讨论的方法,将数据分段,将数据段作为副本单位。达到每台机器都有primary副本的目的。 方法二:由primary控制secondary的可用性。当primary更新某个secondary不成功时,将其标记为不可用。不可用的secondary副本继续尝试与primary同步数据,直到成功同步后转为可用状态。 方法三:Quorum机制。后续讨论。 (3) primary副本的确定与切换 如何确定primary副本?primary副本所在机器异常时,如何切换副本? 通常在primary-secondary分布式系统中,哪个副本为primary这一信息属于元信息,由专门元数据服务器维护。执行更新操作时,首先查询元数据服务器获取副本的primary信息,进一步执行数据更新流程。 切换副本难点有两个方面:如何确定节点状态以发现原primary节点出现异常(Lease机制)。切换primary后不能影响一致性(Quorum机制)。 (4) 数据同步 当发生secondary与primary不一致的情况,需要secondary向primary进行同步(reconcile)。 不一致的原因有3种: 网络分化等异常导致secondary落后于primary 常用的方式是回放primary上的操作日志(redo日志),追上primary的更新进度 某些协议下secondary是脏数据 丢弃转到第三种情况;或者设计基于undo日志的方式 secondary是一个新增副本完全没有数据 直接copy primary的数据,但要求同时primary能继续提供更新服务,这就要求primary副本支持快照(snapshot)功能。即对某一刻的副本数据形成快照,然后copy快照,再使用回放日志的方式追赶快照后的更新操作。 2.2.3 去中心化副本控制协议 去中心化副本控制协议没有中心节点,节点之间通过平等协商达到一致。工程中唯一能应用在强一致性要求下的是paxos协议。后续介绍。 2.3 lease机制 2.3.1 基于lease的分布式cache系统 (1) 需求:分布式系统中有一个节点A存储维护系统的元数据,系统中其他节点通过访问A读取修改元数据,导致A的性能成为系统瓶颈。为此,设计一种元数据cache,在各个节点上cache元数据信息,使得: 减少对A的访问,提高性能 各个节点cache数据始终与A一致 最大可能处理节点down机、网络中断等异常 (2) 解决方案原理: A向各个节点发送数据的同时向节点颁发一个lease,每个lease具有一个有效期,通常是一个明确的时间点。一旦真实时间超过次时间点则lease过期 在lease有效期内,A保证不会修改对应数据的值。 A在修改数据时,首先阻塞所有新的读请求,等待之前为该数据发出的所有lease过期,然后修改数据的值 (3) 客户端节点读取元数据的流程 if (元数据处于本地cache && lease处于有效期内) { 直接返回cache中的元数据;} else { Result = 向A请求读取元数据信息; if (Result.Status == SUCCESS) { WriteToCache(Result.data, Result.lease); } else if (Result.Status == FAIL || Result.Status == TIMEOUT) { retry() or exit(); }} (4) 客户端节点修改元数据的流程 节点向A发起修改元数据的请求 A收到修改请求后阻塞所有新的读数据请求,即接受读请求但不返回数据 A等待所有与该元数据相关的lease超时 A修改元数据并向节点返回修改成功 (5) 优化点 A修改元数据时要阻塞所有新的读请求 (编辑:ASP站长网) |