前言
腾讯社交网络相关产品, 例如腾讯课堂增值会员动漫直播游戏商城音乐 Qzone 校园等, 主要目标群体定位为年轻一代, 属于对新事物接受比较高也更喜欢新鲜个性内容的群体, 产品设计上必然使用大量的图片展示; 同时核心产品 QQ 也涉及大量的图片存储及展示, 例如 QQ 群图群相册等图片在产品中的大量使用拥有诸多好处的同时, 也带来以下几点问题:
服务器端出口流量增加文件存储磁盘增加, 运营成本增高;
用户访问单页面 / 产品流量消耗增加, 尤其当前移动互联网流量按量计费, 富图片会明显增加用户访问成本;
客户端加载页面耗时增大, 首屏显示时间延迟, 影响用户使用体验;
为进一步降低运营带宽成本, 减小用户访问流量及提升页面加载速度, 社交网络 CDN 运维紧跟行业图片优化趋势, 创新引入 webPSharpP 自适应分辨率 Guetzli 等图像压缩技术到现网, 经过三年多的多部门联合攻关, 已逐渐形成一套覆盖全图片类型 (JPEGJPGPNGWebPGIF) 多场景的图片压缩运营体系, 适用于各类型终端, 每年节约外网带宽几百 G
示例 1:QQ 空间 GIF 采用 SharpP 编码后, 单图平均大小降幅 90%, 高峰期流量降幅 30%;
(点击图片查看大图)
示例 2:QQ 相册 GIF 采用 SharpP 编码后, 节约流量非常明显, 降幅超过 80%
架构演变阶段
腾讯图片压缩架构的成熟稳定也并非一蹴而就, 而是经过了多轮的演进优化而来, 最终达到覆盖面广压缩效益好以及业务接受度高的局面其架构演变大致经历了如下几个阶段:
阶段一: 引入 WebP 压缩, 对业务强侵入
WebP 是 Google 在 2010 年推出的新一代 web 图片压缩格式, 它的优势体现在:
具有更优的图像数据压缩算法, 能带来更小的图片体积(原图基础上节约 30% 左右大小);
拥有肉眼识别无差异的图像质量;
具备了无损和有损的压缩模式 Alpha 透明以及动画的特性;
在 JPEG 和 PNG 上的转化效果都相当优秀稳定和统一;
支持 GIF, 对 GIF 的压缩效果尤其显著, 可以节约企业大量的带宽资源以及数据空间;
运维同事及时跟进研究 WebP 并推动应用现网, 并基于该技术建立了最初的 CDN 图片压缩访问方案
压缩参数设置
通过验证发现, 压缩质量参数在编码后图片质量及大小间形成正相关关系, 质量参数越高, 编码后图片质量越好体积也就越大质量参数设置 70%~90% 间, 可以达到最优平衡现网默认设置 80%
编 / 解码性能优化
终端 WebP 解码性能, 在当前网络环境下不存在问题, 平均解码耗时在 100ms 以内并且, 通过有限制的使用 WebP 图片, 例如限制图片尺寸使用的 CPU 核心及最大频率等方式, 可以进一步优化编解码能力;
终端兼容性
嵌入 WebP 解码库的自有 APP 以及已知支持 WebP 的公共浏览器, 例如 ChromeOpera 等其他场景下无法解码 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 后台下发能力, 最终接入业务除相册外, 寥寥无几
阶段二: 引入 WebP/SharpP / 自适应多方式压缩, 业务无痛接入
老架构的图片压缩在 CDN 现网能正常服务部分业务, 减小服务器端带宽消耗和数据存储的同时, 提升了客户端的加载速度但该架构的固有缺陷也十分明显:
压缩能力有限, 只支持 WebP 一种方式, 跟不上行业压缩技术趋势;
压缩场景有限, 只支持兼容 WebP 格式的部分客户端访问;
对业务侵入严重, 导致实际推广效果不佳;
基于此, 在优化图片压缩访问方案的时候, 希望新架构能对业务侵入小甚至无侵入, 同时引入更高效的图片压缩技术进行现网推广使用项目历时 15~16 共两年时间, 期间我们也跟随行业编码技术趋势, 在优化成熟 WebP 自适应方案同时, 创新性的引入了 SharpP 编码技术
编码技术: 优化 WebP, 新引入腾讯自研 SharpP 及分辨率自适应调整能力
WebP 编码在原图基础上节约 30% 左右大小, 但随着 H.265VP9 以及 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 图片 |
运营方案: 对业务最小侵入的图片压缩访问架构
让业务以最小的改动代价来获得最大的带宽及性能收益, 才能让技术架构更容易推广
考虑到 AcceptUser-Agent 属于标准的 HTTP 请求头字段, 分别用来承载客户端的解码能力信息及屏幕分辨率信息, 也属常理; 并且类似 ChromeOpera 这种已支持 WebP 的浏览器, 请求头默认有带上 Accept: image/webp 字段, 完全兼容该套方案
a. 基于 Accept 头的 WebP/SharpP 自识别编码
PC 浏览器, 例如 ChromeOpera 等, 支持 WebP 解码情况下, 在请求头 Accept 字段中默认有带上 image/webp 字段, 兼容该套压缩访问框架;
非浏览器类, 例如 APPPC 客户端, 在发送图片请求前, 可根据编码能力, 自定义添加或通过底层 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 以上, 同时该套方案也正在向全公司内部推广
阶段三: 持续引领, 引入 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 编码优势明显
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);
来源: https://cloud.tencent.com/developer/article/1029772