(2023.08.05 Sat @KLN)
异地多活
高可用的计算/存储架构,设计目的是解决在部分服务器出现故障的场景下,系统能够继续提供服务。极端场景下,字机房断电、火灾、地震、水灾等,系统所有服务器都可能出现故障。即便采用备份,恢复的时间也比较长。此时需要异地多活架构。
异地多活架构的两个关键点如命所示,分别是异地和多活。异地,指的是服务放在不同的地方;多活指不同地理位置的系统都能够提供业务服务。判断异地多活的两个标准:
- 正常情况下,无论用户访问哪个地点的业务系统,都能够得到正确的业务服务
- 某地系统异常情况下 ,访问其他地方的正常业务系统,得到正确的业务服务
异地多活中的活字,与之对应的是备字。备,即备份,正常情况下不对外提供服务,若提供服务则需要大量人工干预和操作,才能让备变成活。
显然异地多活具备不低的代价,保证多个地点的机房同时能对外提供服务。并非所有业务功能都需要异地多活,比如新闻网站仅提供信息,企业内部的IT系统、博客站等,异地多活对这类服务来说成本过高,仅需要备份就就可以。而打车、在线支付等业务,需要保证服务的实时性连续性,异地多活就变得很有必要了。
异地多活架构
- 同城异地
- 跨城异地
- 跨国异地
-
同城异地
在一个城市部署多个机房,之前用专用高速网络连接在一起。该架构优势在于同城,逻辑上可视为一个机房,设计复杂度和成本比较低。但应对自然灾害和城市灾害的能力不高。 -
跨城异地
异地之间距离要远,避免出现区域性大停电和区域性自然灾害的情况。同时,距离远也导致了架构复杂度提升,机房的网络传输速度会降低。
距离的提升导致期间不可控因素也提升。可能导致延迟提升。
网络延迟提升给业务带来了复杂性。真正的多活需要再不同地点部署机房,又要从数据的角度保证业务多活,这就带来看似矛盾的地方:(异地引起的网络延迟导致)数据不一致,会使得业务不会正藏,但跨城异地肯定会导致数据不一致。
解决问题在于数据,根据数据的特性来做架构设计。强一致性的数据,如银行存款余额、支付宝余额,实际上无法做到跨城异地多活。即便实现出来也可能被黑客利用。对数据一致性要求不高,或数据改变不多,或即便丢失也影响不大的业务数据,跨城异地就可以使用了。比如登录数据(数据不一致时重新登录即可)、新闻类网站(日内数据变化较少)和微博类网站(丢失用户发布的微博和评论则影响不大),可应用跨城多活。
- 跨国异地
距离更远,延迟更长。应对的是如下情况:
- 为不同地区用户提供服务
- 只读类业务做多活
每个架构的关键点提炼如下:
- 同城异区
搭建高速网络将两个机房连接起来,达到近似于一个本地机房的效果,可以将两个机房当做本地机房来设计,无须额外考虑 - 跨城异地
在数据不一致的情况下,业务不受影响或很小。设计的目的就是为了解决这个矛盾 - 跨国异地
面相不同地区用户,或提供只读业务,对架构设计要求不高
异地多活设计技巧
异地多活主要针对跨城异地这种复杂度最高的架构。
-
技巧一:保证核心业务异地多活
避免误区:保证所有业务的异地多活
优先实现核心业务的异地多活架构
举例来说,登录是核心业务,但是用户注册和用户信息修改非核心业务 -
技巧二:核心数据最终一致性
通过异地的数据冗余,保证极端情况下业务也能够正常提供给用户。数据同步是异地多活架构设计的核心。避免完美主义误区:所有数据都实时同步。但异地多活理论上不可能很快,这是物理定律决定的。
有几种方法:
- 减少异地多活机房的距离,搭建高速网络
- 减少数据同步,只同步核心业务相关数据
- 保证最终一致性,不保证实时一致性:CAP理论中的BASE理论,业务不依赖数据同步的实时性,只要数据最终能一致就可以
- 技巧三:采用多种手段同步数据
数据同步是异地多活架构设计的核心。各个数据库的存储系统都提供了数据同步功能。一个不得不注意的问题是数据库提供给的同步功能往往有各种问题。MySQL 5.1版的复制是单线程复制,在网络抖动或大量数据同步时常发生延迟较长的问题。Redis 3.0出现的Cluster功能提供主从复制,但是从机down机或主机断开时连接都需要重新连接主机,重新连接都会触发全量的主从复制。
有如下几种数据同步方式:
- 消息队列方式
比如创建用户信息,账号只创建不会修改和删除,可将账号数据通过消息队列同步到其他业务中心 - 二次读取方式
假设消息队列也出现了延迟,用户在A中心注册,访问B中心的业务,B中心暂时拿不到用的账号数据。为解决这个问题,B中心读取本地数据失败,可根据路由规则,去A中心访问一次,也就是二次读取,第一次读取本地,本地失败后第二次读取对端。这样就解决了异常情况下同步延迟的问题。 - 存储系统同步
使用数据库自带的数据复制功能 - 回源读取方式
比如登录的session数据,数据量大,可不同步数据。用户在A中心登录后,又在B中心登录,B中心拿到用户上传的session id后,根据路由判断session属于A中心,去A中心请求session数据。 - 重新生成数据方法
同样是session数据,如果A中心down机,B请求数据失败,则要求用户在B登录,重新生成session数据
- 技巧四:只保证绝大部分用户的异地多活
异地多活设计步骤
-
业务分级
-
数据分类
-
数据同步
-
异常处理
-
业务分级
只有核心业务实现异地多活,降低整体复杂度和实现成本
常见的分级标准有这几种:
- 访问量达的业务:用户的登录、注册、信息管理,其中的登录是访问量最大的业务
- 核心业务:QQ空间和聊天业务 中,聊天是更加核心的业务
- 产生收入的业务:空间广告和聊天业务,空间广告是收入来说。实际上很可能聊天和空间都实现了异地多活
- 数据分类
对数据的特别分析维度包括下面几项
- 数据量:数据量大,则同步延迟的概率越高,同步方案需要考虑对应的解决方案
- 唯一性:多个异地机房才产生的同类数据必须保证唯一。比如用户ID。如果数据要求必须唯一,要么只能一个中心点产生数据,要么需要设计一个数据唯一生成的算法
- 实时性:对数据同步的实时性要求越高,方案越复杂
- 可丢失性:是否可丢失,比如session数据可丢失,但是用户ID不可丢失
- 可恢复性:用户密码丢失,可通过手机号找回;用户账号丢失,就无法找回
下面是三类数据的维度分析
数据 | 数据量 | 唯一性 | 实时性 | 可丢失性 | 可恢复性 |
---|---|---|---|---|---|
用户ID | 每天新增1万注册用户 | 全局唯一 | 5s内同步 | 不可丢失 | 不可恢复 |
用户密码 | 每天1千用户修改密码 | 用户唯一 | 5s内同步 | 可丢失 | 可重置密码恢复 |
登录session | 每天1000万 | 全局唯一 | 无须同步 | 可丢失 | 可重复生成 |
- 数据同步
- 存储系统同步:最简单的同步方式
- 消息队列同步:Kafka,ActiveMQ,RocketMQ等
- 重复生成:cookie,session,缓存数据
数据 | 数据量 | 唯一性 | 实时性 | 可丢失性 | 可恢复性 | 同步方案 |
---|---|---|---|---|---|---|
用户ID | 每天新增1万注册用户 | 全局唯一 | 5s内同步 | 不可丢失 | 不可恢复 | 消息队列同步 |
用户密码 | 每天1千用户修改密码 | 用户唯一 | 5s内同步 | 可丢失 | 可重置密码恢复 | MySQL同步 |
登录session | 每天1000万 | 全局唯一 | 无须同步 | 可丢失 | 可重复生成 | 重复生成 |
- 异常处理
同步延迟、数据丢失、数据不一致等。常见的异常处理方式有以下几类:
- 多通道同步
以多种方式来进行数据同步, 其中某条通道故障的额情况下,系统通过其他方式来进行同步,可以应对同步通道处故障的情况。
以用户账号注册为例。一开始挑选了MQ的方式同步。异常情况下,MQ通道可能中断,也可能延迟严重。为保证新注册的账号能快速同步到异地机房,再增加MySQL同步方式作为备份。除非两种方式都发生故障,不然数据总能同步到异地。
注意,多通道同步有几个关键点
- 采取两通道就可以,多了付出更高成本
- MQ通道和DB同步通道不能采用相同的网络连接,因为网络一旦发生故障,通道将会阻塞。可选方案是一个连接公网,一个连接内网
- 需要数据可以重复覆盖(幂等),无论通过哪个通道写入异地,最终结果都是一样的。新建用户数据符合这个标准,但是密码数据不符合这个标准。
- 同步和访问结合
异地机房通过系统接口进行数据访问。异地的B机房通过接口访问A的系统,获取用户账号信息。
注意,同步和访问相结合方案的关键点:
- 访问通道和数据库同步通道不能采用相同的网络连接/网络通道
- 数据有路由规则,根据数据可推断应该由哪个机房的接口来获取数据
- 有同步通道,故优先读取本地数据,本地数据无法读取再去接口访问,这样可降低跨机房的异地接口访问数量,适用于实时性要求高的数据
-
日志记录
-
用户补偿
Reference
1 从零开始学架构-照着做,你也能成为架构师,李运华著,电子工业出版社
2 excalidraw·
网友评论