不要迷信 QUIC

这篇具有很好参考价值的文章主要介绍了不要迷信 QUIC。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

很多人都在强调 QUIC 能解决 HoL blocking 问题,不好意思,我又要泼冷水了。假设大家都懂 QUIC,不再介绍 QUIC 的细节,直接说问题。

和 TCP 一样,QUIC 也是一个基于连接的,保序的可靠传输协议,TCP 的问题,QUIC 本质上都存在,只是看谁的处理方式更合理更优雅些,不存在彻底解决。QUIC 并没有解决 HoL blocking,只是缓解。里外高低都得先从多路复用开始说。

QUIC 多路复用指的是可以将多条 stream 封装在同一个 QUIC packet 中,或换句话说,多条 stream 可以通过同一条 QUIC connection 承载。

至于为什么非要多路复用,与 HTTP 相关,参考从【这里】开始往后的段落。

若只有 1 条 stream A,QUIC 与 TCP 无异,传输 A1~A100 这 100 个 packet,若 A2 丢了(or 乱序),传输会停滞,receiver 在 hole 未补充前无法交付数据,这就是 HoL blocking。

若一条 QUIC connection 承载 3 条 stream,记为 A,B,C,可有以下典型布局:
不要迷信 QUIC
第一种布局,只要丢一个 packet,3 条 stream 全部 HoL blocking,第二种,第三种布局下丢一个 packet 只影响一条 stream,但它并不比多条 TCP 好多少,虽确实减少了握手开销,但也带来了问题。第二种情况属于 fair sharing,它延迟了所有 stream,将每条流的传输延时摊派到所有 3 条流的总传输延时,第三种情况属于 run-to-completion,只是简单将 3 条路串行化。

有两种典型丢包模式,随机丢和密集丢,随机丢情况下,按照中心极限定理,所有 stream 同等概率遭遇 HoL blocking,而密集丢情况下,中心极限定理依然起作用,只是影响时间跨度更大。无论如何,采用单条多路复用 QUIC connection 和采用多条 TCP 相比,在传输层面没有任何改变。

TCP 的问题在于它无法获取网络快照,在同样背景信息下,QUIC 也好不到哪里去。 无法预知网络丢包模式,千万不要猜测或假设网络丢包模式,这只会让结果偏离统计期望。采用随机布局是最好的,比如 AABBBACCCBCAABBAAAABCCBBA,这和多条 TCP 有什么不同呢?

QUIC 并没有解决 HoL blocking,只是缓解。但即便是缓解 HoL blocking,QUIC 多路复用也不如 receiver 的 Out-Of-Order Queue 作用更大,ofo Queue 提供了一个 buffer 用来松散保序约束,这才是抓住了本质,若非如此,GBN 才是真正受 HoL blocking 之大害。

此外,实际场景中,stream 数量倾向于少,而丢包乱序倾向于多,这往两边拉,QUIC 解决 HoL blocking 的解释更苍白无力。

那么 QUIC 多路复用的意义到底在哪里?

【这里】我曾说过,QUIC 是从 HTTP 协议演化而来的,当然适配它诞生的水土,HTTP 请求的一个页面上有 jpg,text,javascript 等多种元素,将这些打包在一起再合适不过。QUIC 并不适合传输单个大文件,它简直就是针对 HTTP 的。HTTP/2 提出了二进制分帧,多个资源可以整合在一起传输,但依然沿用了 TCP,整个请求被单一 TCP 连接承载,HoL blocking 问题非常明显。

解决 HTTP/2 HoL blocking 的思路是既然分帧层自己知道多路复用细节,就让分帧层自己处理单独 stream 的 HoL blocking,而不是 TCP 去处理,TCP 不识别 stream,它自身只是一条 stream。就这样,QUIC 诞生了。收到 p2,p3,p4,p5,p8,p10,丢了 p1,p6,p7,p9,对于 TCP,这些数据一个字节也没法交付,全堵在 rcvbuff,而对于 QUIC,也许可交付一部分数据,比如恰好同一个 stream 在收到的 packet 中而没包含在丢失的 packet 中,但也只是也许可以交付,不能保证。

QUIC 只是缓解了 HTTP/2 的 TCP HoL blocking。可为什么不用多条 TCP?为什么不能为每个资源创建一条 TCP 连接?

用进程/线程,协程来解释再恰当不过。指令流是一条需保序可靠执行的串行流。

TCP 和进程/线程一样,是系统感知的,创建一条 TCP 连接,需要握手时间开销,还需要生命周期内连接状态的空间开销,就好比创建一个进程需要生成 PCB 的时间开销,保存 PCB 需要空间开销,都是系统开销,它们的时空复杂度都是 O(n),无论 TCP 连接还是进程/线程,都不可扩展。

因此,为每个请求创建一个进程或线程的 MPM 方案基本都被淘汰了,工人们倾向于在固定数量的进程中处理任意数量的请求,比如 Nginx 就是这种架构。在编程 API 层面上,这就是协程。

协程是系统不感知的,因此也就没有系统开销。QUIC 中的 stream 就是传输协议中协程,QUIC 就是基于 “协-stream” 的多路复用传输协议。

在执行过程中,协程并不比多进程/多线程更快,在很矬的 CPU 上,协程的效果可能还要更差,协程的优势在于资源整合和调度,而非执行效率。与此一致,QUIC 并不比多条 TCP 更快,QUIC 可能确实修正了 TCP 的一些硬伤,比如 SACK blocking 的限制,rwnd 的限制等,但这种 patch 式修正终究改变不了太多,QUIC 的优势亦在资源整合和调度。
我来梳理一下整个故事,TCP 故事里纯背锅。

1997 年 RFC2068 定义的 HTTP/1.1 并没有强制 HTTP 一定要被 TCP 承载:

HTTP communication usually takes place over TCP/IP connections. The default port is TCP 80, but other ports can be used. This does not preclude HTTP from being implemented on top of any other protocol on the Internet, or on other networks. HTTP only presumes a reliable transport; any protocol that provides such guarantees can be used; the mapping of the HTTP/1.1 request and response structures onto the transport data units of the protocol in question is outside the scope of this specification.

注意关键句子 “HTTP only presumes a reliable transport”,彼时除了 TCP 并没有任何成熟的 “reliable transport”(当然,现在也就多了个 QUIC),只好借 TCP 承载 HTTP/1.1。

是 HTTP/1.1 先遭遇了 HoL blocking 而不是 TCP,即时不丢包场景,在 1G 的 text 后跟一个 1K 的 jpg 是一个典型的 HoL blocking case,因为 HTTP Request/Response 必须串行,而 Request 并不知道 text 和 jpg 的大小。如果 Request 知道 jpg 只有 1K,肯定会先请求 jpg,从而解除 HoL blocking。

为 HTTP/1.1 加个二进制分帧层,将文件分片混合传输,就解决了问题,由于此时依然没有除 TCP 外的 reliable transport,加上 HTTP over TCP 已默认成准则,HTTP/2 沿用了 TCP 作为承载协议。这时才遇到 TCP 的 HoL blocking 问题。

缓解(再也不要说解决) TCP HoL blocking 的直接方案就是创建多条 TCP 连接。虽然粒度较粗,但和 “多线程解决单线程 IO 等待的 HoL blocking” 的方法如出一辙。紧接着,出现新的问题,创建多条 TCP 的开销过大,这和多进程,多线程系统开销过大也是同样的嘈点。可以预料,解决问题的思路也一样。

HTTP/3 选择 QUIC 作为传输层,和多条 TCP 连接缓解 HoL blocking 效果相当,但解决了可扩展性问题,消去了 O(n) 增长的 TCP 连接管理开销。

这就是整个故事梗概,TCP 从最开始作为受命托付者,承载 HTTP 20 年,最后却被吐槽,被 QUIC “取而代之”。但实际上,这哪是 TCP 的锅,这是 HTTP 的锅啊。

保序传输本身就是顺序依赖,必须串行解除,这意味着 HoL blocking 是其内秉属性,而非问题。事实上,假如(只是假如)为 HTML 超链接资源加上 size 属性,浏览器便可在少量 TCP 连接上按某种策略 “调度” 资源的 Request,比如 SRPT(Shortest Remaining Processing Time),优先请求最小的资源,就像在 4 个 CPU 上调度 N 个进程一样,总有最优解。

超链接资源支持 size 显然很难,动态获取则需额外一个 RTT,但创建多条 TCP,并行请求多个资源,依然还是调度问题。HTTP 缺的不是一个解决 HoL blocking 问题的传输协议,因为没有这样的协议,HTTP 是个资源池,缺的是调度器。

在公网,QUIC 取代 TCP 的呼声高涨,而老教授 John Ousterhout 也在喷 TCP 不适合 DC。但 TCP 大概率不会消失,无论是 HTTP-Oriented QUIC,or RPC-Oriented Homa,都无法取代 Everything-Oriented TCP,TCP 不假设任何先验,它的意义不是在资源充盈的时候表现得多好,而是最坏的情况下它不至于太糟糕。

当然,QUIC 有很多相对 TCP 的优势,不然它就没有存在的必要了,本文的主旨是,看到不足,才知进步。

HoL blocking 是串行流的内在属性,无论对指令流的执行还是 byte stream 的传输,本质都一样,都是保序流,保序流意味着顺序依赖,且这种顺序只允许唯一一种可能性,降低了容错空间,HoL blocking 对效率的影响显而易见。但经常听到 “QUIC 解决了 HoL blocking” 的说法,需要澄清一下了。最近在读 《布匿战争》,执政官 A 从墨西拿海峡率领 2 个军团纵贯狭长的意大利半岛赶去阿尔卑斯山南麓驰援执政官 B,如何行军最快?列队行军吗?执政官 A 对军团下令,就地解散,个人或结伴自行北上,到达执政官 B 附近后重新列队。这就是乱序传输了,解除了顺序依赖,效率自然高。

浙江温州皮鞋湿,下雨进水不会胖。文章来源地址https://www.toymoban.com/news/detail-406636.html

到了这里,关于不要迷信 QUIC的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 现代 CSS 解决方案:accent-color 强调色

    accent-color 是从 Chrome 93 开始被得到支持的一个不算太新属性。之前一直没有好好介绍一下这个属性。直到最近在给一些系统整体切换主题色的时候,更深入的了解了一下这个属性。 简单而言,CSS accent-color 支持使用几行简单的 CSS 为 表单元素 着色,是的,只需几行代码就可以

    2024年03月09日
    浏览(40)
  • 【使用debian镜像】docker的基础镜像很多,生产环境中使用建议还是不要使用centos和alpine的基础镜像了,直接使用debian的基础镜像即可。

    本文的原文连接是: https://blog.csdn.net/freewebsys/article/details/108971807 未经博主允许不得转载。 博主CSDN地址是:https://blog.csdn.net/freewebsys 博主掘金地址是:https://juejin.cn/user/585379920479288 博主知乎地址是:https://www.zhihu.com/people/freewebsystem 为啥要使用debian镜像呢? 首先 centos的官网已

    2024年02月08日
    浏览(46)
  • vscode的vue中出现很多红色波浪线解决办法

    出现这个的原因是代码和vetur插件的格式不对应。解决办法 如果还是不行的话就找这个插件 可以先禁用或删除,禁用过后记得重新启动一下VScode。

    2024年02月12日
    浏览(45)
  • Android Studio 控制台中文乱码,解决方案都在这里了,完美解决

    Android Studio 如果不进行配置的话,运行程序时控制台中文乱码问题会非常严重,甚至影响我们对信息的获取和程序的跟踪。 通过历年的开发经验,在本文中我总结出四点用于解决控制台中文乱码问题的方法,希望有助于大家。 注意 :下面根据我日常工作的经验总结,排序的

    2023年04月08日
    浏览(82)
  • Java中关于内存泄漏分析和解决方案,都在这里了!

    最近正在熟悉Java内存泄漏的相关知识,上网查阅了一些资料,在此做个整理算是对收获的一些总结,希望能对各位有所帮助,有问题可以文末留言探讨、补充。 如下是整篇文章的结构,所需阅读时间大约20min 内存泄漏 :对象已经没有被应用程序使用,但是垃圾回收器没办法

    2024年02月13日
    浏览(44)
  • VS Code打开vue文件出现很多黄色波浪线的解决办法(完美解决!!!)

    最近下拉代码到VS Code中有很多的黄色波浪线,通过下面这种方法完美解决!!!! 如图,这一堆黄色波浪线,看到都头皮发麻,下面通过下面的方法完美解决。 其实就是 ESLint 这个插件引起的。 ESLint是一个用来识别 ECMAScript 并且按照规则给出报告的代码检测工具,使用它可

    2024年02月07日
    浏览(47)
  • 在Visual Studio Code中有很多红色波浪线怎么解决?

     这么看呢,代码没什么问题,为什么有那么多红色波浪线呢?其实出现这个的原因是代码和vetur插件的格式不对应所以导致出现红色波浪线。解决办法  1.可以严格遵循vetur的格式去写,不过麻烦。  2.打开设置搜索vetur 将这三个取消掉。  

    2024年02月16日
    浏览(50)
  • 织梦DEDECMS友情链接出现内页与首页都在首页显示解决方法

    dedecms首页调用友情链接的时候,自己制作的模板有时候会出现内页链接显示的情况。那么怎么才能只调用首页链接呢,其实早就有了解决的办法,很多用DEDECMS的朋友都对内页友情链接与首页友情链接都在首页显示的问题所困扰。 方法: 进入后台--模板---默认模板管理,找到

    2024年02月02日
    浏览(50)
  • Java下载文件,中文文件名乱码问题解决(文件名包含很多%)

    一般情况下,大家都是这样: 其实乱码就是乱在;filename=\\\" + fileName这里,对文件名的编码设定上。 使用URLEncoder.encode(filepath,\\\"UTF-8\\\")虽然可以解决在提示下载框中正确显示汉字文件名的问题,并且在选择保存,然后打开的情况下,文件名称也可以正确的显示。 但是在提示下载框

    2024年02月12日
    浏览(51)
  • #git篇:Vscode消除侧边栏文件夹git颜色包含强调项

    代码里的左侧颜色标识: 红色,未加入版本控制; 远程clone到本地 绿色,已经加入版本控制暂未提交; (新增部分) 蓝色,加入版本控制,已提交,有改动; (修改部分) 白色,加入版本控制,已提交,无改动; 灰色:版本控制已忽略文件。 场景: 将文件从一个文件夹移动到另一

    2024年02月12日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包