前言
腾讯社交网络相关产品,例如腾讯课堂、增值会员、动漫、直播、游戏商城、音乐、Qzone校园等,主要目标群体定位为年轻一代,属于对新事物接受比较高也更喜欢新鲜个性内容的群体,产品设计上必然使用大量的图片展示;同时核心产品QQ也涉及大量的图片存储及展示,例如QQ群图、群相册等。图片在产品中的大量使用拥有诸多好处的同时,也带来以下几点问题:
服务器端出口流量增加、文件存储磁盘增加,运营成本增高;
用户访问单页面/产品流量消耗增加,尤其当前移动互联网流量按量计费,富图片会明显增加用户访问成本;
客户端加载页面耗时增大,首屏显示时间延迟,影响用户使用体验;
为进一步降低运营带宽成本,减小用户访问流量及提升页面加载速度,社交网络 CDN运维紧跟行业图片优化趋势,创新引入WebP、SharpP、自适应分辨率、Guetzli等图像压缩技术到现网,经过三年多的多部门联合攻关,已逐渐形成一套覆盖全图片类型(JPEG、JPG、PNG、WebP、GIF)多场景的图片压缩运营体系,适用于各类型终端,每年节约外网带宽几百G。
示例1:QQ空间GIF采用SharpP编码后,单图平均大小降幅90%,高峰期流量降幅30%;
(点击图片查看大图)
示例2:QQ相册GIF采用SharpP编码后,节约流量非常明显,降幅超过80%。
腾讯图片压缩架构的成熟稳定也并非一蹴而就,而是经过了多轮的演进优化而来,最终达到覆盖面广、压缩效益好以及业务接受度高的局面。其架构演变大致经历了如下几个阶段:
WebP是Google在2010年推出的新一代web图片压缩格式,它的优势体现在:
具有更优的图像数据压缩算法,能带来更小的图片体积(原图基础上节约30%左右大小);
拥有肉眼识别无差异的图像质量;
具备了无损和有损的压缩模式、Alpha 透明以及动画的特性;
在 JPEG 和 PNG 上的转化效果都相当优秀、稳定和统一;
支持GIF,对GIF的压缩效果尤其显著,可以节约企业大量的带宽资源以及数据空间;
运维同事及时跟进研究WebP并推动应用现网,并基于该技术建立了最初的CDN图片压缩访问方案。
压缩参数设置
通过验证发现,压缩质量参数在编码后图片质量及大小间形成正相关关系,质量参数越高,编码后图片质量越好体积也就越大。质量参数设置70%~90%间,可以达到最优平衡。现网默认设置80%。
编/解码性能优化
终端WebP解码性能,在当前网络环境下不存在问题,平均解码耗时在100ms以内。并且,通过有限制的使用WebP图片,例如限制图片尺寸、使用的CPU核心及最大频率等方式,可以进一步优化编解码能力;
终端兼容性
嵌入WebP解码库的自有APP以及已知支持WebP的公共浏览器,例如Chrome、Opera等。其他场景下无法解码WebP数据;
(点击图片查看大图)
一期主要联合ISUX开发实现现网CDN的WebP能力引入,并建立了相应压缩访问方案。如下图所示,服务器端部署异步压缩工具,对特定规则的图片应用压缩,并生成对应的副本文件;客户端(Browser+APP)和后台管理端联动,客户端识别载体是否支持WebP解码,并将结果返回后台管理端,后台管理端再根据客户端能力,确定最终的资源访问URL。
(点击图片查看大图)
CDN源站部署WebP编码工具,对符合规则的资源进行WebP编码及写DB操作;
WebP编码采用异步模式,且编码成功后才写DB知会后台管理,因此即使编码失败或耗时长也不影响客户端实际访问;
客户端需先向后台管理获取资源路径,然后才能对资源发起实际请求,向管理端请求资源访问路径时,会带上自身WebP兼容性标签数据;
CDN缓存是基于访问URL为key的,而原图及WebP副本访问URL不一样(副本为.webp后缀),因此实际会在CDN节点缓存两份不同数据;
以上方案在接入CDN的ISUX上使用稳定,并且达到了预期效果,后续也逐步推广应用到了少量Qzone图片上。不过由于该方案对接入业务侵入性较强,要求业务客户端必须具备WebP兼容性检测能力,以及访问URL后台下发能力,最终接入业务除相册外,寥寥无几。
老架构的图片压缩在CDN现网能正常服务部分业务,减小服务器端带宽消耗和数据存储的同时,提升了客户端的加载速度。但该架构的固有缺陷也十分明显:
压缩能力有限,只支持WebP一种方式,跟不上行业压缩技术趋势;
压缩场景有限,只支持兼容WebP格式的部分客户端访问;
对业务侵入严重,导致实际推广效果不佳;
基于此,在优化图片压缩访问方案的时候,希望新架构能对业务侵入小甚至无侵入,同时引入更高效的图片压缩技术进行现网推广使用。项目历时15~16共两年时间,期间我们也跟随行业编码技术趋势,在优化成熟WebP、自适应方案同时,创新性的引入了SharpP编码技术。
编码技术:优化WebP,新引入腾讯自研SharpP及分辨率自适应调整能力
WebP编码在原图基础上节约30%左右大小,但随着H.265、VP9以及AVS2等新编码技术的出现,图片压缩有了进一步优化的空间。
a. 基于HEVC的SharpP编码压缩
Sharp是基于新一代图片编码标准HEVC,并对编码性能、效率及支持能力等方面做出优化扩展后,由腾讯社交网络音视频实验室推出的图像编解码技术。不管理论还是实际验证,基于HEVC的SharpP相对WebP可节约21%大小,相对JPEG可节约43%左右大小;
(点击图片查看大图)
SharpP系统组成同WebP一样,包括编码和解码两部分:
编码:RGB->SharpP
解码:SharpP->RGB
通过对原HEVC编解码内核优化、支持渐进式功能及透明通道、动态图片格式等方式,进一步降低了SharpP编解码性能消耗并增加对现有图片类型的兼容性,并做到了质量上的基本不失真。由于现阶段SharpP还属于腾讯内部自有格式,因此只能应用于腾讯自有APP,通过APP中添加SharpP解码库的方式实现客户端的解码。
b. 图片分辨率自适应调整
终端机型分辨率大小不一,相关图片是以最大分辨率设计的,目前统一标准是750px,但许多中低端机型并不需要高分辨率的图片,如果能按需返回适当分辨率图,同样可达到节约流量及优化性能的目的。经现网验证,启用自适应图片压缩后,相关产品访问流量可在原有基础上,再节约20%左右。
图片分辨率调整相对WebP/SharpP来说原理简单,不修改编码格式只调整分辨率信息,因此无编解码性能或客户端兼容问题。我们将现有终端设备分辨率按如下三级进行划分,并对应到源站某个固定分辨率的图片副本:
屏幕分辨率Pixel |
使用图片 |
Pixel>=750(未开启大图剪裁) |
原图 |
Pixel>=750(开启大图剪裁) |
.750图片 |
640<=Pixel<750 |
.640图片 |
Pixel<640 |
.480图片 |
运营方案:对业务最小侵入的图片压缩访问架构
让业务以最小的改动代价来获得最大的带宽及性能收益,才能让技术架构更容易推广。
考虑到Accept、User-Agent属于标准的HTTP请求头字段,分别用来承载客户端的解码能力信息及屏幕分辨率信息,也属常理;并且类似Chrome、Opera这种已支持WebP的浏览器,请求头默认有带上“Accept: image/webp”字段,完全兼容该套方案。
a. 基于Accept头的WebP/SharpP自识别编码
PC浏览器,例如Chrome、Opera等,支持WebP解码情况下,在请求头Accept字段中默认有带上“image/webp”字段,兼容该套压缩访问框架;
非浏览器类,例如APP、PC客户端,在发送图片请求前,可根据编码能力,自定义添加、或通过底层WebView来统一添加“image/webp” “image/sharpp”字段。腾讯APP类产品上承载的业务一般较多,分属不同内部开发团队,为便于资源接入及统一管理,我们推荐的方式是APP平台统一嵌入解码SDK及修改请求头Accept字段,其上业务调用APP内嵌WebView来请求图片资源即可。
为识别客户端发送的编码格式字段并返回正确编码后的压缩内容,CDN节点和CDN源站同样需要提前做好相应的调整部署:
(点击图片查看大图)
如上图所示:
腾讯浏览器、QQ APP的WebView中预埋WebP/SharpP解码SDK,并向上提供Accept头字段的自动修改能力及图片解码能力;
CDN节点,根据识别到的Accept头字段返回对应缓存内容,或者直接透传请求到源站;
CDN源站,根据获取到的请求头字段,读取预生成的压缩格式副本或触发实时压缩,并响应对应编码内容给客户端。
由于WebP/SharpP编码有可能失败或者耗时过高,现网通过以下几个手段来保障请求数据的及时返回:
在资源到达CDN源站前,实施相关编码格式预压缩;
在线编码采用异步模式,并设置超时;若超时则直接返回原图,并设置缓存时间max-age=10,便于该次请求内容在CDN可以尽快过期更新;
若检测到压缩后的文件对比原图无优势(没有比原图小),则直接返回原图内容;
鉴于SharpP比WebP编码更高效,在 Accept 字段同时带有 "image/webp"、"image/sharpp" 时,CDN 优先返回 SharpP 编码内容;
b. 基于User-Agent的分辨率自适应调整
HTTP头字段中带的User-Agent,一般不包括分辨率(或格式不统一)。经过调研,我们认为以“Pixel/750”这种格式来匹配最标准,也更容易兼容已有客户端能力。同编码方案类似,基于User-Agent的自适应方案,同样需要客户端WebView头字段修改能力支持,以及CDN节点和CDN源站的对应功能实现:
(点击图片查看大图)
如上图所示,分辨率自适应方案不依赖独立的解码SDK,直接使用WebView中自带的公共SDK即可;另,此处WebView同样需要修改UA头字段,按照格式要求添加分辨率信息后,传递给CDN节点或CDN源站,节点及源站再进行相应的逻辑处理:
WebView修改请求头User-Agent带上分辨率信息,然后传递给CDN。例如User-Agent: Mozilla/5.0 Pixel/480 …;
CDN节点根据UA分辨率数据读取对应缓存并返回,或者直接透传请求到源站;
源站根据UA分辨率数据读取本地预生成的对应副本,或触发在线压缩;
在线压缩采用异步模式,并设置超时时间。失败或超时情况下直接返回原图,并且设置缓存时间max-age=10;
自适应调整后图片编码格式与原图相同,只是分辨率不一样;
编码压缩和分辨率调整属于不同的两种图像压缩方式,理论上可叠加使用不影响实际功能,且同时带来叠加后的压缩比和性能收益。现网应用的时候,我们也充分考虑到了这点,将两种不同压缩方案同样分为客户端(SDK+WebView)、CDN节点、CDN源站三个层级,并在对应层级上将二者功能逻辑耦合在一起,实现交错叠加能力。
现网结合编码压缩和分辨率自适应的最终方案流程图如下:
(点击图片查看大图)
该套方案解决了业务侵入性问题,同时通过引入SharpP、自适应能力,提高了编码效率以及终端适用场景;当前已成功应用到腾讯手Q H5、手Q群图片、相册及Qzone结合版、独立版等重要业务上,月节约流量400Gbps以上,同时该套方案也正在向全公司内部推广。
WebP/SharpP编码压缩虽然在压缩效率上更优,但需客户端具备对应解码SDK才能正常使用。对现网流量数据分析,发现除WebP/SharpP/自适应图片外,还存在大量的原图请求流量,其中JPG格式请求占比30%左右。其原因如下:
CDN静态已全量图片压缩应用,但较多来自独立APP或PC浏览器的访问,导致jpg原图流量占比约9%;
手Q服务号已改造支持新格式,但jpg格式带宽占比还是有35%之多;
QQ群图改造编码压缩难度大(无法兼容所有客户端类型),一直无进展;
腾讯视频APP已改造支持新格式,但还有来自PC端各种浏览器的访问,导致jpg带宽占比35%。
Guetzli是Google 2017年最新推出的图片编码算法,用于编码JPEG格式,官方宣称比早期的libjpeg减小30%左右大小。此算法只是改进并没有改变JPEG编码算法,因此编码出来的图片适用目前已有解码器。
开源Guetzli工具在编码文件时,内存及时间消耗都比较高,经过相关优化调整,可大大减小工具性能消耗,延时下降92%,成本节省一半以上,从而具备初步的线上应用能力。当前现网存在大量jpg原图请求,可应用Guetzli编码压缩进行场景覆盖。据统计,Guetzli优化后图片大小平均节省30%,用户侧下载延时下降25%左右,相对传统JPEG编码优势明显。
Guetzli现网应用方案
Guetzli并未改变图片原有编码格式,只是对其数据进行优化缩减,因此不管对客户端还是CDN节点来说,都可将Guetzli副本当做原图来处理;唯一需要做的只是准备好工具并在源站部署对应处理逻辑:
1. 工具优化
开源Guetzli工具在现网是没法直接用的,相信只要关注Guetzli的同学,都知道这个结论。为让工具具备现网应用能力,开发同学主要从以下两个方面对其进行了优化:
GPU计算加速
将整个Guetzli的计算算法全部都转移到了CUDA里去,利用显卡的并行能力及浮点计算优势进行加速。
参数调优
对内存分配改用效率更高的TCMalloc库;优化CUDA的Block Size大小;将计算精度由double改为float。
优化后的Guetzli工具,性能较源开源版本提升90%以上,质量上基本无差异。
2. 源站处理逻辑
简单的Guetzli应用,直接通过Web方式触发对应shell命令即可。为便于业务灰度控制,我们引入业务ID概念:CDN源站通过请求业务ID来区分是否Guetzli请求,同时通过前端Nginx匹配域名+URL规则,来控制放量范围。如下所示:
客户端按照正常情况发送图片请求;
Nginx层根据$uri 匹配规则分别转发请求到不通的后端业务ID,其中一个业务ID开启Guetzli压缩,另一个没有;
源站Guetzli压缩支持预压缩和在线压缩两种,其中在线压缩为异步模式,并设置有超时时间。若压缩失败或超时,则返回原图并设置max-age=10;
Guetzli副本存储在Cache层原图的key位置,即默认使用Guetzli副本代替原图;
与原有架构的结合
Guetzli编码后的图片还是JPEG格式,理论上再次进行WebP/SharpP压缩是可行的,现网实际测试也的确如此。那么Guetzli是否会和分辨率自适应一样,在与WebP/SharpP叠加编码后,压缩效率和性能收益同样叠加?
我们从现网获取了100张视频封面作为测试样本,Guetzli质量因子设备90,WebP/SharpP质量因子设置70,分别进行独立的编码压缩以及WebP + Guetzli叠加、SharpP + Guetzli叠加。取得测试数据如下:
从测试数据可以看出, Guetzli与WebP/SharpP的叠加压缩必要性不大,叠加的GUE压缩并没有带来更优的压缩效率,甚至在色彩单一情况下,叠加压缩的图片比原图WebP/SharpP压缩后还要大些。
因此,最终落地方案设计时,没有对是否叠加压缩进行强制限制。即Guetzli与原有压缩访问架构在源站并行部署,各自覆盖对应适用场景并且有一定几率叠加使用。最终落地方案架构如图所示:
(点击图片查看大图)
Guetzli编码优化功能自上线以来,由于其无敌的现有终端兼容能力,一个月内即完成CDN全量域名推广,两个月内即完成QQ看点、腾讯视频图片、QQ音乐封面的推广,节约带宽近百G,并会随着时间推移持续增长。
经过三年多的多部门联合运作,终于完成图像压缩技术方案在腾讯CDN的落地以及全域名实施。
压缩访问方案做到了对现有规范的最大兼容、对业务的最小侵入,使得对内可以尽快推广;相关编码/分辨率压缩技术紧跟行业趋势,在开源基础上优化、精炼和扩展,优化后的工具能力较开源版本提升明显,并有逐渐反哺开源社区;提升自身业务竞争力的同时,也为行业发展贡献了一份力量!
以上方案涉及的一些关键编码工具,其中:
WebP工具在开源版本基础上无修改,直接基于libwebp封装而成;
Guetzli工具基于开源版本有少量参数调整及BUG修复,相关代码已开源到GitHub;
SharpP工具从17年3月开始,已采用AVS2作为新的内核;17年5月正式对外推出基于AVS2的图片格式,联合北大、AVS组织一起完善相关规范,并命名为TPG(Tiny Portable Graphics);