分布式系统学习(五)异地多活高可用

目的:
  1. 避免机房级别的故障导致服务不可用
  2. 保持无限扩展的能力,机器数量不受限于单机房容量
  3. 用户就近接入,全球化部署
设计原理
  1. 异地多活是个AP方案,在一定程度上舍弃了一致性
  2. 只保证核心业务实现异地多活,并不是所有业务都可以实现异地多活(比如注册不做异地多活,登录可实现异地多活)
遇到的挑战及问题
路由实现

让特定用户访问特定的机房,尽量避免跨机房调用

机房故障切换数据不一致问题解决

在发生机房级别的failover时,如果目标机房的状态没有和故障机房完全同步,且同步的消息丢失,没有同步的状态就会丢失。
解决这一问题的思路又是CAP的选择。选择可用性的话,就是什么都不做,优先使大部分数据正常流转,异常数据事后修复。如果要保证一致性,那么一个方法是:当发生failover后,锁定老数据的修改(使用时间戳判断,锁定所有老数据),直到所有数据复制之前,都不允许写入。在此期间,新数据可以产生,但是修改老数据时会直接在数据库中间件层报错。

数据同步方案
  1. 依赖Mysql等存储系统的底层实现
  2. 自研发消息队列等做同步
  3. 业务可以二次读取和回源读取
  4. 数据同步很可能会出现数据冲突,一种方法是通过版本号等做冲突解决,一种方法是每条固定的记录只能在一个机房写,如果有写错机房的情况直接由数据库中间层拒绝
跨机房调用不可避免

单元化首先要考虑的问题是如何进行单元化分片,一般来说可以根据用户的UID进行流量和数据的分片,比如可以使用UID的后两位将流量和数据分成100个片,多个分片组成一个单元。使用UID分片时,比如转账操作,会同时操作两个UID下的账户,这种情况不避免的需要进行跨单元调用,这时尽可能通过一定的设计将跨单元的操作进行异步化处理,避免延时问题对用户体验产生直接影响。还有一种情况像是淘宝这类的交易业务,还存在商家和商品等信息,如果使用买家UID进行分片,就意味着非买家维度的信息需要做一定的妥协,一般会将这些全量数据进行全局复制,复制到所有机房内,当买家对非买家维度数据访问时,可以接受“最终一致”的就直接读买家单元内非买家的非实时数据,不能接受“最终一致”的则需要跨单元访问写单元,比如交易减库存,也就是数据集中写写单元,然后复制到所有单元,由每个单元进行本地读,最终达到买家的所有操作在买家所在的单元内尽可能的读写封闭。

数据同步回环问题解决
  1. 通过附加表:B机房拉取A机房的数据时先插入一条记录表明是A机房产生的数据。之后A机房拉取B机房数据时,发现是自己的记录则会丢弃
  2. GTID
参考:

一个理论,三个原则,多个通过步骤:阿里游戏异地多活设计之道
分布式系统 - 关于异地多活的一点笔记 - overview
异地多活设计辣么难?其实是你想多了!
饿了么异地多活技术实现(一)总体介绍
Zookeeper系列(2)–2PC、3PC及其应用
专访阿里巴巴毕玄:异地多活数据中心项目的来龙去脉
多活架构思考总结
饿了么MySQL异地多活的数据双向复制经验谈(附PPT)
异地多活场景下的数据同步之道

你可能感兴趣的:(分布式)