腾讯技术分享:社交网络图片的带宽压缩技术演进之路

760 阅读23分钟
原文链接: www.52im.net

1、引言


腾讯社交网络相关产品,例如腾讯课堂、增值会员、动漫、直播、游戏商城、音乐、Qzone校园等,主要目标群体定位为年轻一代,属于对新事物接受比较高也更喜欢新鲜个性内容的群体,产品设计上必然使用大量的图片展示;同时核心产品QQ也涉及大量的图片存储及展示,例如QQ群图、群相册等。

图片在产品中的大量使用拥有诸多好处的同时,也带来以下几点问题:

  • 服务器端出口流量增加、文件存储磁盘增加,运营成本增高;
  • 用户访问单页面/产品流量消耗增加,尤其当前移动互联网流量按量计费,富图片会明显增加用户访问成本;
  • 客户端加载页面耗时增大,首屏显示时间延迟,影响用户使用体验。

为了进一步降低运营带宽成本,减小用户访问流量及提升页面加载速度,社交网络 CDN运维紧跟行业图片优化趋势,创新引入WebP、SharpP、自适应分辨率、Guetzli等图像压缩技术到现网,经过三年多的多部门联合攻关,已逐渐形成一套覆盖全图片类型(JPEG、JPG、PNG、WebP、GIF)多场景的图片压缩运营体系,适用于各类型终端,每年节约外网带宽几百G。

▼ 示例1: QQ空间GIF采用SharpP编码后,单图平均大小降幅90%,高峰期流量降幅30%
腾讯技术分享:社交网络图片的带宽压缩技术演进之路_1.jpg

▼ 示例2: QQ相册GIF采用SharpP编码后,节约流量非常明显,降幅超过80%
腾讯技术分享:社交网络图片的带宽压缩技术演进之路_2.png

2、相关文章



3、本文作者


腾讯技术分享:社交网络图片的带宽压缩技术演进之路_0.jpg

4、技术演进阶段一:引入WebP压缩,对业务强侵入


WebP是Google在2010年推出的新一代web图片压缩格式,它的优势体现在:

  • 具有更优的图像数据压缩算法,能带来更小的图片体积(原图基础上节约30%左右大小);
  • 拥有肉眼识别无差异的图像质量;
  • 具备了无损和有损的压缩模式、Alpha 透明以及动画的特性;
  • 在 JPEG 和 PNG 上的转化效果都相当优秀、稳定和统一;
  • 支持GIF,对GIF的压缩效果尤其显著,可以节约企业大量的带宽资源以及数据空间。

运维同事及时跟进研究WebP并推动应用现网,并基于该技术建立了最初的CDN图片压缩访问方案。

压缩参数设置:
腾讯技术分享:社交网络图片的带宽压缩技术演进之路_3.jpg
通过验证发现,压缩质量参数在编码后图片质量及大小间形成正相关关系,质量参数越高,编码后图片质量越好体积也就越大。质量参数设置70%~90%间,可以达到最优平衡。现网默认设置80%。

编/解码性能优化:
终端WebP解码性能,在当前网络环境下不存在问题,平均解码耗时在100ms以内。并且,通过有限制的使用WebP图片,例如限制图片尺寸、使用的CPU核心及最大频率等方式,可以进一步优化编解码能力。

终端兼容性:
腾讯技术分享:社交网络图片的带宽压缩技术演进之路_aaaa.png
嵌入WebP解码库的自有APP以及已知支持WebP的公共浏览器,例如Chrome、Opera等,其他场景下无法解码WebP数据( 关于主流浏览器对WebP的支持情况点此查看)。

一期主要联合ISUX开发实现现网CDN的WebP能力引入,并建立了相应压缩访问方案,如下图所示:
腾讯技术分享:社交网络图片的带宽压缩技术演进之路_5.png
  • 服务器端部署异步压缩工具,对特定规则的图片应用压缩,并生成对应的副本文件;
  • 客户端(Browser+APP)和后台管理端联动,客户端识别载体是否支持WebP解码,并将结果返回后台管理端,后台管理端再根据客户端能力,确定最终的资源访问URL。

大致的原理是:

  • CDN源站部署WebP编码工具,对符合规则的资源进行WebP编码及写DB操作;
  • WebP编码采用异步模式,且编码成功后才写DB知会后台管理,因此即使编码失败或耗时长也不影响客户端实际访问;
  • 客户端需先向后台管理获取资源路径,然后才能对资源发起实际请求,向管理端请求资源访问路径时,会带上自身WebP兼容性标签数据;
  • CDN缓存是基于访问URL为key的,而原图及WebP副本访问URL不一样(副本为.webp后缀),因此实际会在CDN节点缓存两份不同数据。

以上方案在接入CDN的ISUX上使用稳定,并且达到了预期效果,后续也逐步推广应用到了少量Qzone图片上。不过由于该方案对接入业务侵入性较强,要求业务客户端必须具备WebP兼容性检测能力,以及访问URL后台下发能力,最终接入业务除相册外,寥寥无几。

5、技术演进阶段二:引入WebP/SharpP/自适应多方式压缩,业务无痛接入


老架构的图片压缩在CDN现网能正常服务部分业务,减小服务器端带宽消耗和数据存储的同时,提升了客户端的加载速度。

但该架构的固有缺陷也十分明显:

  • 压缩能力有限,只支持WebP一种方式,跟不上行业压缩技术趋势;
  • 压缩场景有限,只支持兼容WebP格式的部分客户端访问;
  • 对业务侵入严重,导致实际推广效果不佳。

基于此,在优化图片压缩访问方案的时候,希望新架构能对业务侵入小甚至无侵入,同时引入更高效的图片压缩技术进行现网推广使用。项目历时2015~2016共两年时间,期间我们也跟随行业编码技术趋势,在优化成熟WebP、自适应方案同时,创新性的引入了SharpP编码技术。

5.1编码技术:优化WebP,新引入腾讯自研SharpP及分辨率自适应调整能力


WebP编码在原图基础上节约30%左右大小,但随着H.265、VP9以及AVS2等新编码技术的出现,图片压缩有了进一步优化的空间。

【a. 基于HEVC的SharpP编码压缩】:

Sharp是基于新一代图片编码标准HEVC,并对编码性能、效率及支持能力等方面做出优化扩展后,由腾讯社交网络音视频实验室推出的图像编解码技术。不管理论还是实际验证,基于HEVC的SharpP相对WebP可节约21%大小,相对JPEG可节约43%左右大小。

腾讯技术分享:社交网络图片的带宽压缩技术演进之路_6.png

腾讯技术分享:社交网络图片的带宽压缩技术演进之路_7.png

SharpP系统组成同WebP一样,包括编码和解码两部分:

  • 编码:RGB->SharpP
  • 解码:SharpP->RGB

腾讯技术分享:社交网络图片的带宽压缩技术演进之路_8.jpg

通过对原HEVC编解码内核优化、支持渐进式功能及透明通道、动态图片格式等方式,进一步降低了SharpP编解码性能消耗并增加对现有图片类型的兼容性,并做到了质量上的基本不失真。由于现阶段SharpP还属于腾讯内部自有格式,因此只能应用于腾讯自有APP,通过APP中添加SharpP解码库的方式实现客户端的解码。

【b. 图片分辨率自适应调整】:

终端机型分辨率大小不一,相关图片是以最大分辨率设计的,目前统一标准是750px,但许多中低端机型并不需要高分辨率的图片,如果能按需返回适当分辨率图,同样可达到节约流量及优化性能的目的。经现网验证,启用自适应图片压缩后,相关产品访问流量可在原有基础上,再节约20%左右。

腾讯技术分享:社交网络图片的带宽压缩技术演进之路_9.png

图片分辨率调整相对WebP/SharpP来说原理简单,不修改编码格式只调整分辨率信息,因此无编解码性能或客户端兼容问题。我们将现有终端设备分辨率按如下三级进行划分,并对应到源站某个固定分辨率的图片副本:
腾讯技术分享:社交网络图片的带宽压缩技术演进之路_bbb.png

5.2运营方案:对业务最小侵入的图片压缩访问架构


让业务以最小的改动代价来获得最大的带宽及性能收益,才能让技术架构更容易推广。

考虑到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源站同样需要提前做好相应的调整部署:
腾讯技术分享:社交网络图片的带宽压缩技术演进之路_10.jpg

如上图所示:

  • 腾讯浏览器、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源站的对应功能实现:
腾讯技术分享:社交网络图片的带宽压缩技术演进之路_11.jpg

如上图所示,分辨率自适应方案不依赖独立的解码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源站三个层级,并在对应层级上将二者功能逻辑耦合在一起,实现交错叠加能力。

现网结合编码压缩和分辨率自适应的最终方案流程图如下:
腾讯技术分享:社交网络图片的带宽压缩技术演进之路_12.png

该套方案解决了业务侵入性问题,同时通过引入SharpP、自适应能力,提高了编码效率以及终端适用场景;当前已成功应用到腾讯手Q H5、手Q群图片、相册及Qzone结合版、独立版等重要业务上,月节约流量400Gbps以上,同时该套方案也正在向全公司内部推广。

6、技术演进阶段三: 持续引领,引入Guetzli补充适用场景,业务无感知


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编码优势明显。

6.1Guetzli现网应用方案


Guetzli并未改变图片原有编码格式,只是对其数据进行优化缩减,因此不管对客户端还是CDN节点来说,都可将Guetzli副本当做原图来处理;唯一需要做的只是准备好工具并在源站部署对应处理逻辑:

【a. 工具优化:】

开源Guetzli工具在现网是没法直接用的,相信只要关注Guetzli的同学,都知道这个结论。

为让工具具备现网应用能力,开发同学主要从以下两个方面对其进行了优化:

  • GPU计算加速:将整个Guetzli的计算算法全部都转移到了CUDA里去,利用显卡的并行能力及浮点计算优势进行加速;
  • 参数调优:对内存分配改用效率更高的TCMalloc库;优化CUDA的Block Size大小;将计算精度由double改为float。

优化后的Guetzli工具,性能较源开源版本提升90%以上,质量上基本无差异。

【b. 源站处理逻辑】:

简单的Guetzli应用,直接通过Web方式触发对应shell命令即可。为便于业务灰度控制,我们引入业务ID概念:CDN源站通过请求业务ID来区分是否Guetzli请求,同时通过前端Nginx匹配域名+URL规则,来控制放量范围。

如下所示:
腾讯技术分享:社交网络图片的带宽压缩技术演进之路_13.png

原理大致如下:

  • 客户端按照正常情况发送图片请求;
  • Nginx层根据$uri 匹配规则分别转发请求到不通的后端业务ID,其中一个业务ID开启Guetzli压缩,另一个没有;
  • 源站Guetzli压缩支持预压缩和在线压缩两种,其中在线压缩为异步模式,并设置有超时时间。若压缩失败或超时,则返回原图并设置max-age=10;
  • Guetzli副本存储在Cache层原图的key位置,即默认使用Guetzli副本代替原图。

6.2与原有架构的结合


Guetzli编码后的图片还是JPEG格式,理论上再次进行WebP/SharpP压缩是可行的,现网实际测试也的确如此。那么Guetzli是否会和分辨率自适应一样,在与WebP/SharpP叠加编码后,压缩效率和性能收益同样叠加?

我们从现网获取了100张视频封面作为测试样本,Guetzli质量因子设备90,WebP/SharpP质量因子设置70,分别进行独立的编码压缩以及WebP + Guetzli叠加、SharpP + Guetzli叠加。

取得测试数据如下:
腾讯技术分享:社交网络图片的带宽压缩技术演进之路_14.png

从测试数据可以看出, Guetzli与WebP/SharpP的叠加压缩必要性不大,叠加的GUE压缩并没有带来更优的压缩效率,甚至在色彩单一情况下,叠加压缩的图片比原图WebP/SharpP压缩后还要大些。

因此,最终落地方案设计时,没有对是否叠加压缩进行强制限制。即Guetzli与原有压缩访问架构在源站并行部署,各自覆盖对应适用场景并且有一定几率叠加使用。

最终落地方案架构如图所示:
腾讯技术分享:社交网络图片的带宽压缩技术演进之路_15.jpg

Guetzli编码优化功能自上线以来,由于其无敌的现有终端兼容能力,一个月内即完成CDN全量域名推广,两个月内即完成QQ看点、腾讯视频图片、QQ音乐封面的推广,节约带宽近百G,并会随着时间推移持续增长。

7、本文小结


经过三年多的多部门联合运作,终于完成图像压缩技术方案在腾讯CDN的落地以及全域名实施。

在技术演进的过程中得到的收获:

  • 压缩访问方案做到了对现有规范的最大兼容、对业务的最小侵入,使得对内可以尽快推广;
  • 相关编码/分辨率压缩技术紧跟行业趋势,在开源基础上优化、精炼和扩展,优化后的工具能力较开源版本提升明显,并有逐渐反哺开源社区;
  • 提升自身业务竞争力的同时,也为行业发展贡献了一份力量!

以上方案涉及的一些关键编码工具,其中:

  • WebP工具在开源版本基础上无修改,直接基于libwebp封装而成;
  • Guetzli工具基于开源版本有少量参数调整及BUG修复,相关代码已开源到GitHub;
  • SharpP工具从17年3月开始,已采用AVS2作为新的内核;17年5月正式对外推出基于AVS2的图片格式,联合北大、AVS组织一起完善相关规范,并命名为TPG(Tiny Portable Graphics)。

附录:微信、QQ团队相关文章汇总


[1] 有关QQ、微信的技术文章:
腾讯技术分享:社交网络图片的带宽压缩技术演进之路
微信团队分享:视频图像的超分辨率技术原理和应用场景
微信团队分享:微信每日亿次实时音视频聊天背后的技术解密
QQ音乐团队分享:Android中的图片压缩技术详解(上篇)
QQ音乐团队分享:Android中的图片压缩技术详解(下篇)
腾讯团队分享:手机QQ中的人脸识别酷炫动画效果实现详解
腾讯团队分享 :一次手Q聊天界面中图片显示bug的追踪过程分享
微信团队分享:微信Android版小视频编码填过的那些坑
微信手机端的本地数据全文检索优化之路
企业微信客户端中组织架构数据的同步更新方案优化实战
微信团队披露:微信界面卡死超级bug“15。。。。”的来龙去脉
QQ 18年:解密8亿月活的QQ后台服务接口隔离技术
月活8.89亿的超级IM微信是如何进行Android端兼容测试的
以手机QQ为例探讨移动端IM中的“轻应用”
一篇文章get微信开源移动端数据库组件WCDB的一切!
微信客户端团队负责人技术访谈:如何着手客户端性能监控和优化
微信后台基于时间序的海量数据冷热分级架构设计实践
微信团队原创分享:Android版微信的臃肿之困与模块化实践之路
微信后台团队:微信后台异步消息队列的优化升级实践分享
微信团队原创分享:微信客户端SQLite数据库损坏修复实践
腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率
腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(下篇)
腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(上篇)
微信Mars:微信内部正在使用的网络层封装库,即将开源
如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源
开源libco库:单机千万连接、支撑微信8亿用户的后台框架基石 [源码下载]
微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解
微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)
微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)
Android版微信从300KB到30MB的技术演进(PPT讲稿) [附件下载]
微信团队原创分享:Android版微信从300KB到30MB的技术演进
微信技术总监谈架构:微信之道——大道至简(演讲全文)
微信技术总监谈架构:微信之道——大道至简(PPT讲稿) [附件下载]
如何解读《微信技术总监谈架构:微信之道——大道至简》
微信海量用户背后的后台系统存储架构(视频+PPT) [附件下载]
微信异步化改造实践:8亿月活、单机千万连接背后的后台解决方案
微信朋友圈海量技术之道PPT [附件下载]
微信对网络影响的技术试验及分析(论文全文)
一份微信后台技术架构的总结性笔记
架构之道:3个程序员成就微信朋友圈日均10亿发布量[有视频]
快速裂变:见证微信强大后台架构从0到1的演进历程(一)
快速裂变:见证微信强大后台架构从0到1的演进历程(二)
微信团队原创分享:Android内存泄漏监控和优化技巧总结
全面总结iOS版微信升级iOS9遇到的各种“坑”
微信团队原创资源混淆工具:让你的APK立减1M
微信团队原创Android资源混淆工具:AndResGuard [有源码]
Android版微信安装包“减肥”实战记录
iOS版微信安装包“减肥”实战记录
移动端IM实践:iOS版微信界面卡顿监测方案
微信“红包照片”背后的技术难题
移动端IM实践:iOS版微信小视频功能技术方案实录
移动端IM实践:Android版微信如何大幅提升交互性能(一)
移动端IM实践:Android版微信如何大幅提升交互性能(二)
移动端IM实践:实现Android版微信的智能心跳机制
移动端IM实践:WhatsApp、Line、微信的心跳策略分析
移动端IM实践:谷歌消息推送服务(GCM)研究(来自微信)
移动端IM实践:iOS版微信的多设备字体适配方案探讨
信鸽团队原创:一起走过 iOS10 上消息推送(APNS)的坑
腾讯信鸽技术分享:百亿级实时消息推送的实战经验
>> 更多同类文章 ……

[2] 有关QQ、微信的技术故事:
2017微信数据报告:日活跃用户达9亿、日发消息380亿条
腾讯开发微信花了多少钱?技术难度真这么大?难在哪?
技术往事:创业初期的腾讯——16年前的冬天,谁动了马化腾的代码
技术往事:史上最全QQ图标变迁过程,追寻IM巨人的演进历史
技术往事:“QQ群”和“微信红包”是怎么来的?
开发往事:深度讲述2010到2015,微信一路风雨的背后
开发往事:微信千年不变的那张闪屏图片的由来
开发往事:记录微信3.0版背后的故事(距微信1.0发布9个月时)
一个微信实习生自述:我眼中的微信开发团队
首次揭秘:QQ实时视频聊天背后的神秘组织
>> 更多同类文章 ……