为了应对用户规模的增加和交易活动的激增,淘宝购物车近年来进行了一系列技术升级,其中主要集中在扩容与性能优化上。本文将简要介绍这些改进措施,以及它们如何提升购物车的响应速度和用户体验,以实现“又快!又丝滑!”的购物体验。主要包括:
- 淘宝购物车扩容分析与解决方案
- 网络包大小与服务端并行化分析与方案
扩容的背景
首先讲一讲购物车的职责。购物车承载着购前环节中促成购买的职责:对于下单犹豫的用户,用营销等手段提升用户决策效率,对于转化确定性较高的用户,精准的推荐让他买的更多;在购中环节提供流畅的交易体验:优惠计算的准确性和过程的清晰度以及各种业务形态商品的凑单合并结算等。作为在购前链路中直面消费者的重要节点,购物车里的体验问题就显得十分重要且敏感。
分析往年的用户原声可以发现,用户对于扩容有强烈诉求。
So 购物车大刀阔斧般的升级可以说是刻不容缓!
针对全量用户做购物车加购商品上限的扩容,由200(现货120+预售80)扩充至380(现货300+预售80)。
扩容的挑战与解法
▐ 扩容的挑战
每每提到购物车的容量,在扩容功能上线前都会受到一个灵魂拷问为什么我的购物车上限只有120??? 我们内部在进行多轮讨论后,也意识到购物车的整体扩容在技术上和产品设计上都面临巨大的挑战。聚焦在技术上的挑战主要来源于对数据库的直接冲击与扩容带来的交易全链路计算量放大。
- 数据库的挑战
存储瓶颈与相关影响
扩容首先带来的就是存储容量的上涨,按扩容到300的预期估算,存储量上涨就大约达到了2倍,在物理机资源有限的情况下存储量的上涨会同时到来BP缓存率的下降,这样就导致其他用户的数据只能去物理磁盘读取,磁盘IO会成为巨大的瓶颈,进而导致数据库各个操作的RT飙升。
扩容后由于 BP 命中率下降,冷数据访问导致大量读盘,数据库磁盘 IO 会成为巨大瓶颈。
- 实时计算量放大对交易全链路的挑战
现有架构的特点:「分页商品实时计算」
购物车现有的分页设计着实提高了用户进入购物车的秒开体验。
但是遇到类似 跨店满减筛选、降价筛选、消费券筛选等强依赖实时计算结果的产品设计,需要针对用户加购品做全量计算并一次性下发给客户端。
购物车筛选的实现
大促跨店满减报名是类目+商家纬度,营销规则又包含了部分类目黑标的逻辑。 但是购物车跨店满减筛选是商品纬度的判断。所以这里有一个从类目+商家到商品纬度的打平计算的过程。
为了判断商品是否报名了跨店满减,需要调用 营销 进行实时计算。
用户纬度的所有加购品经过 营销 计算后,购物车才能筛选出哪些参与了跨店满减。
下发客户端数据体积过大,导致用户体验变差
下发300+个品的数据包预计约为1M左右,在弱网环境下,按 100KB/s计算,需要的传输时间是10s 左右。
- 购物车已经采用了分页实时计算方案,提高用户秒开体验
- 由于筛选涉及全量下发,扩容会放大对交易链路的计算量且增加购物车本身的性能压力,从而导致用户体验的降低。
▐ 扩容的解法
- 引入 tairsql 提升购物车读性能
以双十一峰值的购物车监控为例,在峰值期间有明显的脉冲流量,且主要流量集中在查询与勾选这两种依赖读db的操作类型,而涉及写db的流量(加购,删除,更新等)明显偏少。
查询购物车的SQL逻辑基本属于简单语句,SQL这种的查询条件主要是用户id、加购状态等。并且购物车数据是按照用户纬度聚合,单次请求返回的数据体积不会太大。
所以我们总结出购物车的流量特点为:
- 典型的读多写少,
- sql返回数据不会太大
- 有瞬时脉冲
- 对RT敏感
根据流量特点在调研多种数据库选型后,并结合营销团队在双十一通过 tairsql 解决买家资产查询的经验后,购物车本次选择云原生内存数据库 tairsql 作为读库提升查询性能。
读写分离
引入tairsql后,峰值期间的读流量全部走tairsql,写流量仍然会对db与taisql执行双写,同时有数据同步任务(精卫任务)做同步兜底。
- 使用tairsql与db做读写分离
- 采用双写+精卫方案保证数据同步
- 预计算
购物车的首页筛选难点在于依赖全量商品实时计算的结果,购物车扩容后势必对筛选造成性能压力。那么是否存在一种方式,能在调用下游服务进行实时计算之前,根据某些规则结合商品属性(商品标签,营销属性等),进行一次过滤,从而减少实时计算商品数呢?
分析现有的筛选产品功能后,针对营销类筛选(跨店满减筛选、预热态筛选、消费券筛选),考虑前置生成商品染色表,记录加购品特征,在营销计算前,根据筛选规则过滤出可能参加指定活动的商品。
预计算链路图示:
预计算链路中通过监听类目信息,优惠规则结合加购底表数据,生成加购商品特征表。当用户发起筛选请求时,和正常的渲染请求一样还是会在实时加购数据中查询全量加购数据的基础信息,之后会结合特征表和筛选规则,筛选出符合规则的商品,这些通过筛选的商品再与后续下游服务交互做实时计算。
端到端耗时组成
近年来内网用户都在吐槽手淘购物车的性能体验不好,也很罕见的在用户舆情里也看到反馈 “购物车卡顿”。在如此激烈的竞争中,购物车不仅是用户购物体验的直接接口,更是电商运营效率的关键所在。一个优秀的购物车系统,应当能承受巨大的并发请求,同时保持数据的准确性与实时性,为用户提供流畅的购物体验。
从性能数据来看从一次用户在购物车内发起网络请求到客户端产生相应变化,耗时组成大致分为“网络传输”、“服务端耗时”、“客户端渲染”三大部分。从服务端的视角结合快速降低耗时的使命,我们针对除客户端逻辑外的优化思路主要有以下几块,具体的细节也会在后文详细展开
网络传输优化:
- 压缩数据:使用如Gzip这样的数据压缩技术或结合业务逻辑做裁剪减少传输数据的大小。
- 缓存策略:合理设置缓存策略,减少不必要的网络请求和包大小。
- 延迟加载:对于购物车非关键资源进行延迟加载,优先加载对用户体验影响最大的内容。
服务端耗时优化:
- 缓存机制:使用内存缓存如tair等,对频繁访问的数据进行缓存,减少网络传输压力。
- 并发处理:优化代码,使用异步处理和多线程技术,提高服务端的并发处理能力。
- 代码优化:精简代码逻辑,移除不必要的中间件和服务
淘宝购物车扩容与性能优化(下):https://developer.aliyun.com/article/1443491