醍醐灌顶!异地多活架构设计看这篇就够了
👉目录
1 关于基础架构
2 关于异地多活
3 写时延是关键
4 写量大拆分片
5 做隔离拆分片
6 其他影响因素
7 数据复制架构
8 数据影响路由
9 架构选型模式
01
高可用,分布式系统中节点众多,引发故障不可避免,如何减少故障的影响,尽快从故障中恢复,就是高可用设计的关键; 高性能,大体量业务的海量请求,需要软件系统能够应对大并发量能力,具备强大的吞吐量,而且要有更短的响应时延; 高扩展,功能迭代、请求模型、外部环境都是变化不定的,软件系统需要针对这种种变化,作出良好设计,以便灵活应对; 低成本,软件系统往往是一种商业行为,需要关注商业价值,其构建要衡量投入产出比,最小化成本实现最大化商业价值; 安全性,软件系统安全性要求,需防范数据泄露、保护用户隐私、防止非法访问及操作,确保系统稳定可靠,维护用户权益; 多功能,业务是多变的,架构设计的前瞻性归根到底是有局限性的,未知的未知对架构的破坏性巨大,是复杂性的根本所在。
02
单机器,业务起步阶段,体量非常小,单机部署就能够支撑,这时候面临的单机故障可能会是磁盘损坏、操作系统异常、数据误删等,为了应对这种故障,避免数据丢失,需要做一些数据备份,搭建主从; 单机房,业务规模增长,体量比较大,需要用到相当多的机器,这时候有了更高的追求,在部署的时候,会将机器部署到不同的机房,以规避单个机房故障带来的影响; 单城市,业务持续增长,体量非常大,同城市内的多个机房已经不能满足业务的容灾需要,如果发生城市级别的灾害,例如台风、地震、洪水等灾害,会使城市成为整个服务的单点。
03
同机房内的往返耗时大约 0.5ms 以内; 同城跨机房往返耗时大约在 3ms 以内; 千里之外的深圳上海跨城市耗时大约在 30ms 以内,北京上海,深圳天津的耗时会更长一些。
跨城容灾的场景,涉及到数据写入和副本复制,一次写请求将产生两倍延时,即 60ms; 业务写请求是否要串行发起 n次写请求,即 60ms 的 n倍; 需要做一些前瞻性设计,当前是能接受 60ms 的 n倍,后续的 n 会不会扩大,会不会扩大到不能接受的地步,在后续的设计中是否能贯彻这一依赖,都需要重点关注; 跨城情况下,网络状况可能会差一些,例如容易产生抖动,这个倒不是大问题,一般来说有能力搭建跨城网络的公司,也有能力保障网络的稳定性,在测试的过程中也发现跨城的耗时挺稳定的,在长达近4个半小时的测试中,最大抖动不超过8毫秒,而且最大耗时在30毫秒以内。
04
05
接入层,根据请求中的相关信息做单元分片路由选择; 逻辑层,只处理归属于本单元分片内的请求; 数据层,单从隔离角度出发,可以做跨城数据的同步复制; 单元化隔离与本文讨论的异地多活跨城容灾的关系不是特别紧密,不过多展开,对于路由的影响在下文中会提到。
06
写后立即读,这种情况,要求读到写入之后的最新值,是一种强一致性的诉求,须通过读写点的方式来解决,实际上就归入到写操作的范畴里面去了; 适当延迟读,这种情况,可以接受读取到历史旧值,满足最终一致性要求即可,可以通过读写入之后同步数据的副本来应对,是本部分讨论的内容。
07
搭建1主4从5实例的架构,分布在3个城市5个 IDC 机房中; 写请求要保证对应的数据写入到1主4从中的3个实例中,即写入主后,要同步到另外2个备,达成多数派要求; 在发生城市故障的情况下,不管哪个城市发生故障,在该城市以外,都有完整的数据可以满足容灾要求。
一般来说,跨城切换更复杂,成本更高; 机器以及机房的故障概率要远高于城市故障; 在某个 DB 实例发生故障的时候,尽量让其发生做同城内进行切换,如果是三地三中心,只要有故障就会发生跨城切换; 三地五中心相对于三地三中心会有机器资源浪费的情况,对于跑不满资源的情况,可以采用混布的方式,通过一些资源隔离的(例如 CGroup)机制,来提高资源利用率的同时,又可避免混布业务之间互相影响。
某城市故障时,将写请求放到异地对等的同城三中心处理,所以,下图中每个同城三中心的实例中都有一部分对等同城三中心实例的数据; 这种容灾模式,在发生城市故障的时候,可能会发生产生重复数据的问题,例如用户在蓝色的 set1 种新增一条数据,发生了城市故障,数据来不及同步到异地的异步备,故障切换,用户的请求已经切换到对等的绿色 set2,此时,用户读不到刚刚新增的数据,就会重新操作; 数据读取时,可以整合本城市的写点数据和对等同城三中心的异步备数据。
维护一个统一的时间位点发生器,每次写操作,都记录时间位点,新增记录记为 Ti(insert); 数据做异步复制的时候,记录复制到的时间位点,记为 Ts(sync); 发生故障时,将故障所在的实例禁写,禁写时间记为 Tb(ban); 有损的情况: Ts < Ti < Tb,即在主写新增的记录在没有复制到备的情况下,用户由于读不到之前在主写写入的数据,而重新尝试写操作,就会产生重复数据; 对于所有新增时间 Ti < Tb && Ts < Tb 的数据,即在故障禁写之前就存在的数据,不能在切换到新写点之后进行更新,因为在 Tb 之前总有数据写操作没有复制到位,如果直接更新,就可能产生写冲突。
在具体进行写操作之前,通过做一次跨城调用记录下该写操作对应的数据属主到未同步名单中; 待该写操作同步到跨城实例后,再将写操作的数据属主从未同步名单中清理掉; 在做数据写入之前,先检查写操作的数据属主是否存在未同步名单中,如果存在,则拒绝该请求; 这种模式,依然是有损的,只是牺牲了极少部分未复制到位的用户,而且数据一致性得到了保障,配合双主互复制使用,可以达到很好的效果。
08
跨城全局数据,数据不分片,主从之间做跨城同步复制; 就近分片数据,数据需分片,由于业务不能接受跨城串行写入的耗时,只能做同城的同步复制,跨城则采用异步复制; 跨城分片数据,数据需分片,每个分片的主从之间做跨城同步复制。
09
📢📢欢迎加入腾讯云开发者社群,享前沿资讯、大咖干货,找兴趣搭子,交同城好友,更有鹅厂招聘机会、限量周边好礼等你来~
(长按图片立即扫码)