说一说单元化
为什么要有单元化
单元化, 顾名思义, 用多AZ的实例来提供服务。现在稍微有点体量的公司都在做单元化,那为什么要做单元化的呢,总结而言有以下几个原因
1. 多AZ(可用区) 容灾。
2. 服务器体量太大,单一IDC没有足够的机器。
3. 提升用户请求访问速度/方便海外观众访问。
单元化演进:
容灾是单元化最重要的应用场景之一,这里我们先聊聊容灾的演进史。借此引入单元化的话题。
单数据库
当一个网站刀耕火种之际,往往是多机服务 + 单mysql DB运行,这样我们一个服务迅速上线了。
半同步场景
这个网站的运气比较好,顺利经过了初创期,DBA未雨绸缪,防止单DB跪了无法启动服务,他们购买了新的两台DB,开启了mysql 半同步机制,并设置半同步超时报警,一个看起来非常稳固的系统就此诞生。
多机房容灾
直到有一天,网站IDC的光纤被挖断了 ,网站停止了服务,连续可用天数戛然而止。在开了无数次会议之后,网站决定开启异地机房,实现机房级容灾。
为了保证数据的强实时性,两IDC都读写DB1, 多IDC进行数据异步同步。如果DB1出问题,两数据库瞬间切到IDB3,能达到秒级RTO。
当DB1恢复时, 再把没同步的数据和DB3进行合并,按最后发生为准。(update 可能被覆盖,delete 未被更改的话有效,insert判断有无覆盖,当然也少不了人工对账)
平行世界,dba和业务人员合并的困难和业务对账让人头疼。他们决定采用如下架构,异可用区至少有一个实例完全同步才返回,牺牲一部分可用性换取强一致性。
异地伪多活
炎热的夏季让整个城市停止了电力供应。网站又陷入了停滞,为了应对新的问题,城市级容灾的方案出现了。
在这样的架构设计下, 主城市跪了,异地机房切换到 idc3的db5。当然这种情况并不能达到RTO为0,毕竟考虑CAP都是要取舍的。 一段时间内提供只读服务,极端情况下开写服务最后进行人工对账。
异地真多活
这时候绝大部分公司的演进之路告一段落了,但如果我们的体量过于巨大,暴露出了两个核心问题。
- 单AZ实际依然承受着全量的系统流量和连接资源,单AZ机房或者电力达到极限面临不能扩容的困扰。
2. 异地伪多活,真实切换的时候,回出现信心不足。
为了回避上述情况就需要数据库的真多活解决上述问题了。
当然异地真多活,会引入一系列新的问题:
性能侧:
1 很多服务内的查询将变成分布式查询,耗时会变长。
2 数据库同步更慢,更加复杂。
使用侧:
1 为了应对路由选择,需要更多的数据改造。
如何实现单元化:
明确目标: 保障核心业务不受或着受可接受的影响,而不是保证所有业务不受影响。所以第一步问自己几个问题
- 哪些功能/业务需要单元化,功能保成什么样子
- 哪些业务需要强实时同步,哪些最终一致就可以。
具体实施:
实施步骤主要分为时间线和行为线。
时间线: 正常情况, 异常处理 [1] ,系统恢复。
行为线: 路由选择,数据同步,系统负载控制。
- 外部访问选择怎样的路由. 【路由表,就近路由】
2. 内部系统互相调用RPC路由如何设计. 【全局唯一场景路由,时间延迟不敏感如何恢复】
3. 数据的路由方式 【取决于单元化是真双活还是伪双活】
数据同步:
强一致: paxos, mysql 半同步。
最终一致: mysql 异步binlog同步, 外部CDC同步, RPC/消息双写。
主动拉: 数据回源拉取。
系统负载控制: 保证灾难时系统负载能正常应对
经典案例:
举几个例子,各自有它的代表性
优酷点播弹幕:
业务介绍:
常规web服务模式: 弹幕审核后,入库,入库完成后更新cache。用户请求从cache中取。下面是一个简化了的主逻辑的图:
目标:
- 最终保证弹幕能同步到异地机房【20s-30s】。
- 主机房故障时,异地机房能提供基本的读功能,一定时间内不可写可接受。
- 切回主库数据不丢,主机房不会有故障。
具体措施
优酷账号:
在帐号体系的异地多活场景,最需要保护的是用户的登录场景,需要保证的是99.999%的用户在异地能够登录。
业务目标分析:
- 使用异地伪双活,发生故障迁移,可以停写,保证绝大多数用户能正常登录,也不会引起故障错乱。
- 登录态故障迁移时允许丢失,可使用回源访问,而不是全量同步缓存数据。
网商单元化:
目标: 不丢数据,仅主从切换停写,强一致
具体实施:
不可分模块: 放在唯一主机房GZONE,其他机房热备。考虑跨机房访问GZONE 时延很高,创新性的使用了CZONE。工程师们发现了大多数应用场景有读写时间差。对于实时要求不高的情况,可以在每个城市部署可供读取的CZONE(只读), 例如用户修改密码之后,起码3秒之后才会完成下次登陆。
正常同步 | 异常切换 | 数据恢复 | |
---|---|---|---|
路由 | cookie hash 到其他Rzone | 修改路由规则 | 恢复路由规则 |
数据同步 | Paxos数据同步 | Paxos主从切换 | 将主切回原单元 |
机房负载 | 无需 | 无需 | 无需 |
参考
- ^ 首先恢复主从同步,再想如何切换回原来的主