二.大规模集群中保证数据一致性
事实上网络分裂很难从根本上避免,我们在设计系统时都是假设网络分裂一定会出现,基于此思考应该采用什么方案保障系统在网络分裂时能正常运作。
我们的方案是在每个数据中心都建设三个独立的数据园区,可以做到在任意一个数据园区出现网络分裂等故障,甚至彻底变成园区孤岛后,另外两个数据园区可以无损承接整个数据中心的请求。
三园区容灾的关键就是数据一致性。我们需要做到在分裂出去的那个数据园区的数据在其他园区有个强一致的副本,这样请求落到其他两个园区后,可以无损完成服务,此外在故障园区恢复后,数据在所有园区还能自动保持强一致。微信后台实现了基于Quorum算法,对数据有强一致性保证的存储系统——KvSvr(这一存储系统另文介绍)。此外还有可以提供三园区强一致保证的可靠异步队列,这次就应用在这个红包系统中。前边提到的部署在接入服务的红包文件实际上也是可以实现三园区容灾的,我们在每台接入服务部署的红包文件都会在其他数据园区有个备份。在某个数据园区故障时,我们可以在其他数据园区发放故障园区的红包。
今年活动红包总量非常大,活动形式也更丰富,我们在以下方面做了优化。
1.服务性能
为提升各个服务模块的处理性能,我们通过压测和Profiler分析,发现了不少性能瓶颈点,做了大量优化。
2.业务支撑能力
支持更加复杂的业务场景,并在客户端和服务器都加入了很多可以后期灵活调整的预埋能力,以更好地服务产品运营。
3.可用性
不断提升系统可用性是我们一直努力的目标,以下5点很好地提高了系统的可用性。
1.系统容量评估与配额
对系统的容量需要有个准确的评估与验证,并结合业务设计合理的配额方案和降级方案,尽可能保障系统不会过载。例如,我们评估并验证完系统每秒最大拆红包量后,就可以在处理用户摇一摇请求时,限制系统每秒最大发放红包配额,这就间接保证了拆红包量不会超出处理能力。
2.过载保护
服务如果出现过载了,必须有能力自保,不被压垮,并且不扩散到系统其他的服务。我们在后台的服务框架层面具备通用的过载保护能力:服务如果处理不过来,就按请求的优先级尽快丢掉超出处理能力的请求,保证服务的有效输出;上游调用端在部分服务实例过载时,能自动做负载均衡调整,将请求调整到负载较低的服务实例中;上游调用端发现大部分服务实例都出现过载,也可以主动丢掉部分请求,减轻后端服务器的负担。
3.减少关键路径
减少核心用户体验所涉及的步骤和模块,集中力量保证关键路径的可用性,从而在整体上提高可用性。我们把活动红包的信息流和业务流进行异步化,就是基于这个考虑。跟用户核心体验相关的抢红包操作,在信息流中的接入服务、红包简化逻辑服务和红包异步队列(入队)这三个服务模块参与下即可完成。这三个服务模块是可以比较容易用较低成本就做到高可用的,可以较好地规避业务流和资金流中几十甚至上百个服务模块可能出现的风险。
4.监控指标
我们需要对系统的真实负载情况有准确及时的了解,就必须要有一套高效、可靠的监控系统,同时还要有一套有效的监控指标,监控指标不是越多越好,太多了反而会影响判断,必须要有能准确反映问题的几个核心指标。在我们系统里,这些核心指标一般在基础框架集成,根据经验来看,其中一个很有用的指标是服务的最终系统失败。我们把服务的失败分为两类:逻辑失败和系统失败。系统失败一般是服务暂时不可用导致,是可通过重试来自动解决的,如果请求重试若干次仍然为系统失败,就产生最终系统失败。通过最终系统失败通常可以快速定位到异常的服务,及时处置。
5.人工介入
我们在红包系统内预置了很多配置开关,当自动运作的过载保护无法发挥预期作用时,可以通过人工介入,使用这些保底的手动开关迅速降低负载、恢复服务。