长期以来,主图上的价格表达都是商家自己维护,商品价格发生变化后,手动去换图。这样做,会带来3个问题:
-
价格的准确性:商家手动填写的图片价格,跟实际的购买价可能不一致,造成不好的用户体验。
-
价格更新的及时性:有时候,由于优惠券/品类券的生效失效,会导致商品的价格变化会很频繁,商家根本来不及换图。
-
商家的操作成本:手动修改图片的价格,成本还是很高的,需要通过ps等软件修改图片,重新上传,编辑商品。
今年双11,淘系技术部-鹿班团队,试图通过技术手段来解决这些问题。当商品价格发生变化后,系统自动计算新的价格,自动合成图片,然后更新商品主图。
我们知道,淘宝网有上亿的商品,光大促商品就有几千万,因此,价格变化导致的图片变化频率非常高。最高的就是在双11的0点,全部大促商品的价格都会由日常价格变成大促价格。
这就意味着,大促高峰期,有上千万的图片刚生成就会被用户访问。那这个情况会产生什么问题呢,让我们先了解下淘宝的图片空间和CDN的架构,就清楚了。
===
淘宝图片空间和CDN的架构
=================
淘宝整个图片的访问链路有三级缓存(客户端本地、CDN L1、CDN L2),所有图片都持久化的存储到OSS中。真正处理图片的是img-picasso系统,它的功能比较复杂,包括从OSS读取文件,对图片尺寸进行缩放,编解码,所以机器成本比较高。
CDN的缓存分成2级,合理的分配L1和L2的比例,一方面,可以通过一致性hash的手段,在同等资源的情况下,缓存更多内容,提升整体缓存命中率;另一方面,可以平衡计算和IO,充分利用不同配置的机器的能力。
用户访问图片的过程如下:
-
用户通过手机淘宝来搜索商品或者查看宝贝详情。
-
详情/搜索/推荐通过调用商品中心返回商品的图片URL。
-
客户端本地如果有该图片的缓存,则直接渲染图片,否则执行下一步。
-
从CDN L1回源图片,如果L1有该图片的缓存,则客户端渲染图片,同时缓存到本地,如果L1没有缓存,则执行下一步。
-
从CDN L2回源图片,如果L2有该图片的缓存,则客户端渲染图片,同时CDN L1及客户端缓存图片内容,如果CDN L2没有缓存该图片,则执行下一步。
-
从图片空间回源图片,图片空间会从OSS拉取图片源文件,按要求进行尺寸缩放,然后执行编解码,返回客户端能够支持的图片内容,之后客户端就可以渲染图片,同时CDN的L1、L2以及客户端都会缓存图片内容。
===
频繁换图带来的技术挑战
===============
当商品的价格发生变化时,我们会使用新的价格重新合成图片,更新商品中心中存储的图片URL。这样会带来2个问题:
-
CDN及手机淘宝原本缓存的图片内容失效了,用户访问图片会全部回源到img-picasso。
-
由于更改了商品的字段,交易的核心应用(购物车和商品中心)的缓存也失效了,用户浏览及购物时,对商品的访问会走到db。
源站img-picasso处理图片,以及查询商品DB,都是非常消耗资源的。CDN及商品的缓存命中率降低后,对源站img-picsasso以及db会产生巨大的压力。
拿CDN缓存为例,简单计算一下,CDN平时的命中率是98%,假设命中率降低1个点,对源站的压力就会增加1/3(原本承担2%的流量,现在需要承担3%的流量),意味着img-picasso需要扩容1/3。如果全网一半的图片都同时变化,cdn的命中率降到50%,对img-picasso的访问量就会增加25倍,这个扩容成本肯定没法接受。
解决这2个问题,对应的有2个办法:
-
改图保持图片URL不变,可以避免商品链路的缓存失效。
-
在访问高峰到来之前,提前预热图片到CDN,可以避免CDN缓存失效对源站的压力。
下面,介绍下我们具体是怎么做到这2点的。
===
===
频繁换图的应对方案
=============
▐ 改图保持图片URL不变
图片内容发生变化时,执行下面2个操作:
-
更新OSS内容:使用新的图片内容替换OSS中老的图片内容
-
刷新CDN缓存:清除CDN之前缓存的图片内容
这样,用户再次访问图片时,发现CDN没有缓存,就会回源到img-picasso,从OSS拉取新的图片内容。
由于图片URL没有变化,就不必去更新商品中心的图片链接,这样商品链路的缓存可以保持不变。
在真正实施这个方案的过程中,遇到了几个问题,简单跟大家分享下:
OSS三地同步
淘宝的图片空间,承载了淘系所有图片的上下行稳定性保障,为了保障高可用,一份资源会存储到三地OSS。图片上传时,默认只上传一地,利用OSS的能力,自动同步到另外两地。
但是使用URL不变方案,CDN缓存已经清除完成后,如果另外2地的OSS还未同步完成,用户访问后,就会回源到旧的图片内容,发现图片内容没有变化。
针对该问题,我们将异步同步OSS软链的模式,改成三地同步建软链,三地都返回成功后,再去清除CDN缓存,这就保证了用户访问的图片一定是最新的内容。
图片尺寸收敛
同一张商品图片会用于不同的场景坑位展现,不同的坑位对图片的尺寸有不同的要求。为此,图片空间提供了一项功能,可以方便的生成不同尺寸的缩率图。只需要访问图片时,给图片增加不同的后缀,img-picasso源站就可以按要求进行图片进行缩放。
由于历史原因,之前对缩放的尺寸种类没有限制,导致CDN上的图片后缀格式多达2400种+,TOP6格式覆盖率46%,TOP15格式覆盖率64%。这意味着,一张图片,在cdn上最多可能有2400+个不同的url,当图片内容变化后,要把这些缓存全部清掉,才能保证所有用户看到的图片都是新内容。
为了解决这个问题,我们对域名格式进行了收敛。
图片空间对于图片质量压缩参数的规则如下:
-
图片质量参数常见有一下8种形式:Q90、Q75、Q50、Q30、q90、q75、q50、q30
-
图片锐化参数常见有一下3种形式:s100,s150,s200
我们重新将图片质量定义为高质量图片和低质量图片,收敛格式为 q90 和 p50s150
这样,就可以把2000多种格式收敛到6种主要格式,CDN清除缓存才变得可行。
多副本清除CDN缓存
通过图片尺寸收敛,每张图片只需要清除6个不同的url就可以了,那能不能进一步提升刷新效率呢?
为此,阿里云CDN为我们提供了多副本刷新的解决方案:每种不同后缀的图片,作为图片的一个副本,在CDN的swift层增加一层KV结构,存储url和不同副本的映射关系,清除缓存时,可以通过该结构找到所有副本,实现快速清除所有副本。这样,每张图片,我们只需要调用一次CDN清除缓存接口就可以了,极大提升了CDN缓存刷新效率。
图片域名收敛
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

最后
由于篇幅限制,小编在此截出几张知识讲解的图解
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
限制,小编在此截出几张知识讲解的图解**
[外链图片转存中…(img-4L7YQfYl-1712094727081)]
[外链图片转存中…(img-PF4k7hgQ-1712094727081)]
[外链图片转存中…(img-BKPig9Hu-1712094727082)]
[外链图片转存中…(img-JyNF2ao0-1712094727082)]
[外链图片转存中…(img-17Z8yKpu-1712094727082)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!