为什么需要业务高可用?
有些业务比较重要【银行】,或者用户巨多分布不同地区【如微信、推特】的服务,如果出现故障不可用,会有难以承受的后果,那么则需要做业务高可用了。
如何做业务业务高可用
业务多活,需要考虑的就不仅仅是单台机器故障了,还需要考虑到机房级的故障,地区级的灾难【如美加大停电、海底电缆断了】,这种就需要做异地多活了。不要把鸡蛋放在同一个篮子里。
异地多活的方案有:
- 同城双活
- 跨城双活
- 跨国多活
是否要做业务高可用
是否要做业务高可用?
这是一个值得探讨的问题,需要考虑到业务重要程度、社会影响、建设高可用架构的成本问题。
如,用户只有10w,当然没必要做多活。
再比如,设计到钱、重要业务的,可以考虑做多活。
需要做综合的考虑。
同城双活
同城双活还是比较简单的,能够应对机房级的故障转移,通常的使用者是地区的银行。
并且由于是同城双活,延迟较小,可以用专线提升网络质量。机房间可以做数据的同步,因此是比较简单的。
缺点是,无法应对整个区域的灾难。
跨城多活
跨城双活则是比较麻烦了,因为两个城市之间可能相距几千公里,延迟通常在50ms~100ms了,即使是专线也提升不大了,这是由物理定律限制的。
并且由于相距较远,相连的光缆比较远,被破坏、出问题的可能性就越大。
因此如果要做所有数据的同步是不太可能的,一是数据量较大,有些数据不同步也可以;一是延迟太大,比如网络糟糕的情况,可能要过几秒才能同步过去,然而在这几秒内用户可能已经从这个机房里取这些数据了。
举个例子 ,转账业务,如果一个用户进行转账,但由于数据同步不及时,用户再次刷新可能余额还在,这种会出现无法预料的后果。
但一些数据的一致性要求没那么高,则可以使用跨城多活的架构了。如 :用户登录的状态,这个就没必要同步了,大不了再让用户登录一次呗,或者路由到用户上次登录的机房服务器取出用户的信息就可以了。
跨国双活
跨国双活则是更大的的延迟,更难以同步数据。解决方案也是多种多样 :
- 为某个地区的用户提供特供版 :如亚马逊中国,两个平台数据不互通。这样还可以规避一些风险
- 只读业务做多活 :如谷歌搜索数据,同步没那么及时也没什么关系。
- 同步没那么及时也没关系 :如美国的旁友发了一条推特,在东半球晚几秒收到也没什么问题。
异地多活的设计思路
上面介绍了三种业务高可用的方案,分别都有不同的优缺点,汇总一下 :
- 同城双活 :延迟低,同城的机房可以实现近似一个机房的效果
- 跨城多活 :延迟高,需要考虑哪些同步、业务上如何解决这种延时
- 跨国多活 :延迟更高,可以采用不同地区独立业务系统。
针对跨城多活和跨国多活的难点,有以下技巧可以借鉴 :
-
只做核心业务的数据同步
思考哪些业务是核心的,比如对于微信来说,聊天是最核心的,什么直播、摇一摇什么的都是非核心业务。对于一个登录系统,登录才是最重要的,注册、修改信息都是非核心的。
-
核心数据的最终一致性
距离较远,没必要做强一致性,保证最终一致性即可。
比如用户修改了签名,五分钟能同步就可以了,可以将用户的信息缓存到本地,读取的时候判断远程的修改时间是否大于缓存中用户信息的修改时间。
-
使用多种方式同步
MySQL和Redis的数据同步都有一定的缺陷,有时并不一定可以满足我们的需求,需要结合业务来看。
- 消息队列 :如将信息放入消息队列,其他中心来取消息
- 回源读取 :如本地没有信息,则去有信息的中心来取数据
- 重新生成数据 :登录失效了,那就让用户重新登录一次
-
只保证绝大多数用户的可用性
可以采用补偿受到影响的用户。
异地多活的设计步骤
业务分级
分为核心业务和非核心业务,评定标准有三个 :
- 业务的用户访问量 :比如登录系统,登录使用人数肯定比注册、改密的多
- 核心业务 :如微信的主要业务是聊天,而不是朋友圈
- 设计到钱的业务 :钱都是比较敏感的
数据分类
数据分类的标准有 :
- 数据量 :数据量越大,延迟越高,越要考虑从业务角度来解决
- 唯一性 :用户的唯一ID,可以通过设计一个算法来解决
- 实时性要求
- 是否可丢失 :某些数据不可丢失
- 是否可恢复 :用户登录失效,在登录一次就可以了
数据同步的方式
数据同步的方式 ;
- 使用消息队列同步
- 重复生成
- 存储系统同步 :使用MySQL\Redis自带的同步方案
异常处理
再严密的系统,都有可能出现异常情况。针对这些异常情况,要有相应的预案 :
- 采用多通道同步,降低概率
- 数据修正 :修正异常的数据
- 安抚用户
接口级的故障应对方案
机房级的故障可能性很小,毕竟美加大停电也不是天天发生。
接口级的故障更常见,一样会出现严重后果。
由于服务之间会互相调用,某一个服务出现响应缓慢、不可用状态【死循环、数据库慢查询、内存泄露一直GC、泛洪攻击、突发流量】,都有可能出现服务雪崩,整个系统都GG了。
针对这种情况,在发布流程上和部署上 :
- 首先要确保的是服务高可用
- 发布前做好严密的测试
- 灰度发布
针对接口级故障,在业务上也有对应的解决方案和设计思想。
思想 :确保核心业务可用,边缘业务是可以牺牲的。
业务上的处理 :
- 降级 :停掉边缘业务,保证核心业务可用
- 熔断 :调用某个有问题的接口,直接返回错误
- 限流 :基于请求限流\基于资源限流
如果是云部署的情况,可以使用 :
- 扩容 :包括紧急扩容‘、平滑扩容
- 排队 :将请求放在队列中,等系统资源不是那么紧张时再去取。
思想 :确保核心业务可用,边缘业务是可以牺牲的。
业务上的处理 :
- 降级 :停掉边缘业务,保证核心业务可用
- 熔断 :调用某个有问题的接口,直接返回错误
- 限流 :基于请求限流\基于资源限流
如果是云部署的情况,可以使用 :
- 扩容 :包括紧急扩容‘、平滑扩容
- 排队 :将请求放在队列中,等系统资源不是那么紧张时再去取。