被自己以为的GZIP秀到了
问题的开始

我司某产品线有这么一个神奇接口 (https://host/path/customQuery)
该接口在预发或线上缓存正常的情况下TTFB为150ms左右(可以认为服务处理时间差不多就是TTFB),不过相比150ms的TTFB,显然数据资源下载时间过长的问题会更引人注意需要100ms左右(当然这也是网络条优秀的情况下,网络一般的话这个下载时间会更夸张)
customQuery请求一次请求的数据响应大概为2.7MB, 压缩后也有超过300KB
下载时间过长看起来就是因为这个响应实体过大了(100Mb的带宽满速,300KB差不多也需要30ms),通过测试可以发现同样的网络条件同一个应用的其他接口,如果响应压缩后小于1KB,其ContentDownLoad时间可以忽略不计(通常都会小于2ms)
因为代理默认开启了gzip,其实数据已经被压缩了近10倍,但是压缩后的数据还是过大。
分析了customQuery响应实体的数据结构。
发现数据每个list中fields节点大量重复出现。

如上图其中field的描述是完全一致的(按一页50条计算,这些数据重复了50遍)
这些数据field描述数据单个都大小大概是50KB(重复50次可以看到2.7MB的数据几乎都是这些重复的数据)
开始秀了
既然已经明确了这些重复描述数据,服务端的同学很自然想到把这些field描述提取出来重新组装数据可以大幅度减小数据传输的大小。
不过自己恰好曾经“看过”DEFLATE压缩(http的gzip正好使用的是DEFLATE)其中使用到的LZ77是会匹配前文相同短语后面的相同短语都会被替换成“标记”。
那我“秀”的时候又到了,当即表示采用这种数据重组的方式并不会带来明显的实际提升,因为数据实际的信息量没有实际变化,只是手动去除了冗余,而之前冗余的数据其实已经被gzip处理过了,所以仅仅单纯去除重复描述数据片段并不能带来预期的收益。
因为我秀的时候如此自信,对方马上就自己不自信了,表示要回去先验证效果后在做打算。
看起来是失败了
果然后面的结果“居然”是我被打脸了

customQuery接口返回的实体大小直接变成了25kb,解压后189kb(之前是327kb,解压后2.7Mb)
那这差距太大了,实体大小减小到了之前的10%不到,当然下载速度ContentDownLoad也有了大幅度的降低。(基本上就是一个RTT的时间)
不过这完全跟我之前的认知不一样啊,一定是哪里出现了问题。(毕竟是以为自己懂了系列)
试图抢救下
为了挽回颜面,我把这2组原始数据下载下来,本地压缩进行分析(还不想承认自己错了,试图找到产生这种结果的其他解释)
如下图老的数据为customQuery_v1(2.7MB),新的为customQuery_v2(190KB)

分别使用zip,gzip,rar对2组数据进行压缩 (gzip即为http默认使用的压缩算法,MAC上直接使用gzip命令可以对文件进行压缩)
可以发现RAR的压缩结果就与我最开始的想法差不多(即使原始数据差了超过10倍,而压缩的结果是几乎一致的,v1为19kb ;v2为17kb)
不过gzip对2组数据的压缩结果与在浏览器上看到的是一样的。(v1为329kb ;v2为25kb)
既然本地压缩也得到了同样的结果,看来真的是自己Too young too naive (大意了,没有闪,秀的时候应该先在本地验证一下的)
默默面对错误分析原因
但是为什么会有这样的结果,按我的理解压缩结果应该与rar一致才对。要搞清楚还要从压缩的方式入手。
一定是我以为的压缩行为与实际存在差异,gzip的基础是DEFLATE,DEFLATE是LZ77与哈夫曼编码的一个组合体( https://tools.ietf.org/html/rfc1951)
Huffman Coding 只是单纯的字符编码,编码后的大小与编码前的大小直接正相关,肯定不是产生结果的原因。
那剩下就只有是LZ77,只能是LZ77一开始没有把那些重复的fields压缩掉,而为什么LZ77没有把原始数据里大量重复的描述“标记”起来。
LZ77整体是是使用已经出现过的相应匹配数据信息替换当前数据从而实现压缩功能,为了匹配数据需要用到了“滑动窗口”的概念
细细一品,LZ77并不是全文匹配,数据为了可以边发送边压缩会进行分块压缩。通过查阅RFC文档,大概可以明确块的大小被限制在64k内,最大滑动窗口就是64k/2=32k,并且还要求“标记”的最大长度为256字节(当然标记长度这个问题不大,大不了不多用几个标记)。这里的问题在于使用滑动窗口就要求重复的数据必须要“相邻” 而块大小最大为64K,如果重复的2段数据不能出现在一个窗口内是不能被标记的。但是窗口最多是块大小的一半32Kb(实际也不会用这么大的窗口),而我们之前就计算过我们重复的单个field描述就有50Kb,要出现有2个重复的内容,即使2个描述相邻那也至少上100Kb(他们甚至都无法在同一个块里),实际上窗口最大32Kb,所以LZ77根本不能标记出这些重复的field。
以下引至https://tools.ietf.org/html/rfc1951#section-2
|
Compressed representation overview A compressed data set consists of a series of blocks, corresponding Each block is compressed using a combination of the LZ77 algorithm Each block consists of two parts: a pair of Huffman code trees that Each type of value (literals, distances, and lengths) in the |
总结
最终也还是自己错了,也没有什么好总结的
要是什么都不知道也不出问题,要是知道的很清楚也不会出问题,就是在“以为自己知道”的情况下就各种问题。
被自己以为的GZIP秀到了的更多相关文章
- Linux常见压缩命令 - gzip,zcat,bzip2,bzcat
几个常见的压缩文件扩展名 *.Z compress 程序压缩的文件: *.gz gzip 程序压缩的文件: *.bz2 bzip2 程序压缩的文件: *.tar tar 程序打包的数据,并没有压缩过: ...
- Android总结之Gzip/Zip压缩
前言: 做过Android网络开发的都知道,在网络传输中我们一般都会开启GZIP压缩,但是出于刨根问底的天性仅仅知道如何开启就不能满足俺的好奇心的,所以想着写个demo测试一下比较常用的两个数据压缩方 ...
- 易企秀微场景2016最新完整版V10.5,小编亲测修复众多错误
易企秀V10.5更新说明1.修复拨号英文错误2.修复转送场景问题3.修复设置场景密码乱码问题4.修复前台批量删除客户图片5.修复数据收集分页问题6.修复图片分类错乱问题7.修复音乐和特效冲突问题8.修 ...
- Android GZIP压缩IO流,优化APP数据传输(一)
我是小搬运工,今天讲解流的压缩传输 在我们安卓开发中,通常伴随着大量的数据传输,在此,楼主给出一个简单的压缩流的数据进行操作. public void GZIPCpf(String path) { / ...
- ASP.NET MVC 3 网站优化总结(一) 使用 Gzip 压缩
网站开启 Gzip 压缩的好处相信很多人都已经清楚,这样做可以提高网站的性能.那么为什么很多网站没有开启 Gzip 压缩功能呢?原因有4点:防病毒软件.浏览器 bug.网站代理和服务器未配置. 使用 ...
- 压缩和解压文件:tar gzip bzip2 compress(转)
tar[必要参数][选择参数][文件] 压缩:tar -czvf filename.tar.gz targetfile解压:tar -zxvf filename.tar.gz参数说明: -c 建立新的 ...
- Linux下的压缩和解压缩命令——gzip/gunzip
gzip命令 gzip命令用来压缩文件.gzip是个使用广泛的压缩程序,文件经它压缩过后,其名称后面会多处".gz"扩展名. gzip是在Linux系统中经常使用的一个对文件进行压 ...
- php关于ob_start('ob_gzhandler')启用GZIP压缩的bug
如果使用ob_start("ob_gzhandler"); 则ob_clean()后面的输出将不显示,这是个bug,可以用ob_end_clean();ob_start(" ...
- 使用HttpClient来异步发送POST请求并解析GZIP回应
.NET 4.5(C#): 使用HttpClient来异步发送POST请求并解析GZIP回应 在新的C# 5.0和.NET 4.5环境下,微软为C#加入了async/await,同时还加入新的Syst ...
随机推荐
- PyQt(Python+Qt)学习随笔:QTabWidget部件选项卡可用状态访问方法isTabEnabled、setTabEnabled
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTabWidget的每个选项卡及页面可设置是否可用,如果选项卡不可用时,则不能通过操作手工切换到该 ...
- PyQt(Python+Qt)学习随笔:QTabWidget选项卡部件的documentMode属性作用
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTabWidget的documentMode属性用于控制是否以适合文档页的模式呈现选项卡部件.这与 ...
- Python正则表达式处理中的匹配对象是什么?
老猿才开始学习正则表达式处理时,对于搜索返回的匹配对象这个名词不是很理解,因此在前阶段<第11.3节 Python正则表达式搜索支持函数search.match.fullmatch.findal ...
- Python正则表达式re模块学习遇到的问题
Python正则表达式处理的组是什么? Python正则表达式处理中的匹配对象是什么? Python匹配对象的groups.groupdict和group之间的关系 Python正则表达式re.mat ...
- sails框架结合mocha的测试环境搭建
一.环境结构 1.首先最底层是操作系统 2.其次在操作系统之上是Node.js的运行环境,和Database 3.再之上就是sail和mocha框架 二.环境搭建 1.首先需要Node.js的运行环境 ...
- CSS常用语法缩写
使用缩写可以帮助减少你CSS文件的大小,更加容易阅读.CSS常用语法缩写的主要规则如下: 颜色 16进制的色彩值,如果每两位的值相同,可以缩写一半,例如:#000000可以缩写为#000;#33669 ...
- 从HBase底层原理解析HBASE列族不能设计太多的原因?
在之前的文章<深入探讨HBASE>中,笔者详细介绍了: HBase基础知识(包括简介.表结构).系统架构.数据存储 WAL log和HBase中LSM树的应用 HBase寻址机制 mino ...
- ARC109F - 1D Kingdom Builder
一行格子,其中小于\(0\)的格子为白色,大于\(n\)的格子为黑色,中间的格子颜色由题目给出. 有一些格子需要被标记.标记按照以下规则进行:选择一个颜色\(c\),找到一个未标记的 旁边有标记点的 ...
- 基于jaccard相似度的LSH
使用Python通过LSH建立推荐引擎 LSH:一个可以用来处理成百上千行的算法 前提: Python 基础 Pandas 学完本教程之后,解锁成就: 通过建立shingles 为LSH准备训练集和测 ...
- JOISC2020 自闭记
以下是我考场上的思路,很多题都不是正解.对于某些题目,我们使用<代码部落>中的题解,希望大家能够看懂 JOISC2020 Round1 自闭记 T1 11 pts 算法:考虑\(DP\). ...