【巨人的肩膀】CDN是什么?使用CDN有什么优势?

起因

在知乎看到的问答,下边的淘系的回答

阿里巴巴淘系技术的答案

淘宝的图片访问,有 98% 的流量都走了 CDN 缓存。只有 2% 会回源到源站,节省了大量的服务器资源
但是,如果在用户访问高峰期,图片内容大批量发生变化,大量用户的访问就会穿透 cdn,对源站造成巨大的压力

CDN工作原理

内容分发网络(Content Delivery Network,简称CDN)是建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成的分布式网络
CDN 应用广泛,支持多种行业、多种场景内容加速,例如:图片小文件、大文件下载、视音频点播、直播流媒体、全站加速、安全加速
在这里插入图片描述
借用阿里云官网的例子,来简单介绍 CDN 的工作原理
假设通过 CDN 加速的域名为 www.a.com,接入 CDN 网络,开始使用加速服务后,当终端用户(北京)发起 HTTP 请求时,处理流程如下:

  1. 当终端用户(北京)向 www.a.com 下的指定资源发起请求时,首先向 LDNS(本地DNS)发起域名解析请求
  2. LDNS 检查缓存中是否有 www.a.com 的 IP 地址记录。如果有,则直接返回给终端用户;如果没有,则向授权 DNS 查询
  3. 当授权 DNS 解析 www.a.com 时,返回域名CNAME www.a.tbcdn.com 对应 IP 地址
  4. 域名解析请求发送至阿里云 DNS 调度系统,并为请求分配最佳节点 IP 地址
  5. LDNS 获取 DNS 返回的解析 IP 地址
  6. 用户获取解析 IP 地址
  7. 用户向获取的 IP 地址发起对该资源的访问请求。如果该 IP 地址对应的节点已缓存该资源,则会将数据直接返回给用户

例如,图中步骤 7 和 8,请求结束。如果该 IP 地址对应的节点未缓存该资源,则节点向源站发起对该资源的请求。获取资源后,结合用户自定义配置的缓存策略,将资源缓存至节点,例如,图中的北京节点,并返回给用户,请求结束

从这个例子可以了解到:

  1. CDN 的加速资源是跟域名绑定的
  2. 通过域名访问资源,首先是通过 DNS 分查找离用户最近的 CDN 节点(边缘服务器)的 IP
  3. 通过 IP 访问实际资源时,如果 CDN 上并没有缓存资源,则会到源站请求资源,并缓存到 CDN 节点上,这样,用户下一次访问时,该 CDN 节点就会有对应资源的缓存了
淘宝鹿班图片业务背景

商品的主图贯穿整个导购和交易链路,相比文字,图片更能吸引眼球,主图对消费者的购物决策有很大的影响
主图上表达的内容各式各样,但其中一定少不了的一定是价格的表达
长期以来,主图上的价格表达都是商家自己维护,商品价格发生变化后,手动去换图。这样做,会带来3个问题:

  1. 价格的准确性:商家手动填写的图片价格,跟实际的购买价可能不一致,造成不好的用户体验
  2. 价格更新的及时性:有时候,由于优惠券/品类券的生效失效,会导致商品的价格变化会很频繁,商家根本来不及换图
  3. 商家的操作成本:手动修改图片的价格,成本还是很高的,需要通过 ps 等软件修改图片,重新上传,编辑商品
    在这里插入图片描述
    今年双11,我们淘宝鹿班团队,试图通过技术手段来解决这些问题。当商品价格发生变化后,系统自动计算新的价格,自动合成图片,然后更新商品主图。我们知道,淘宝网有上亿的商品,光大促商品就有几千万,因此,价格变化导致的图片变化频率非常高。最高的就是在双 11 的 0 点,全部大促商品的价格都会由日常价格变成大促价格。这就意味着,大促高峰期,有上千万的图片刚生成就会被用户访问。那这个情况会产生什么问题呢,让我们先了解下淘宝的图片空间和 CDN 的架构,就清楚了
淘宝图片空间和CDN的架构

淘宝整个图片的访问链路有三级缓存(客户端本地、CDN L1、CDN L2),所有图片都持久化的存储到 OSS 中。真正处理图片的是 img-picasso 系统,它的功能比较复杂,包括从 OSS 读取文件,对图片尺寸进行缩放,编解码,所以机器成本比较高
CDN 的缓存分成 2 级,合理的分配 L1 和 L2 的比例,一方面,可以通过一致性 hash 的手段,在同等资源的情况下,缓存更多内容,提升整体缓存命中率;另一方面,可以平衡计算和 IO,充分利用不同配置的机器的能力
在这里插入图片描述
用户访问图片的过程如下

  1. 用户通过手机淘宝来搜索商品或者查看宝贝详情
  2. 详情/搜索/推荐通过调用商品中心返回商品的图片 URL
  3. 客户端本地如果有该图片的缓存,则直接渲染图片,否则执行下一步
  4. 从 CDN L1 回源图片,如果 L1 有该图片的缓存,则客户端渲染图片,同时缓存到本地,如果 L1 没有缓存,则执行下一步
  5. 从 CDN L2 回源图片,如果 L2 有该图片的缓存,则客户端渲染图片,同时 CDN L1 及客户端缓存图片内容,如果 CDN L2 没有缓存该图片,则执行下一步
  6. 从图片空间回源图片,图片空间会从 OSS 拉取图片源文件,按要求进行尺寸缩放,然后执行编解码,返回客户端能够支持的图片内容,之后客户端就可以渲染图片,同时 CDN 的 L1、L2 以及客户端都会缓存图片内容
频繁换图带来的技术挑战

在这里插入图片描述
当商品的价格发生变化时,我们会使用新的价格重新合成图片,更新商品中心中存储的图片 URL
这样会带来 2 个问题:

  1. CDN 及手机淘宝原本缓存的图片内容失效了,用户访问图片会全部回源到 img-picasso
  2. 由于更改了商品的字段,交易的核心应用(购物车和商品中心)的缓存也失效了,用户浏览及购物时,对商品的访问会走到 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 个办法

  1. 改图保持图片 URL 不变,可以避免商品链路的缓存失效
  2. 在访问高峰到来之前,提前预热图片到 CDN,可以避免 CDN 缓存失效对源站的压力

下面,介绍下我们具体是怎么做到这2点的。

频繁换图的应对方案——改图保持图片URL不变

在这里插入图片描述
图片内容发生变化时,执行下面2个操作:

  1. 更新 OSS 内容:使用新的图片内容替换 OSS 中老的图片内容
  2. 刷新 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,当图片内容变化后,要把这些缓存全部清掉,才能保证所有用户看到的图片都是新内容

为了解决这个问题,我们对域名格式进行了收敛

图片空间对于图片质量压缩参数的规则如下:

  1. 图片质量参数常见有一下8种形式:Q90、Q75、Q50、Q30、q90、q75、q50、q30
  2. 图片锐化参数常见有一下3种形式:s100,s150,s200

我们重新将图片质量定义为高质量图片和低质量图片,收敛格式为 q90 和 p50s150 这样,就可以把 2000 多种格式收敛到 6 种主要格式,CDN 清除缓存才变得可行

  • 多副本清除CDN缓存
    通过图片尺寸收敛,每张图片只需要清除 6 个不同的 url 就可以了,那能不能进一步提升刷新效率呢?

为此,阿里云 CDN 为我们提供了多副本刷新的解决方案:每种不同后缀的图片,作为图片的一个副本,在 CDN 的 swift 层增加一层 KV 结构,存储 url 和不同副本的映射关系,清除缓存时,可以通过该结构找到所有副本,实现快速清除所有副本。这样,每张图片,我们只需要调用一次 CDN 清除缓存接口就可以了,极大提升了 CDN 缓存刷新效率
在这里插入图片描述

  • 图片域名收敛
    淘系的图片域名有 300 多种,主要有下面2个原因:
  1. 图片完整的链接太长,所以存储时经常只存最后一段,业务自己来拼域名,很多业务就自己申请了一个图片域名来拼
  2. PC 时代,浏览器对同一域名下的并发请求数是有限制的,不同浏览器不一样,一般 6 个左右

为了突破该限制,一些业务就会申请多个域名,随机的拼不同的域名。前面我们讲过,CDN 的缓存是跟域名绑定的,不管是缓存命中还是缓存清除,都只能针对一个域名

我们显然不可能改一张图,就去对 300 个域名调用 CDN 刷新。于是我们考虑对图片域名进行收敛,使得用户对图片的访问都路由到同一个域名,我们希望将所有的图片访问统一收敛到 http://picasso.alicdn.com,具体实现方式如下:

  1. 对于手淘和猫客客户端,图片访问都收口在图片库,我们推进图片库进行改造,符合一定规则的 url,统一收敛到http://picasso.alicdn.com,实现了域名的一刀切
  2. 对于PC浏览器端,就比较麻烦了,没有统一收口的地方。我们只能退而求其次,针对访问最多的 6 大域名,在 cdn 上配置域名转发规则,重定向到 picasso 域名
    在这里插入图片描述
    通过这种方式,我们实现了全网 99% 以上的图片访问流量都路由到 picasso 域名,图片内容发生变化时,通过清除 picasso 域名的 cdn 缓存,就能保证基本所有的场景都能看到新的图片内容
客户端及浏览器缓存

通过多副本和图片域名收敛,cdn 的缓存问题得到了解决
但在 cdn 之上,用户图片访问首先是来自客户端或者浏览器,这里也会有一层缓存

大家知道,浏览器的缓存都遵循标准的 http max-age 协议,指定该 header 后,到了时间图片就会失效,访问到新的图片

所以我们可以在源站 img-picasso 回源给 cdn 时,添加 max-age 协议头,值为1分钟,cdn 会原封不动的透给浏览器,这样浏览器就可以实现1分钟内图片缓存失效,重新到 cdn 拉新的图片资源。对于手机淘宝客户端,我们在原有的 LRU 缓存机制之上,另外支持标准的 http 协议。这样,手机淘宝也实现了1分钟内图片缓存失效

提前预热CDN图片

通过改图保持图片 URL 不变,我们解决了改图对商品链路缓存的影响。但是,图片变化时,虽然 URL 没有变,但我们清除了 CDN 缓存,导致用户访问时还是会回源到 img-picasso 源站,所以对图片源站的压力依然存在。
在这里插入图片描述
我们发现,商品的价格变化大部分发生在大促节奏变化的时刻,基于这个特点,我们通过提前合成图片,提前预热到 CDN,可以实现图片切换瞬间生效,同时对源站没有压力

具体方案如下:

  1. 提前合成多波段图片:我们知道大促期间商家集中换图的时间点后,按这些时间点把图片的展示分成多个波段,每个波段图片提前合成,并提前将图片 URL 写入到商品中心扩展结构中
  2. 图片访问路由:营销系统根据配置的大促氛围切换计划,告诉鹿班图片二方包,当前是哪个波段,鹿班根据当前波段及场景,返回正确的图片 URL 给各个场景
  3. 图片渲染:各个场景拿到图片 URL 后,结合自身的业务逻辑,决定是否要展现该图片
  4. CDN 图片预热:为了避免图片集中切换时,把源站击垮,我们会在集中切换前把这些冷图片内容预热到 CDN
  5. 波段内图片变化:提前合成各个波段图片后,商家可能会临时发券/改价,导致商品价格再次变化,对于这类换图需求,为了避免更新商品中心的图片 URL,我们通过前边刷 CDN 缓存的方式实现
总结和展望

CDN 技术广泛应用于互联网的各个场景,如今的 CDN 服务商,都提供了非常简单的业务接入方式,而且 CDN 的费用每年都在降低,这一切使得 CDN 的接入和使用成本越来越低

本文通过淘宝图片业务的例子,为大家阐述了使用 CDN 过程中可能遇到的问题和解决思路

淘宝的图片业务除了访问量大,还会面临更新频繁的问题。图片的频繁更新,一方面会由于商品上的图片 url 变化,导致商品缓存失效,另一方面会大幅降低 CDN 的图片访问缓存命中率

针对图片 url 变化导致商品缓存失效的问题,我们通过刷新 cdn 缓存,用户访问时重新回源的方式,实现了改图保持图片 url 不变,这个过程中了,我们解决了一些列的问题,包括:OSS 三地同步更新、图片尺寸收敛、图片域名收敛、客户端及浏览器本地缓存

针对改图降 CDN 图片缓存命中率的问题,我们根据业务的特点,提前合成不同波段的图片,并预热到 CDN,保障了源站的安全

目前,淘宝上用户看到的图片,都是提前合成好的。未来,我们考虑在用户访问图片时,实时合成图片。通过这项技术,可以实时感知业务更多的实时信息,可以根据这些信息,在图片上合成当前用户或者环境更匹配的文案/元素等内容,给用户带来更多的惊喜

当然,实时合图也会面临更多的挑战,如:计算能力、合图性能。此外,对于 CDN 而言,由于每次用户访问的内容是临时合成的,CDN 的缓存策略也是一个很大的挑战

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值