受疫情影响,全国各学校的开学均被延期。为避免耽误学生的课业,教育部推出了“停课不停学”政策,鼓励师生积极开展线上教学模式。
赶考状元(上海亿山睦教育科技有限公司)为此积极响应政府号召,向湖北全省一年级到高三的学子免费开放教材的同步在线教学课程,后来进一步扩大至全国范围。这一公益活动获得了很大反响,网站用户注册量和浏览量超过平时数倍。
虽然活动从策划到上线总共只有 4 天时间,赶考网技术团队通过科学决策,及时精密的实施,完成了业务代码改造、架构评估、扩容升级、SQL 优化等工作,期间也和 UCloud UDB 团队紧密合作,在其协助下实现了数据库的架构改造和扩容,很好地承接了 QPS 暴涨 20 倍的访问压力,圆满完成技术保障任务。
下面分享一些我们在此过程中的细节和思考,供有快速扩容需要的企业参考。
公司自 2005 年成立一直专注于 K12 在线教育,此次疫情公益活动构想阶段,业务侧运用此前超过十年的互联网及线下教育经验,快速设计了有效可行的方案,在不少细节上下了功夫,例如加速审核通道,只需两步即可学习的易用性,面向家长推广的二维码等。
技术团队的任务则是提前预判后台流量的迅猛增长,未雨绸缪设计行之有效的预案,查漏补缺,切实保障活动顺利流畅运行。为此我们细致梳理了现有架构的薄弱点,并相应制定了精准有效的扩容方案。
由于我们原先的扩容是稳定慢节奏的,这次预见到了大量访问需求,首要工作是分析现有架构的能力和不足。
此前业务的主应用架构为 ULB 负载+双 UHost 单体架构+分布式缓存+单实例高可用 UDB,用了大量 UCloud 的云组件。我们全面梳理了架构各层模块,对每一层的能力做了评估。ULB 有扛大流量的能力,主要关注后端。UHost 上是应用服务,我们测算了一个部署于 8 核 16GB UHost 上的主站模块能够扛住多大并发请求、应用模块垂直扩容和平行扩容两个方案的优劣对比,最终决定水平扩展。考虑到外围的单体服务接口受主应用流量的带动,也进行了扩容承压的调整。缓存的做法是加大分布式缓存、优化访问缓存。压力最大的是数据库,可能带来性能上的严重瓶颈。
不管是 MySQL、PostgreSQL 还是 MongoDB,我们都采用了 UCloud 的 UDB 托管服务,其中包括核心数据库。相比自建数据库,UDB 提供的高健壮高可用以及免维护的服务,可以让我们更安心专注于上层业务逻辑的构建上。且在数据的安全问题上,UDB 提供了完善的备份和恢复机制,避免数据意外丢失。
最初我们的业务核心数据库选用了高可用 UDB 部署。在业务平稳期,从性价比角度考虑,最开始 UDB 实例配置不高,预估 QPS 最大负载在 3000 以内。业务爆发前夜,首先对 UDB 实例做了垂直升级,大幅度提升了数据库的内存和磁盘配置。这个操作很快,几乎不影响业务访问(只在磁盘升级时有秒级访问中断), 实例的处理性能迅速得到提升。
2、**高性能读写分离 **
但高速增长的业务,给数据库带来的压力预计很快便超过单个 UDB 实例所能承受的极限,因此数据库从单机升级为集群势在必行。
我们设计方案时,获得了 UDB 团队的协助。分析业务的 SQL 请求后,发现读写比例在 50 : 1 左右,属于典型的读多写少业务,于是向我们推荐了一主多从 + 读写分离 Proxy 的数据库集群架构。
在该架构下,主(高可用 UDB )和从(单节点 UDB )之间通过异步复制保持数据同步,业务数据库 IP 改指向读写分离 Proxy 的 IP,由读写分离 Proxy 识别业务 SQL 的读写类型,将写 SQL、事务读 SQL 转发到主, 普通读 SQL 按比例转发到从,转发比例控制台可自由配置。同时,读写分离 Proxy 几乎 100%兼容 MySQL 语法和协议,业务无需改造即可顺畅接入。
通过该架构,似乎可完美解决读多写少业务对数据库的大流量压力问题,但实际上仍有一些至关重要的技术细节需要把握。
其中之一就是读写分离中间件的转发性能问题。从理论上看,可以通过横向添加从节点的办法线性提升数据库集群的读性能,但如果底层从节点数量加上去了,读写分离中间件又是否会成为新的瓶颈?
我们十分重视这个问题,为此首先做了一系列的数据指标估算,包括现有 UDB 实例的性能上限、UDB 在垂直升级后根据现有访问模型估算性能上限、UDB 升级为读写分离主从集群后对读写请求的处理性能和从节点数量的关系等。
第二步则是和 UDB 团队配合做了读写分离 Proxy 的压测。
上述压测实验采用 Sysbench 程序,在两台物理机上模拟了底层 UDB 节点从 1 主线性增长到 1 主 6 从的情况下,整个读写分离集群的读处理性能。从结果可以看出,得益于读写分离 Proxy 对多核 CPU 的充分利用,以及代码层面的多个性能调优, 读写分离 Proxy 具备可靠的转发性能,不构成集群的性能瓶颈。从而保证集群的读性能,能够随着从节点的线性增长,呈现几乎完美的线性增长。
实测数据令人放心,UDB 团队继而帮助制定了整套 UDB 扩容计划,我们的业务代码也相应做了调整,整个方案可以在网站用户几乎零感知的情况下实施。此后,我们后端服务的扩容有条不紊地开始,每天凌晨在业务低谷时执行扩容,先扩容主站应用集群,将数据库升级到读写分离集群,然后逐层向外扩容外围单体服务,整个扩容工作设计合理,快马加鞭实施到位。
公益项目开始后,2 月 1 号到 2 月 10 号短短 10 天内,赶考状元平均日注册用户量由 0.83 万上升到 3 万,最大单日注册用户达 5.8 万。平稳承压了单日 20 万用户的 web/App 访问,顺利地为全国各地区超过 100 万学生免费赠送了在线微课学习、题库练习、作业组等线上服务,为停课不停学“添砖加瓦”,贡献了优质的公益教育资源。
在此期间,我们业务数据库的吞吐量( QPS )暴涨了近 20 倍,目前线上读写分离 Proxy 单实例最高 QPS 已达到 20 万以上,升级到读写分离集群后,通过 1 主 6 从加 2 节点双活读写分离 Proxy 的集群配置,平稳扛住了业务流量的高速增长。我们的技术架构,也成长为一个具有相当规模的中型互联网服务。
在渡过 2 月 10 号这个线上开学高峰后,业务依然在高速发展,虽然主从读写分离集群在应对业务高 QPS 访问上不成问题,但随着业务模块的增多,在 2 月 12 号上午高峰期业务向数据库发起的连接数,已经达到高可用版 UDB 产品 6000 的上限。
为了从根本上解决这个问题,UDB 研发团队建议,将高可用 UDB 的后台架构,从传统的 VIP+代理+DB 的架构升级为其最新开发的漂移 VIP+DB 双主新架构。为此他们连夜制定了透明升级的方案,能够不迁数据在 2 分钟内从旧架构原地升级为新架构,获得我们认可并在凌晨实施,确保第二天业务的正常运行。
新的高可用 UDB 架构,利用稳定的 UCloud 虚拟网络 VIP 管理服务,将架构简化为更朴素的漂移 VIP+DB 双主的实现,在数据链路上减少一次转发,消除一个潜在性能瓶颈,并且简化控制模块,减少不可控因素。同时新架构对数据库( MySQL 和 PG )原生的兼容度更高。
提前规划和快速扩容,给了我们更多的余裕,能去快速应对和解决大流量突发时暴露的其它隐藏问题,最典型的例子是数据库慢查询。
我们后台代码采用了 ORM 框架连接 MySQL,由于 ORM 层屏蔽了底层 MySQL 库表的细节,小部分访问 MySQL 的代码没有考虑到底层 MySQL 的执行逻辑,存在慢查询过多的问题。慢查询的问题,在平时小流量慢增长的情况下影响并不明显,但是疫情期间大流量压力下就变得不容忽视。
UCloud DBA 团队期间提供了诸多帮助,他们在慢查询问题的定位和解决上有丰富的经验。疫情期间,他们克服在家办公干扰多,远程沟通不便等不利因素,通过微信、远程会议等方法随时和我们保持联系,结合我们对业务逻辑的理解,协同定位问题,一起梳理了业务近半年所有新增数据库表并增加索引,最终慢查询的问题得到有效解决。
这次面对突发需求的快速响应扩容,从方案到实施,是云的使用者和云厂商分工协作、发挥各自优势的一个有效实践。我们在业务中广泛使用 UDB,是对于其弹性和全托管这两个核心能力的充分认可。此次协作,也对其快速应对、方案制定、7*24 在线服务等有了更多认识。
据悉,近期 UCloud UDB 团队还将推出快杰 UDB 新产品,其基于计算和存储分离架构构建,并结合 UCloud 数据方舟后端的分层混合存储设计,可实现数据库数据的快速备份和恢复到任一秒能力,有效避免用户误删数据库导致数据丢失以及数据恢复慢等问题,值得期待。