华为云 SparkRTC 面向低时延、大通量传输业务的技术探索
本文分享自华为云社区《华为云SparkRTC面向低时延、大通量传输业务的技术探索》,作者:吴治宗。
编者按:网络和移动设备高速发展的今天,人们开始思考如何用更短的时间下载更大的文件,追求更快的速度。当下在稳定的基础上有什么方法可以提升速度呢?2022 LiveVideoStackCon 音视频技术大会上海站邀请到了华为云的吴治宗老师,为我们分享华为云 SparkRTC 面向低时延、大通量传输业务的技术探索。
下午好,我今天演讲的课题叫“华为云 SparkRTC 面向低时延、大通量传输业务的技术探索”。
首先做个自我介绍,我来自于华为云媒体服务商品部,目前负责 RTC 产品和实时媒体网络架设,曾经在 IPTV、CDN 分发领域有多年开发经历,在媒体生产、存储、缓存、分类以及实时传输领域有一定的经验。
下面我就正式开始今天的演讲。
今天的演讲主要分为三个部分:第一部分描述了未来互联网媒体传输业务面临的问题,第二部分是当前华为 SparkRTC 的多业务传输架构,第三部分是如何用现有的架构去解决上面分析的问题。
1、未来互联网媒体传输业务与面临的问题
首先看第一部分,未来互联网媒体的演进方向。从现在来看,我们互联网媒体经过多年的发展,在互动文娱,企业营销,包括远程办公和在线教育等等一些领域已经得到长足的进步。但是随着 2021-2022 年元宇宙的技术和理念的兴起,很多公司都在面向未来虚拟世界与现实世界无缝融合的方向发展。我们也可以看到一些让人比较惊艳的应用,我个人比较喜欢华为基于一个虚拟空间的千万人在线的巡回演唱会,让我非常惊艳。
业界主要从三个入口做探索:第一个入口,基于虚拟社交;第二个是基于办公的,也就是虚拟工作空间的入口;第三部分是虚拟娱乐空间的入口。
举一个典型的案例,华为云的云桌面的高清流畅办公体验。简单来说,云桌面是把线下的主机搬到云上使用,随时随地可以用的显示设备以及件数设备,能跟云上的服务器产生联系,这样就能解决传统的数据拷贝的问题、数据安全的问题、多人协同办公的问题等等。但这样就面临一个非常现实的问题,即桌面中有一个场景叫设计师桌面。设计师桌面的要求与普通办公的桌面要求是完全不一样的,因为他们的眼睛、耳朵跟我们的不一样,所以会有这几个要求:第一个要求,设计师要求色彩无损,即不要 YUV420,要 YUV444,同时要求色彩还原,专业 10bit 色深,降低噪点,柔滑细腻。
同时设计师的办公环境一般来说是双屏三屏,2K/4K 的屏。同时,一些原画设计、游戏设计会要求具有比较稳定的帧率,比如需要 1080P 60fps/4K 60fps 的要求。最后还有操控体验的要求,鼠标、键盘的设键上行一直到云端渲染、采集编码的下行,端到端要求 100ms,至于原画和建模的环节,希望是 50ms,这对于底层华为云 RTC 实时网络带来一个大通量的 dis 键的技术诉求。
刚才是一个场景,下面我们看一下未来互联网面临的一个典型问题。这里有五类问题,其中有一部分不管是现在还是未来都会有,网络传输基于不稳定互联网、基础设施不可靠、长距传输时延大。下面两点是目前遇到的问题:面向大通量的时候,弱网算法性能不够,第二个是带宽探测不适用于大通量。接下来我会先讲一下华为云 SparkRTC 的技术架构,然后再描述基于这个架构,为了解决这个问题,我们从三个方面进行的技术探索。
2、面向未来的多业务传输架构
华为云 SparkRTC 传输网络的架构其实是一个非常典型的 RTC 架构。
整个 RTC 是分为两大部分,第一大部分是信令接收部分,第二大部分是媒体传输部分。信令接收部分又分为两块,第一块是部署在数据中心,包含 RTC 业务的,也就是用户接入服务,包括房间管理、用户管理及流调度等等。第二块我们做了一个信令加速的服务,放在云的边缘,去做信令的低时延和可靠的传输。第二大部分是媒体转发。媒体转发的服务器部署是基于用户的分布来做就近部署的,也就是说它是纯分布式的。
同时媒体转发服务之间是通过全球互联的 RTN 网络来做点对点的互联。
总的来说,SparkRTC 分为两大部分,信令和媒体传输。这两大部分都会跟终端产生交互。
对于终端来说,SparkRTC 的传输能力是分层开放的。
我们最开始做 RTC 时,它的音视频引擎和传输是 all in one 的,就在一个 SDK 里面。这样的话,如果要使用,那么从传输到音视频的采集编码渲染都是一体的,all in one 的技术设定。我们对外开放包含 RTC 的业务 API,里面做的是业务相关的,房间管理、流订阅、音视频引擎等等。
后来我们发现这种方式的适用场景并不能够满足很多业务诉求,比如说云渲染桌面的诉求。它并不需要做一些音视频引擎,只需要好的传输,能够支持一定的弱网。因此我们就把第一部分的 SDK 做了一部分拆解,把音视频引擎拿出去,单独做了一个能够感知媒体的信源信道联动的,能够支持媒体传输的一套 API,它具备一定的音视频感知和一定弱网对抗能力。
但是这样做了之后还是不行,有的客户不想要传输和音视频的能力,只想要接入和选路。我们又把最底层网络层以及在上面分装的 RTN 层开放出去了。这一层就是通用数据的传输,只是保证就近接入以及在云端的最优选路。
第二部分是 APP 不可见的,云端的互联网传输技术。这个技术也是业界通用技术,就是基于 RTN 技术来做低顺延的网络。
我们会做一个基于全球分布的加速节点。这里的加速节点,特别说明一下,是动态分组管理的,即根据长期网络探测结果进行一个分组。然后全球的控制服务会告知加速节点到底应该向哪些加速节点去做对应的探测,然后根据探测结果去做跨组以及组内的路径规划。同时基于路径规划我们也提供了多路径传输的能力,这样就在 OverLay 层上保证低时延和高可靠的路径传输。
接下来我们看基础架构怎么解决问题。
这里基本上分为三大部分,第一部分是基础设施和应用软件,应用软件也包括终端设施和互联网,来从这几个方面各自去提升自己的竞争力。
首先,基础设施要能够提供稳定、低时延的传输通道;基于网络技术栈能够提升和支持弱网的竞争力;互联网外网络能够提升选路竞争力,主要是做可靠、可低时延。最后,我们希望基于 UTP 的扩展协议,通过端到端全链路的方式提升网络测量的能力,针对测量数据去做端到端的正循环。
下面,主要从这三个方面来阐述目前所做的一些技术探索。
3、重构基础骨干网络
第一部分是基础设施,也就是重构骨干网络。我们先看一张图,这是目前华为云骨干网络的优化效果的部分截图。
这里有两张图,第一张图是基于华为骨干网的,产品叫云连接,CC 互连。它是通过专线的方式去做两地之间的通讯。可以看到这个例子,上海到南非要 182ms,但如果要走互联网的话,因为互联网的路由设备和路径是不可控的,需要 354ms,同时会有一定的概率丢包。
这里也列举了一些跨国的场景,可以看到基于骨干网的传输,基于一个优化的基础设施传输相对于互联网直连的方式,它的时延和可靠性可以得到大幅度的提升。
刚才是网络质量的稳定问题,第二点是基础设施覆盖广不广。华为云把骨干网分成两层,第一层是 DC,也就是数据中心。目前是全球 3+1 的数据中心,即中国、新加坡、德国和俄罗斯的莫斯科。这里做的是全球双环线测互连,保证最高的可靠性。同时周边还有一些骨干的节点,这些骨干节点是基于全球流量的高低,包括 GDP,人均消费流量等去做对应的节点选择。这样的话也可以保证一些高可靠、高优先级以及高价值的客户能够进入到骨干网络,获得最优的网络体验。
骨干网面向企业用户提供了一个云连接服务,叫“高效、优质、稳定的云上连接服务”。所有的技术逻辑都是在不同的 VPC 之间提供了一个稳定可靠的传输通道。
目前,通过一个套餐包,就可以实现全球的 VPC 之间非常简单灵活、全球互联的场景,这样就可以快速帮助用户拥有一个更优质的骨干网络。
第二部分主要讲了面向于外网络的,也就是 RTN 部分以及应用部分,即云上的应用部分,做了哪些低时延的探索。
4、传输网络低时延技术探索
外网络传输竞争力主要分为三类。
第一是稳定低时延。第二是高可靠的实时网络。第三,网络是可管理可测量的。我们从这三方面做了竞争力的探索。
第一部分是 RTN 网络。RTN 网络实际上就是 OverLay 的技术。如果通过纯粹的经过一个网络设备,即 underlay 的一个 ISP 的基础设施去做互连的时候,多多少少都会出现网络的拥塞、丢包、抖动等等这些现象。这些现象对于 underlay 的设备来说实际上是不感知的,因为它只关心能否发过去,并不关心服务的质量。
对于实时业务来说,如果出现这种场景,实时业务就没法实施了。所以也需要有一个基于 underlay 的基础设施的 OverLay 的支持性存根技术。加速节点可以主动发现在传输节点和传输节点间的丢包,这样的话先于业务发现丢包,主动缓存重传的机制可以保证传输的可靠性,就可以做到往无损的方向演进。
第二部分我们做了多路径的设计,从 S 到 D,可以允许用户定义 N 个副本。这 N 个副本可以做备份的方式,也可以做双录的方式。如果用备份的方式可以做到高可靠,如果是双录分发的方式,就可以做到基于一个或者几个较低通量的链路去传送较高通量的音视频。
第二个是多 QoS 网络混合调度的问题。华为云的网实际上是分为几个部分。一个是精品的高架路,即刚才显示的四大 DC。第二个是互联网专线,即通过租用全球运营商的光纤或者专线去做 POP 节点之间的优质传输。第三部分是应用于公共互联网。这三张网的可靠性的 SRV 都是不一样的。
以北美到中国的一个节点为例,如果全走公共互联网,需要 220ms。如果走专线,可能要 110ms。为什么要 RTN 呢?是因为不管走互联网也好还是走专线也好,只要路径是通的,路径永远都是固定的。在路径优筛的时候,我们希望能够快速地以秒结的方式切换到另一条线路,所以引进了 RTN 的概念。以中间可以有可选路径的方式,这样的话就可以做到低时延、高可靠的技术目的。
讲完了 RTN,现在讲一讲 RTN 的应用。
我们在 RTN 低时延方面做了一些技术探索。RTN 的服务模式都有两个部分,信令加传输。第一个请求是信令,信令接信之后做媒体的协商,把通道协商出来。这样的话,就会带来一个问题,传统的 RTC 接入是 WebSocket,传输的协议是 TCP,同时要保证安全方面的要求,做一些 TRS。
这也带来了一个问题,首先要做一个 TCP 的三次握手,然后再做一个 TRS 的四次握手,也就是说,一个信令的交互需要做七次握手。
此外,还会面临另外一个问题,终端和信令服务器相邻比较远。因为此时还没有做分布式的信令服务器,还是在中心部署。
举一个极端的例子,一个墨西哥的用户加入房间,那可能需要去新加坡的数据中心加入房间。这样每次的请求,每个 RTT 都是一个最长距离,会带来接触时延非常大的现象。针对这个问题,我们做了两个探索。第一个,就是把 WebSocket 底层的 TCP 传输的方式变更为 QUIC,当然 QUIC 只能应用于 Native 端,Web 端还是只能使用 TCP。
同时也会保留 TCP 的备用链路,一旦 QUIC 打不通时(QUIC 并不是所有场景都适用),也会回落到 TCP 的模式。这样握手次数就从七次变成一次了。
第二,可以看到前面架构图里有一个叫信令加速的服务。这个服务把证书下载到边缘节点。这样如果还是 TCP 接受方式,所有证书的交互就是就近交互,路径就缩短了。
同时信令加速服务是基于华为云的优质专线链路跟远端的信令服务器是已经预建立好的长链。这样就可以以端到端的方式,降低信令接入的时延。按照实测,可以大概下降 65%左右。
第二块是应用的传输时延。
这张图是一个典型的 SFU,RTC 的传输路径。它有两个端,一个 SDK 的操纵端,一个 SDK 的接收端。我们做了一个最简单的测试,接收端接到一个编码器完整的视频帧,在 SDK 就会对帧按照 UTP 的 MTU 做一个 RTP 打包,打包完之后再通过网络传输到就近的 SFU 里边。之前的方式做得比较粗暴,因为要面对多方,一个 SFU 下面要对多个 SDK,并且 SDK 的网络条件有可能是不一样的,有的网络很好,就可以把所有的帧都发过去,但有的网络条件不好,就要在服务器把非关键帧丢掉,只发关键帧就可以了。所以我们在服务器做了一个组帧的操作,但是组帧又带来一个问题,时延。
组帧有两种方式,一种是时延触发的,一种是定时判断的。如果按定时判断来做的话,组一帧至少要消耗一个探测周期或者两个探测周期才能识别一个完整帧,这样就带来一个云端的组帧时延。这种方式确实能够满足多方的分段传输,能够适应弱网的诉求,但是时延无法满足要求。所以针对这种方式,我们做了一些变化:在发送端 RTP 打包的地方做一些扩展,加一些帧的特征信息。这样的话,SFU 不管是什么模式,拿到数据后先进行逐包转发,当然有留空。不管是在帧转发还是包转发都会有对应的留空。我把组帧的逻辑去掉了,这个时候如果一部分端有弱网怎么办,没关系,因为扩展头里加了帧的信息,可以按照帧的信息把一组数据全都丢掉。这样可以减少 SFU 的组帧时延,同时线程调度、等待等时延也都可以去掉了。
按照实测,如果两个 SDK 都接在一个 SFU 上,大概能够节省 3-5ms 的时延。如果是通过 SFU 级连方式,最高大概能省 10ms 的时间。这样又离 100ms 更近了一些。
最后,对于端到端的度量我们也做了一些探索。
现在传统的探测手段都是每个接收端、SFU 都把自己的数据分别报到大数据去,大数据再根据每个方式做关联。这样效率其实并不高,而且经常出现丢数据或者数据不准、对不齐等现象。
针对这种问题,我们提出了一种随路测量的方式:根据配置或者设置,由发送端发送一个单独的 RTP 的探测包文,这个包文是只含这个节点探测到的一些网络 qs 数据以及业务的 qs 数据。每经过下一个节点,这个节点都会把自己的数据累加到这个 RTP 包文里。
这样的话,端到端所有的链路都是有最后一跳,有一个基于某一条流的完整的测量包。这样分析平台会非常容易感知到端到端的链路情况,而且这种方式,如果设备支持,那么就往里面加,如果不支持就不往里面加,包括 WIFI、交换机、路由器都可以用这种方式做,所以是完全松耦合的。数据后台也是根据里面的数据判断端到端的链路是什么样的。
最后再讲一下接入弱网自适应的技术探索。
5、接入弱网自适应技术探索
传输这一块,如果不含调度和编解码,基本上传输中涉及弱网的就这些技术:FEC 的技术、Jitter Buffer 的技术、包括一些重传的技术。
这里面我们会对每一个原子技术进行剖析,找到它的薄弱点,进行对应的性能或者能力上的提升。同时也会从系统工程的角度,通过合理的组合,参数配置来确定在什么场景下的效果是最好的。
下面看一下,面向云桌面目前要支持 32M 传输的情况,我们也做了网损的判断。
上面的图片是基于 TCC 改的算法,可以看到,一开始不限速,限速后恢复,再限速,再恢复,可以看到网络的跟随性。现在选用的是 BBR 的算法,并且做了一些对应的修改。它的算法支持更高的编码码率和稳定的传输帧率,最终用户的清晰度会更高,帧率也会更稳定。
下面我们来分解里面运用的算法。
先说第一部分,FEC。FEC 在音视频传输领域一般用基于多项式的 RS 编码,在码率比较小、数据曝光不多,或者说冗余不高时表现非常好,而且也逼近数学上可以恢复的一个极限了。但是到大码率时它就不行了。
按照实测,100M 的场景下,用传统的 RS 编码,编译码的时间都快超过 20ms 了,这在实时传输里没法接受的,所以必须寻求更高效的编译码的方式。
我们选用的方式叫 Sec-Pro,它实际上是一个基于快速复列变换的 RS 的编码方式。这个编码方式的数学原理叫 FFTRS,在基于伯努利丢包模型测试的情况下,首先做的测试是编译码的时长,在大码率的视频场景下,编译码的时长能不能小于 5ms(实际测试时,编译码的时长基本上是小于 2ms)。而且随着冗余率的升高,编译码的时长并没有升高,这个大家可以实测的。
第二个是新的编码方式在丢包的场景下恢复的能力是否能够满足实时的要求。因为如果只是时延满足要求,但恢复能力不能满足要求,那么也没有用。所以我们针对恢复能力也做了一个测试,即针对典型的网络丢包场景下测试固定冗余的场景恢复能力。我们更改了丢包模块的参数,使丢包率在 0-10%的范围内变化,同时调整冗余率在 1.6%-33.3%范围内变化,其他变量为默认值。
可以看到,随着丢包率的上升,解码的成功率不断下降。从这个图里也可以看到大概有 6.7%冗余率。在丢包率 4%的场景下,基本上可以达到 95%的恢复率。这样的话,根据火山引擎已经公布的网民数据,丢包 5%以下基本已经占 95%,也可以往上,但是根据普适性,我们认为 6.7%的冗余率就可以满足 4%随机丢包。这个丢包是随机丢包,但实际上在现网是连续丢包,所以采用 LVC 加 ARQ 的组合方式,单纯的一个方式可能没法解决丢包问题。
第二类是 Jitter Buffer。
Jitter Buffer 没有算法的优化,主要是工程的优化,即就是数据结构以及 LVC 配合方式的优化。传统 Jitter Buffer 主要有两个,一个是基于 Packet 的,包的链表,一个是帧的链表。
面向包端链表,我们做了一个分队列的操作。这样在大通量的场景下,链表非常长的场景下,查询效率会有比较大的提升。同时,我们也把 Jitter Buffer 里 FEC 相关的部分独立成另外一个线层,这样就不会阻塞 Jitter Buffer 的处理。最终增益的效果可以看对应测试的结果:在无损 100M、无损 200M 和 5%丢包纯 ARQ 的场景下,相对于原来的时延,都会有 85%以上的增益,也就是 1ms。
第三部分是拥塞算法。
拥塞算法的一个根本是带宽评估。现在所用的带宽评估算法基本上都是以探测为主的算法,也就是发送端通过 padding 或者某种方式一点点发送数据,然后把管道撑满,去得到真正可用的带宽。
我们做了两个尝试。第一个尝试还是基于传统的探测方式,但是传统探测方式存在一个问题,就是不管是在加性增还是乘性增期间,它的 step 都非常小。也就是说,如果从 2M 探到 20M,50M,要花上好几分钟才能探到最高的带宽。但是对于实时业务来说,我们希望带宽利用率尽可能地高。
所以面向大通量的应用场景,在乘性增期间用指数上升型的方式做上探的。指数也并不是按平方的方式,逐渐减少的。RTT 其实并不太合适,因为 UTP 的探测是基于端侧的定期的 feedback 来给到,但是一般情况下大家都喜欢用 RTT,所以我就用 RTT 方式来描述。我们希望用 5 个 RTT 的时间,用 5 个 feedback 的时间能够探测到比较高的可用带宽。但这种方式还是有问题,因为这种探测的方式,无论有多少个 RTT,它永远是滞后的。也就是说,当前的数据,实际上计算的是过去时间的网络情况,还是不准确,而且这种方式的网络抖动很大。那么我们又想能不能用预测的方式。
预测的方式业界一般有两类数学模型,一类是基于统计模型,一类是基于 AI 的学习的模式。这种学习的模式,由于开发周期、泛化和鲁棒性的问题,所以我们没有选用基于 AI 的方式进行学习。目前选用的是基于统计模型的方式。我们会统计历史的发送带宽、时延和丢包的关系,按照滑动窗口的方式计算,再更新当前时间片的发送速率。这样虽然还是不准,但是在其他的网络处理情况下,在带宽波动期间网络通量上升了 22.3%。这个对于我们来说,不需要学习,只需要统计。定一个目标函数,根据目标函数判断什么情况下用什么样的运算速率。同时,根据历史数据,带宽、时延、丢包等等这些数据,得到一个网络模型,根据这个模型去匹配目标函数,虽然不准,但是现在够用。
我们也可以看到,用快速带宽感知的测试结果。使用 pantheon 作设置平台,设置 RTT 为 50ms,带宽为 30Mbps、8Mbps 分别做 15s 交替变幻的方波,大概测 90s。在做探测时,注意,这个探测没包含前面的指数探测,可以明显看到,原来探测时,在一段时间内它是拥塞的,delay 非常长,基本是一个方波的时长。但是用预测的方式,实际上就是在网络带宽变更的时间点会产生非常短时间的 delay,在剩余时间很快就恢复到正常的带宽了。
刚才讲的这些东西并不是说一套算法能够适用所有的场景,这是不可能的。所以我们也做了拥塞控制的算法集,去做迭代式的演进。
目前 SDK 这边做的非常简单的算法的插件框架,主要有三个部分:第一部分是基础框架,实际上包含两块,一块是基础库,算法的基类,控制类,以及配置基类和注册表。第二块是数据采集和数据上报,上面是算法仓,这个位置的算法仓并不是即插即用的。我们并不希望 SDK 在使用某一个算法期间实时更改算法,我们希望能够云端 push 算法。先在算法仓里放着,等到 SDK 再次拉起时再选用新的算法,这样可以避免做算法的热切换,从而有一个相对可控的方式。最后是接口层,主要是做算法和参数的配置。同时云端会根据 SDK 使用算法期间采用的一些和体验相关的数据做数据存储、清洗和分析,然后根据算法仓和参数部分往云端 push 新的算法,或者说新的算法参数。这样就形成了一个相对稳定的 SDK 版本,因为 SDK 可变部分我们放在了云端。这是一个简单的框架。
最后再看算法测试环境和实验评价方法。
首先在实验室我们做了一个可控的网络环境,可以额外增加时延抖动和丢包,以及做带宽限制的处理,包括其他的网络处理。同时在发送端和接收端有多个版本的 SDK,每个版本都会自动化采集一些算法指标,发送指标,网络指标以及接收指标。每个指标都有对应的数据。最后根据数据的分析结果,抽象提炼弱网感知能力、带宽预测能力和发送码率控制能力。
在这里所讲的所有的逻辑都尽量避免 SDK 的变更。我们希望把控制部分放在云端。因为做 TO B 服务,不能限制 SDK,不可能跟着版本升级,所以我们希望在云端进行操作。同时,通过这样的循环方式,我们在能够提取到业务与网络的情况下,可以得到应该是用什么样的算法参数,形成一个正循环。上面从基础设施,接弱网和外网传输介绍了我们做低时延大通量的成果。
6、总结与回顾
最后做一下总结,如果想做好大通量低时延的网络,我们希望有优质骨干网络、高性能 OverLay 传输机制,云端具有信令加速的能力、不引入额外时延的能力以及松耦合和随路网络测量的机制。对于接弱网这一点,我们希望有高性能的 FEC 和 Jitter Buffer 算法,高灵敏度带宽探测和预测机制,以及支持算法在线迭代的架构。
版权声明: 本文为 InfoQ 作者【华为云开发者联盟】的原创文章。
原文链接:【http://xie.infoq.cn/article/3da6a20df85b2ba14ab2b79d2】。文章转载请联系作者。
评论