从标题也可以知道,这是一篇关于HTTP2的一个重要特性头部压缩HPACK算法的blog,HPACK在中文互联网上已经有不少HPACK相关的文章,google搜HPACK 算法关键词大概能出来个十来页。大部分都是偏介绍性质,或者一些对RFC 7541、HPACK: the silent killer (feature) of HTTP/2等文章的翻译。其实HPACK的思想很简单,再写篇介绍性质的文章我觉得意义不大,所以这里我将试着从协议设计和实现的角度深入分析HPACK,试着了解HPACK的一些design choices。在进入正题之前,有必要先说下它的诞生背景。
Patrick McManus曾在In Defense of Header Compresson邮件中给出了header压缩与否对延迟的影响的一些数据,很直观地说明了header压缩的必要性。
在如今的互联网上, 一个页面里通常会包含很多资源,每个资源都会需要http请求去加载,如果每个请求的header大小是1400字节(Cookies, Referer之类的header通常都很大,所以1400字节大小规模并不鲜见),光是要去传输这些headers,可能都需要花费7-8个rtt,造成这一现象的原因是TCP拥塞控制算法的slow start过程。此时如果能对header进行压缩,会很大程度上降低http请求的延迟。
前一篇blog中,为了弄清楚长久一来一直困惑我的deflate、zip、gzip、zlib这些关系,我在互联网的各个角落里翻阅了不少RFC和web pages,我觉得算是基本弄清楚它们之间来龙去脉和联系了,接下来进入正题,写写关于Deflate算法。我对这个算法的兴趣源自于之前在公司内部做的一个优化imo客户端和服务端通讯协议相关的工作。本着向经典致敬的态度,我先是深入了解了下Deflate,在学习过程中,我先是找到了RFC 1951也就是Deflate压缩标准来啃,通读一篇发现还是对deflate的工作原理和细节还是模模糊糊,原因是RFC 1951里只有标准,不涉及解释,也就说只说了怎么做,没有解释为什么这么做。后来发现zlib的作者在An Explanation of the Deflate Algorithm一文中对Deflate算法的原理和trouble points做了比较全面的解释,但是我第一次阅读这篇blog时对后半部分基本上没怎么看懂,原因是一方面我水平菜,另一方面我觉得是Antaeus Feldspar大神在这篇blog里省略了很多细节。在各种搜索了解这些缺失但是对理解算法很有必要的细节后,再读起来就比较顺畅了。这篇blog的内容就是扩充下An Explanation of the Deflate Algorithm的内容,补齐其缺失的细节。
在无损压缩算法中,Deflate基本是上互联网时代无损压缩算法的事实标准,我们日常生活常用的zip、gzip等工具、http协议中对body部分的常见压缩算法都是使用的Deflate。Deflate算法最早是由Phil Katz在编写PKZIP(也就是后来被广泛使用的ZIP)时提出,后来在众多自由软件先驱的努力下被众多广泛实现和应用,再被IETF标准化,形成Deflate压缩标准。Deflate算法本身也是在前人工作的基础上创新得到,主要基于LZ77算法和大名鼎鼎的Huffman coding算法,Zlib的作者在An Explanation of the Deflate Algorithm里对Deflate的工作原理做了很好的解释。接下来的主要内容也将会是结合Deflate原理,整理、学习和分析Deflate的一些design choices。不过进入正题之前,先来理清下这些常见名词到底是什么,我觉得应该有很多人和我一样被中文互联网上deflate、zlib、zip、gzip、tar的这些名词的混用而搞的晕乎乎的。