架构师技术联盟的业务多活架构和分布式CAP实战,单元化架构实践的学习笔记
我们不仅仅从淘宝买东西,把钱放到支付宝中,也要从他们能给全国乃至世界十几亿人提供购物平台和支付平台的技术架构中学到一些皮毛。
蚂蚁支付宝是国内最大的支付工具,其在双 11 等活动日当日的支付 TPS 可达几十万级,未来这个数字可能会更大,这决定了蚂蚁单元化架构从容量要求上看必然从单机房走向多机房。
支付宝将单元分成了三类(CRG 架构):
1) RZone(Region Zone):所有可以分库分表的业务系统整体部署的最小单元。每个 RZone 连上数据库就可以撑起一片天空,把业务跑的溜溜的。
2) GZone(Global Zone):全局单元,意味着全局只有一份。部署了不可拆分的数据和服务,比如系统配置等。实际情况下,GZone 异地也会部署,不过仅是用于灾备,同一时刻,同一时刻,只有一地 GZone 进行全局服务。GZone 一般被 RZone 依赖,提供的大部分是读取服务。
3) CZone(City Zone):以城市为单位部署的单元。同样部署了不可拆分的数据和服务,比如用户账号服务,客户信息服务等。理论上 CZone 会被 RZone 以比访问 GZone 高很多的频率进行访问。CZone 是基于特定的 GZone 场景进行优化的一种单元,它把 GZone 中有些有着”写读时间差现象”的数据和服务进行了的单独部署,这样 RZone 只需要访问本地的 CZone 即可,而不是访问异地的 GZone。
"写读时间差现象”是蚂蚁架构师们根据实践统计总结的,他们发现大部分情况下,一个数据被写入后,都会过足够长的时间后才会被访问。
生活中这种例子很常见,我们办完银行卡后可能很久才会存第一笔钱;我们创建微博账号后,可能想半天才会发微博;我们下载创建淘宝账号后,可能得浏览好几分钟才会下单买东西。
当然了这些例子中的时间差远远超过了系统同步时间。一般来说异地的延时在100ms以内,所以只要满足某地CZone写入数据后100ms以后才用这个数据,这样的数据和服务就适合放到 CZone 中。
相信大家看到这都会问:为啥分这三种单元?其实其背后对应的是不同性质的数据,而服务不过是对数据的操作集。
下面我们来根据数据性质的不同来解释支付宝的 CRG 架构。当下几乎所有互联网公司的分库分表规则都是根据用户ID来制定的。
而围绕用户来看整个系统的数据可以分为以下两类:
1) 用户流水型数据:典型的有用户的订单、用户发的评论、用户的行为记录等。这些数据都是用户行为产生的流水型数据,具备天然的用户隔离性,比如A用户的App上绝对看不到 B 用户的订单列表。所以此类数据非常适合分库分表后独立部署服务。
2) 用户间共享型数据:这种类型的数据又分两类。一类共享型数据是像账号、个人博客等可能会被所有用户请求访问的用户数据。比如 A 向 B 转账,A 给 B 发消息,这时候需要确认 B 账号是否存在;又比如 A 想看 B 的个人博客之类的。
另外一类是用户无关型数据,像商品、系统配置(汇率、优惠政策)、财务统计等这些非用户纬度的数据,很难说跟具体的某一类用户挂钩,可能涉及到所有用户。比如商品,假设按商品所在地来存放商品数据(这需要双维度分库分表),那么上海的用户仍然需要访问杭州的商品。
这就又构成跨地跨 Zone 访问了,还是达不到单元化的理想状态,而且双维度分库分表会给整个 LDC 运维带来复杂度提升。
直观的类比,我们可以很轻易的将上述两类数据对应的服务划分为 RZone 和 GZone,RZone 包含的就是分库分表后负责固定客户群体的服务,GZone 则包含了用户间共享的公共数据对应的服务。
GZone 之所以只能单地部署,是因为其数据要求被所有用户共享,无法分库分表,而多地部署会带来由异地延时引起的不一致。
比如实时风控系统,如果多地部署,某个 RZone 直接读取本地的话,很容易读取到旧的风控状态,这是很危险的。
这时蚂蚁架构师们问了自己一个问题——难道所有数据受不了延时么?这个问题像是打开了新世界的大门,通过对 RZone 已有业务的分析,架构师们发现 80% 甚至更高的场景下,数据更新后都不要求立马被读取到。
也就是上文提到的”写读时间差现象”,那么这就好办了,对于这类数据,我们允许每个地区的 RZone 服务直接访问本地,为了给这些 RZone 提供这些数据的本地访问能力,蚂蚁架构师设计出了 CZone。
在 CZone 的场景下,写请求一般从 GZone 写入公共数据所在库,然后同步到整个 OB 集群,然后由 CZone 提供读取服务。比如支付宝的会员服务就是如此。