如何设计一个可靠UDP

news/2024/5/18 14:09:18 标签: udp, 网络协议, 网络

背景

通信领域存在制约三角:时延,成本和质量。TCP是增大时延和成本来保证通信质量,UDP牺牲了质量保证了时延和成本。一定场景使用RDP可以找到这三之间的平衡点。实现可靠UDP主要有三种方式:

  • 尽力可靠:接收方要求发送放数据尽量完整到达,但是业务本身的数据可以丢失的,如音视频
  • 无序可靠:通信放要求发送方数据必须完整到达,但是顺序不重要,如文件传输,日志追加
  • 有序可靠:通信方要求发送方数据必须顺序完整到达

为什么要实现可靠UDP?

主要解决以下问题:

  • 端对端连通性问题:终端之间通信会跨NAT,TCP在NAT之间穿越非常困难,然后uDP就简单很多,如:端对端文件传输,音视频传输等;
  • 弱网传输问题:TCP的延迟受网络影响比较大,如:实时操作网友,语音对话等;
  • 宽带竞争问题:有时候客户端上传数据要突破TCP公平性限制来达到高速低时延和稳定,如音视频直播推流,可以压榨带宽;
  • 传输路径优化:对于时延要求比较高就会用应用层relay的方式来进行选路优化延时,比如服务之间数据转发,数据备份
  • 资源优化问题:主要是避免三次握手和四次挥手,如QUIC

所以首要是实现可靠性,保证质量,核心就是重传。RUDP重传是通过接收端的ACK丢包信息反馈来进行数据重传,主要分为:定时重传、请求重传和FEC重传。

  • 定时重传:发送端在发出数据包之后一个RTO没有收到ACK,就重传这个包,缺点是容易误判:对方可能收到ACK但是ACK丢了,或者ACK在途中但是时间超过一个RTO。核心就是计算好RTO时间,如果应用场景对于延迟比较敏感但是流量成本要求不高,可以把RTO设置小一点,比如在线操作网游,适合小带宽低延迟传输。定时重传对于大带宽消耗比较大,一般采用请求重传。
  • 请求重传:请求重传是接收端发送ACK时候携带自己丢包反馈,发送端根据ACK重传。关键是回送ACK时候标明哪些信息丢失了,因为UDP在网络传输中会抖动,接收端要评估网络的RTT方差,当发现丢包时候记录时间t1,如果t1+RTT方差<当前时刻,就认为丢包了。请求重传还依赖RTO,所以要不停评估这两个参数,整体比定时重传时延大,但是节约了带宽,比较适合视频、文件传输。
  • FEC选择重传:FEC(Forward Error Correction)是前向纠错技术,用XOR算法实现。发送方在发送报文的时候会对数据进行FEC分组,通过XOR得到若干个冗余包,一起发送给接收端,如果丢包了可以通过分组进行还原,就不用重传了。如果不能回复就请求原始数据包。FEC可以解决延时敏感并且可能随机丢包的环境,可以与上面两种方式进行搭配。
具体实现方式

RTT和RTO计算

RTT是网络环路延时,是通过发送数据包和接收到ACK计算的,可以通过类似于加权平均收敛计算,然后再计算RTT方差。计算RTO会涉及到报文重传,就是一个报文的重传周期,如果一个RTT+方差的时间没收到ACK,就可以再次重传,一般RTO = SRTT + SRTT方差,网络严重抖动的时候RTO会设置高一点,比如乘以1.2到2。

窗口和拥塞控制

还需要解决延时和重传带宽的问题,所以发送端可以设置一个拥塞控制窗口来避免高并发带宽过度占用问题。引入一个滑动窗口,有的业务场景RUDP需要发送端和接收端严格控制窗口,比如有序UDP就需要做好窗口排序和缓冲,无序的话一般不用做缓冲,只做位置滑动。每次收到数据接收方的窗口要滑动,滑动的速度受拥塞控制机制控制,拥塞控制可以通过丢包率后者网络时延实现。

拥塞算法

TCP有慢启动、拥塞避免、拥塞处理和快速恢复,都是为了决定发送窗口和速度设计的,根据丢包状况判断网络状态,确定发送窗口大小。TCP的实现是以成本换质量,缺点是很难高效利用也就是压榨网络带宽,很难保证大吞吐量和小时延。

  • BBR算法:基于发送端延迟和带宽评价拥塞的,可以保证在有一定丢包率的网络上充分利用带宽,然后还可以降低buffer时延。主要策略是周期性的根据ACK和NACK评估最小RTT和最大带宽,最大吞吐量等于 = 最大带宽/最小RTT。首先会进行初始化cwnd为8,开始慢启动,根据周期性ACK采样判断是否增大带宽,如果可以cwnd = cwnd * max_gain。如果超过周期丢包就会进行消耗状态,发出去但是还没有确认的数据大小>cwnd的话,继续保持消耗状态,发出去但是还没有确认数据<cwnd,进入带宽探测状态,这个状态下如果没发生丢包并非发出去但是还没确认的数据<1.25倍cwnd,将维持原来状态的cwnd进入慢启动,发生丢包cwnd = cwnd * 0.75,否则cwnd=cwnd*1.25。当10秒内的RTT<=min_rtt,就会进入RTT探测状态,这个状态收到ACK并且没有丢包,将用本次统计最小RTT来更换原本min_rtt,然后再次慢启动。

  • 通过周期性的计算cwnd,来完成拥塞控制,比较适合随机丢包且网络稳定的场景,如果网络极不稳定就容易预测不准,而且在公平问题上小RTT比大RTT更吃带宽。是使用成本换取质量和可用的方式。

  • webRTC算法:webRTC算法是基于丢包率和接收端延迟带宽进进行拥塞控制,并且保证尽力可靠交付,重传太多次会直接丢弃。当丢包率小于2%会加大带宽、在2到10之间会保持当前码率,丢包率大于10%会认为传输过载而减小带宽。缺点就是网络间歇性丢包的时候收敛比较慢,容易造成发送端流量失效。是以质量和成本换取时延。

  • 弱窗口拥塞控制:传输数据量就不大,保证时延比较小和可靠,采用固定大小如cwnd = 32来做控制,简单直接但是难以适应弱网环境。

传输路径

RUDP可以利用UDP特性在链路上做传输优化,主要分为多点串联和多点并联。

  • RTN:双方通过传递节点动态选路,中间的链路只是无状态的缓存,传递节点之间进行路由探测和选路,来保证高可用。

  • 多点并联:中间通过多节点并联来进行跳转。


http://www.niftyadmin.cn/n/5346937.html

相关文章

cartopy在地图中添加经纬线

文章目录 gridlines方法定义 gridlines gridlines可以根据坐标系&#xff0c;自动绘制网格线&#xff0c;这对于普通绘图来说显然不必单独拿出来说说&#xff0c;但在地图中&#xff0c;经纬线几乎是必不可少的&#xff0c;而随着投影方式的不同&#xff0c;经纬线未必与坐标框…

如何荒废你的2024?

这个演讲题目出人意料&#xff0c;当大家都在想着如何才能获得幸福、快乐、成功的时候&#xff0c;芒格却在跟我们讲“如何获得痛苦&#xff1f;” 为什么&#xff1f; 因为只有知道了自己不想过怎样的生活&#xff0c;才能想尽办法避免它&#xff1b;同样&#xff0c;也只有…

springboot 优雅使用函数式编程处理 websocket @OnMessage 消息

背景 现在大多业务功能使用 socket.io实现长连接&#xff0c;但是部分第三方设备对接 只支持基础的websocket。 spring中使用基础的websocket, OnMessage 收到消息&#xff0c;对消息的处理&#xff0c;if else 将会繁琐&#xff0c;难以维护。 本文仅介绍了如何使用enum枚举、…

第28章复数矩阵到微分,乘法以及除法

前面提到了点乘&#xff0c;那么这里就继续讲到微分&#xff0c;用的也是复数&#xff0c;微分空间也是张成出来的但是取的不是纯实数和纯虚数&#xff0c;而是半复数张成的空间&#xff0c;虽然在之前是用不到的&#xff0c;但不代表没有用&#xff0c;现在就提一下&#xff0…

C语言实现希尔排序算法(附带源代码)

希尔排序 希尔排序&#xff0c;也称递减增量排序算法&#xff0c;是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。 希尔排序是基于插入排序的以下两点性质而提出改进方法的&#xff1a; 插入排序在对几乎已经排好序的数据操作时&#xff0c;效率高&#xff0…

刘润-进化的力量2 一刷 笔记

安全感来自确定性&#xff0c;但机会藏在不确定性中 安全感来自确定性&#xff0c;但机会藏在不确定性中。 每一个弯道里&#xff0c;都有你超车的机会 意外、周期、趋势、规划 可是&#xff0c;为什么趋势一定是不可逆转的呢&#xff1f;因为&#xff0c;效率提高了 长期…

XGBoost系列7——XGBoost的性能优化策略

目录 写在开头1. XGBoost的并行计算原理1.1 特征并行1.2 数据并行1.3 参数调整优化并行性能1.4 多线程和分布式计算2. 大规模数据集的分布式训练2.1 分布式训练原理2.2 集群配置2.3 参数调整2.4 数据并行与模型并行2.5 优势与挑战3. 内存优化与缓存策略3.1 内存管理3.2 缓存策略…

docker 安装mindoc

一、拉取镜像 docker pull registry.cn-hangzhou.aliyuncs.com/mindoc-org/mindoc:v2.1 二&#xff1a;创建实例 使用时&#xff0c;要修改为自己的数据库信息 docker run -p 8181:8181 --name mindoc -e DB_ADAPTERmysql -e MYSQL_PORT_3306_TCP_ADDR127.0.0.1 -e MYSQL_PO…