QUIC的实际应用:Uber如何实施以优化性能

QUIC协议非常有趣,因此我们很乐意编写它。 但是,如果以前有关QUIC的出版物更多是历史性(当地历史,如果您喜欢的话)的性质和材料,那么今天我们很高兴发表不同的解释-我们将在2019年讨论该协议的实际应用。 它不是关于基于条件车库的小型基础设施,而是关于几乎在全世界都可以使用的Uber。 该公司的工程师是如何决定在生产中使用QUIC的,他们如何进行测试以及轧制后的结果-削减了成本。
图片是可单击的。 祝您阅读愉快!



Uber在全球范围内,即600个存在城市,在每个城市中,应用程序完全依赖来自4,500多家移动运营商的无线互联网。 用户希望该应用程序不仅可以快速运行,而且可以实时运行-为了确保这一点,Uber应用程序需要低延迟和非常可靠的连接。 las, HTTP / 2堆栈在动态且容易丢失的无线网络中感觉不太好。 我们意识到,在这种情况下,性能低下与操作系统内核中的TCP实现直接相关。

为了解决该问题,我们使用了具有通道复用功能的现代协议QUIC ,它使我们能够更好地控制传输协议的性能。 IETF工作组目前正在将QUIC标准化为HTTP / 3

经过详细的测试,我们得出的结论是,与TCP相比,在我们的应用程序中实施QUIC将使“尾部”延迟减少。 在驾驶员和乘客应用程序的示例中,我们观察到HTTPS流量减少了10-30%。 QUIC还为我们提供了对自定义包的端到端控制。

在本文中,我们分享了使用支持QUIC的堆栈为Uber应用程序优化TCP的经验。

技术的硬道理:TCP


如今,TCP是用于在Internet上传递HTTPS流量的最常用的传输协议。 TCP提供可靠的字节流,从而应对网络拥塞和链路层丢失。 前者的普遍性(几乎每个操作系统都包含TCP),大多数基础结构的可用性(例如,负载平衡器,HTTPS代理和CDN)以及现成的功能(大多数平台和平台都可用)解释了TCP在HTTPS流量中的广泛使用。网络。

大多数用户在旅途中使用我们的应用程序,而TCP尾部延迟远非我们HTTPS流量的实时要求。 简而言之,全世界的用户都面临这个问题-图1显示了大城市的延误:


图1.在Uber经营的主要城市,“尾巴”延误的幅度有所不同。

尽管事实上,印度和巴西网络的延误比美国和英国多,但延误比平均延误要大得多。 即使对于美国和英国也是如此。

空中TCP性能


TCP是为有线网络创建的,也就是说,重点在于可预测的链接。 然而, 无线网络具有其自身的特征和困难。 首先,无线网络易受干扰和信号衰减的影响。 例如,Wi-Fi网络对微波,蓝牙和其他无线电波很敏感。 蜂窝网络由于物体和建筑物对信号的反射/吸收以及邻近蜂窝塔的 干扰而遭受信号损失( 路径损失 )。 与有线连接相比,这导致更显着(4到10倍)和各种往返延迟(RTT)和数据包丢失。

为了应对带宽波动和损失,蜂窝网络通常使用大缓冲区来处理流量突发。 这可能导致过多的优先级,这意味着更长的延迟。 TCP通常将此类序列视为由于超时增加而造成的丢失,因此TCP倾向于进行中继并从而填充缓冲区。 这个问题被称为bufferbloat过多的网络缓冲,缓冲区膨胀 ),这是现代Internet的一个非常严重的问题

最后,蜂窝网络的性能取决于运营商,地区和时间。 在图2中,我们收集了2公里范围内所有小区的HTTPS流量的中值延迟。 收集了印度德里两个最大的移动运营商的数据。 如您所见,每个单元的性能都不同。 另外,一个操作员的性能与第二个操作员的性能不同。 这受诸如网络访问模式,时间和位置,用户移动性以及网络基础设施等因素的影响,其中考虑了塔的密度和网络类型(LTE,3G等)的比率。


图2. 2 km半径示例的延迟。 印度德里。

而且,蜂窝网络的性能随时间而变化。 图3显示了按星期几的中位数延迟。 我们还观察到在一天零一个小时内规模较小的差异。


图3.尾巴延误在不同的日期会有不同的变化,但使用同一操作员。

所有以上这些导致TCP性能在无线网络中效率低下的事实。 但是,在寻找TCP的替代方案之前,我们希望对以下几点有准确的了解:
  • TCP是我们应用程序中拖尾延迟的主要根源吗?
  • 现代网络是否具有显着变化的往返延迟(RTT)?
  • RTT和TCP性能损失的影响是什么?

TCP性能分析


为了了解我们如何分析TCP性能,让我们简要回顾一下TCP如何将数据从发送方传输到接收方。 首先,发送方通过执行三向握手建立TCP连接:发送方发送SYN数据包,等待接收方的SYN-ACK数据包,然后发送ACK数据包。 另外的第二和第三遍创建TCP连接。 接收者确认收到每个数据包(ACK),以确保可靠的传递。

如果数据包或ACK丢失,则发送方将在超时(RTO, 重传超时 )后重新发送 。 RTO是基于各种因素(例如,发送方和接收方之间的预期RTT延迟)动态计算的。


图4. TCP / TLS数据包交换包括重传机制。

为了确定TCP在我们的应用程序中的工作方式,我们用tcpdump监视了一个星期的TCP数据包,以应对来自印度边境服务器的战斗流量。 然后,我们使用tcptrace分析了TCP连接。 另外,我们创建了一个Android应用程序,该程序将模拟流量发送到测试服务器,并尽可能地模拟真实流量。 具有此应用程序的智能手机已分发给几名收集了几天日志的员工。

两个实验的结果彼此一致。 我们看到了很大的RTT延迟; 尾巴值几乎是中值的6倍; 延迟的算术平均值-超过1秒。 许多连接丢失,导致TCP重新传输所有数据包的3.5%。 在机场和火车站等交通拥挤的地区,我们发现损失了7%。 这样的结果使人们对以下传统观念产生了怀疑:蜂窝网络中使用的高级重传方案可以显着减少传输损耗。 以下是“模拟器”应用程序的测试结果:
网络指标价值观
RTT,毫秒[50%,75%,95%,99%][350、425、725、2300]
RTT差异,秒平均〜1.2 s
不稳定连接中的数据包丢失平均〜3.5%(拥堵区域为7%)

这些连接中几乎有一半至少丢失了一个数据包,其中大多数是SYN和SYN-ACK数据包。 大多数TCP实现对SYN数据包使用1秒的RTO值,对于随后的丢失,此值呈指数增长。 由于TCP需要更多时间建立连接,因此应用程序加载时间可能会增加。

对于数据包,在无线网络出现暂时性丢失的情况下,较高的RTO会大大降低有用的网络利用率。 我们发现平均重传时间约为1秒,拖尾延迟将近30秒。 TCP级别的如此高的延迟导致HTTPS超时和重试,这进一步增加了延迟和网络效率低下。

虽然所测量的RTT的第75个百分位数约为425毫秒,但TCP的第75个百分位数约为3秒。 这暗示了丢失迫使TCP进行7-10次传递才能成功传输数据。 这可能是由于RTO计算无效,TCP无法快速响应窗口中最后一个数据包的丢失以及拥塞控制算法的效率低下所致,后者无法区分无线丢失和由于网络拥塞而造成的丢失。 以下是TCP丢失测试结果:
TCP丢包统计价值
丢失至少1个数据包的连接百分比45%
建立连接期间丢失连接的百分比30%
数据交换期间丢失连接的百分比76%
重发延迟分布,秒[50%,75%,95%,99%][1、2.8、15、28]
单个数据包或TCP段的重传分布[1,3,6,7]

QUIC应用


QUIC最初由Google设计,是一种多线程,现代的传输协议,可在UDP之上运行。 目前,QUIC正在标准化过程中 (我们已经写过,有两个版本的QUIC,好奇的人可以关注该链接 -大约翻译器)。 如图5所示,QUIC托管在HTTP / 3下(实际上,QUIC之上的HTTP / 2-这是HTTP / 3,现在已被严格标准化)。 它使用UDP形成数据包,部分替换了HTTPS和TCP层。 由于TLS已完全集成在QUIC中,因此QUIC仅支持安全的数据传输。


图5:QUIC在HTTP / 3下工作,代替了以前在HTTP / 2下工作的TLS。

下面我们列出说服我们使用QUIC加强TCP的原因:
  • 0-RTT连接设置。 QUIC允许重用来自先前连接的授权,从而减少了安全握手的次数。 将来, TLS1.3将支持0-RTT,但仍需要三向TCP握手。
  • 克服HoL阻塞。 HTTP / 2为每个客户端使用一个TCP连接来提高性能,但是这可能会导致HoL(行头)块。 QUIC简化了多路复用,并将请求彼此独立地传递到应用程序。
  • 拥塞管理。 QUIC处于应用程序级别,可以更轻松地根据网络参数(丢失量或RTT)更新控制传输的主要传输算法。 大多数TCP实现都使用CUBIC算法,这对于延迟敏感的流量不是最佳的。 最新开发的算法(例如BBR)可以更准确地为网络建模并优化延迟。 QUIC允许您使用BBR并在改进时更新此算法。
  • 弥补损失。 QUIC会在RTO触发之前调用两个TLP( 尾部损耗探测器 )-即使损耗非常明显。 这与TCP实现不同。 TLP主要重传最后一个数据包(或新数据包,如果有的话)以触发快速补充。 尾部延迟处理对于Uber与网络的工作方式特别有用,即用于短,偶发和对延迟敏感的数据传输。
  • 优化的ACK。 由于每个数据包都有唯一的序列号,因此在中继数据包时不存在区分它们的问题。 ACK数据包还包含处理数据包和生成客户端ACK的时间。 这些功能确保QUIC可以更准确地计算RTT。 QUIC ACK最多支持256个NACK范围,从而帮助发送方更加灵活地进行数据包交换,并在此过程中使用更少的字节。 TCP中的选择性ACK( SACK )不能在所有情况下解决此问题。
  • 连接迁移。 QUIC连接由64位ID标识,因此,如果客户端更改IP地址,则可以在不中断的情况下继续在新IP地址上使用旧连接的ID。 当用户在Wi-Fi和蜂窝连接之间切换时,这对于移动应用程序来说是非常普遍的做法。

QUIC的替代品


在选择QUIC之前,我们研究了解决问题的替代方法。

首先,我们尝试部署TPC PoP(存在点)以完成更接近用户的TCP连接。 本质上,PoP会终止与移动设备的TCP连接,使其更靠近蜂窝网络,并代理到原始基础结构的流量。 关闭TCP,我们有可能减少RTT,并确保TCP对动态无线环境的响应更快。 但是,我们的实验表明,RTT和损耗大部分来自蜂窝网络,而PoP的使用并不能显着改善性能。

我们还着眼于调整TCP参数。 在我们的异构边缘服务器上配置TCP堆栈很困难,因为TCP在不同的OS版本上有不同的实现。 很难实现这一点并测试各种网络配置。 由于缺乏权限,无法直接在移动设备上配置TCP。 更重要的是,诸如0-RTT连接和改进的RTT预测之类的芯片对于协议体系结构至关重要,因此仅通过配置TCP就不可能获得显着的收益。

最后,我们评估了几种对视频流进行故障排除的基于UDP的协议-我们想知道这些协议对我们的案例是否有帮助。 las,它们缺乏许多安全设置,并且还需要用于元数据和控制信息的附加TCP连接。

我们的研究表明,QUIC几乎是唯一可以解决互联网流量问题的协议,同时兼顾了安全性和性能。

QUIC集成到平台中


为了成功集成QUIC并在恶劣的通信条件下提高应用程序性能,我们用QUIC协议替换了旧的堆栈(通过TLS / TCP的HTTP / 2)。 我们使用了Chromium ProjectsCronet网络库,其中包含协议的原始Google版本-gQUIC。 该实现也正在不断改进,以遵循最新的IETF规范。

首先,我们将Cronet集成到我们的Android应用中以添加QUIC支持。 进行集成是为了最大程度地减少迁移成本。 我们没有完全取代使用OkHttp库的旧网络堆栈,而是在OkHttp API框架下集成了Cronet。 通过这种方式进行集成,我们避免了API级别的网络调用( Retrofit使用)的更改。

与Android设备的方法类似,我们在iOS的Uber应用程序中实现了Cronet,使用NSURLProtocol拦截来自网络API的 HTTP流量。 由iOS Foundation提供的此抽象处理特定于协议的URL数据,并确保我们可以将Cronet集成到我们的iOS应用程序中,而无需花费大量的迁移成本。

Quic已在Google Cloud Balancers上完成


在后端,QUIC终止由Google云负载平衡基础结构提供,该基础结构使用alt-svc标头作为响应来支持QUIC。 通常,平衡器将alt-svc标头添加到每个HTTP请求,并且它已经验证了对该域的QUIC支持。 Cronet客户端收到带有此标头的HTTP响应时,它将QUIC用于对该域的后续HTTP请求。 平衡器完成QUIC后,我们的基础架构就会通过HTTP2 / TCP将此操作明确发送给我们的数据中心。

绩效:结果


出色的性能是我们寻求更好协议的主要原因。 首先,我们创建了一个具有网络仿真功能的展台,以了解QUIC在不同网络配置文件下的行为。 为了测试QUIC在实际网络中的运行情况,我们在新德里附近进行了实验,使用模拟的网络流量,该流量与乘客应用程序中的HTTP呼叫非常相似。

实验1


实验清单:
  • 具有OkHttp和Cronet堆栈的Android测试设备,以确保我们分别通过TCP和QUIC发送HTTPS流量;
  • 基于Java的仿真服务器,该服务器在响应中发送相同类型的HTTPS标头,并加载客户端设备以接收来自它们的请求;
  • 物理上位于印度附近的云代理,以完成TCP和QUIC连接。 虽然我们在NGINX上使用反向代理来完成TCP,但是很难找到QUIC的开源反向代理。 我们使用Chromium的基本QUIC堆栈为自己构建了QUIC的反向代理,并以铬作为开源发布了它。


图6. TCP vs QUIC测试的行程集包括具有OkHttp和Cronet的Android设备,用于终止连接的云代理以及一个仿真服务器。

实验2


当Google使用Google Cloud Load Balancing使QUIC可用时,我们使用了相同的清单,但进行了修改:代替NGINX,我们使用Google平衡器来完成来自设备的TCP和QUIC连接,并将HTTPS流量定向到仿真服务器。 。 平衡器分布在世界各地,但使用距离设备最近的PoP服务器(由于地理位置原因)。


图7.在第二个实验中,我们想比较TCP完成延迟和QUIC:使用Google Cloud和使用我们的云代理。

结果,一些启示正在等待着我们:
  • PoP终止改善了TCP性能。 由于平衡器完成了更接近用户的TCP连接并进行了完美的优化,因此降低了RTT,从而提高了TCP性能。 QUIC , TCP ( 10-30 ).
  • (hops) . QUIC- ( 50 ), , – 15%- 20%- 99 TCP. , – (bottleneck) .


8. , QUIC TCP.


, QUIC Android iOS-. A/B , QUIC Uber. , , .

(95 99 ) – LTE, 3G, 2G.

9. QUIC TCP .


, – QUIC , , :


, , 80% QUIC , 15% QUIC TCP. , - , Cronet TCP , UDP- . , QUIC.

QUIC


, . . , , TCP QUIC . QUIC- .

, .

Source: https://habr.com/ru/post/zh-CN463073/


All Articles