火山引擎 RTC 全球化架构设计(火山引擎产品发布会)
off999 2025-03-23 22:47 49 浏览 0 评论
1. 为什么 RTC 要做全球化
RTC(Real Time Communication)是音视频基础设施,它已经融入了大家生活的方方面面:工作中,我们组织视频会议,即使团队成员身处异国,也能保证项目推进;休息时,我们打开抖音,看主播直播连麦;来一局游戏时,我们打开小队语音,大杀四方;学习时,我们相聚线上互动课堂,知识传播不再受距离的桎梏。RTC 拉近了大家的距离,丰富了大家的生活。
在这些场景里,我们最不能忍受的是什么?是延迟!想象一下,开会或者主播连麦时,一个人讲完话,其他人隔 10 秒才能做出反应,这几乎是完全不能接受的体验。
那么什么样的延迟才是好的体验呢?根据 ITU-T G.114 的建议:延时低于 400ms 的通话体验是可接受的,低于 200ms 是令人愉悦的。
ITU-T G.114
在没有全球化的情况下,RTC 需要在公共互联网上进行长距离、跨国的网络传输,有大量因素会影响到通话质量:
- 距离越长,中间经过的路由节点越多,整体故障概率越大(软硬件问题,带宽问题,DDoS 等)
- 跨运营商网络问题
- 跨国网络问题
- ......
以纽约到深圳的数据为例:单向延迟最差的时候超过 1s,日常有 20% 左右的丢包。通过在纽约和深圳的设备进行实验,能看到通话建立成功的概率只有 30%,音视频延迟、卡顿非常严重。
RTC 做全球化的目的就是:降低延时,提供愉悦的 RTC 体验 。
2. 全球化架构分解
在对 RTC 进行全球化架构设计之前,我们需要先了解下 RTC 的业务逻辑。RTC 的所有应用场景都可以简化成一次通话。我将通话的流程做了简化,它包含下面的步骤:
- 给信令服务器发送加入房间请求(同一个房间内的用户才能互相通话)
- 给信令服务器发送发布、订阅请求
- 信令服务器返回媒体服务器地址(信令服务器和媒体服务器对资源的要求不同,一般来说是两种不同的服务器)
- 用户和媒体服务器建连,开始发布、订阅音视频数据
这样一次通话就完成了。大家可以看到,通话过程被分为了两部分,信令交互和媒体交互,因此:RTC 全球化 = 信令全球化 + 媒体全球化。下面我们就分别介绍一下火山引擎 RTC 在媒体全球化上的实践和在信令全球化上的架构演进。
3. 媒体全球化
3.1 机房建设
火山引擎 RTC 在全球建设了大量边缘机房,覆盖 200+ 国家和地区。除自建机房外,全球还有 20+ 边缘云供应商。
3.2 就近接入
建设如此多的边缘机房,目的就是为了让用户能接入到离自己最近、最优质的边缘节点。
这里介绍一下就近接入的逻辑:
- 用户请求分配边缘节点。
- 中心机房的调度服务从请求中获取用户的真实 IP(脱敏)。
- 带着 IP,通过查询 IPIP 数据库,能够拿到用户的地理位置、ISP 等信息。
- 在存储边缘节点的数据库中,通过计算距离、是否同运营商等策略,选择最优的一系列节点返回给用户。
- 用户接入边缘节点。
就近接入的流程大致如上,得益于边缘节点的广泛覆盖,全球用户到火山引擎 RTC 边缘节点的单向平均延时仅为 70ms。
这里需要注意的是中心将会返回一系列节点,原因会在稳定性部分解释。就近接入优化了用户第一公里的质量,但在实际场景中,仅有就近接入一个策略是不够的。这里要先介绍一个概念:级联,假设两个用户通话,用户分别连接到 A、B 两台媒体服务器上,那么 A、B 服务器之间要互相拉流,服务器间拉流的操作就被称作级联。
假设这样一个场景,一个 4 人会议,User1 和 User2 发言,User3 和 User4 是听众,所有人都连接在不同的媒体服务器上,我们可以数一下,一共将产生 6 路级联流(假设每人只发 1 路音频,不开摄像头)。
级联流过多,会造成大量的带宽浪费,降低系统容量。为了解决这个问题,我们实现了一套边缘聚合的策略。
3.3 边缘聚合
顾名思义,关键在聚合。一个房间内的用户,在质量允许的范围内,会尽量分配同一个边缘节点,还是上面的场景,假设 User1 和 User2 在一个工区,User3 和 User4 在一个工区,那么最终会形成这样的推拉流结构:
级联流的数量从 6 个下降到了 2 个,极大降低了系统的压力。
就近接入与边缘聚合是两个互斥的策略,想要用好他们,关键就在于对不同场景下质量的把控,在两个策略当中找到平衡点,这是一个非常值得深入研究的话题,但限于篇幅,这里不再赘述。
3.4 实时传输网
如上面所举的例子,即使有边缘聚合,级联流量也是不可能完全从系统中消失的。两个人如果距离很远,在保证用户的接入网络质量的前提下,他们之间的通话必然会产生级联。
我们的边缘节点都是运行在公共互联网之上,而公共互联网是一个尽力而为( Best Effort) 的网络,特别是在长距离、跨国传输的场景下,质量是无法得到保证的。该如何保证级联的网络质量呢?
我们在尽力而为的公共互联网上,通过广泛覆盖的边缘节点进行转发,构建了一张 Overlay 网络,提供有 QoS 保障的全球网络传输服务。
实时传输网的主要责任有两个:
- 为两点之间提供最优质(延时、丢包,稳定性)的链路进行传输
- 在链路故障时,自动切换到可用链路
公网
实时传输网
上面是公网和实时传输网同一时刻的质量对比,可以很明显地看出,实时传输网的传输质量远高于公网(图片右上角有颜色的说明,绿色最优,黑色最差)。
3.5 稳定性
前面讲到,我们的边缘节点数量很多,覆盖很广,这也意味着,节点出问题的情况会很多,稳定性是我们不得不面对的一个问题。这里简单介绍我们的一些稳定性策略:
- 同一地区引入多家供应商,减少单点。
- 之前提到过,我们会给用户同时下发多个边缘节点地址,边缘可以择优连接,一旦通话过程中节点故障,可以快速切换。
- 针对故障节点的负反馈机制,如上图,当 SDK 发现 110.119.120.1 连不通,会进行负反馈上报,中心服务会将此节点拉黑。
4. 信令全球化
信令的全球化设计经过了 5 个版本的迭代,有的设计活到了现在,有的设计被更好的设计覆盖,接下来将介绍整个演进过程。
在信令全球化的设计中,要始终注意两点:
- 房间中的用户能互相感知(必须满足),一旦无法感知,相当于房间脑裂,无法感知对方,是失败的设计。
- 信令能被尽快处理(极致追求)。
4.1 V1.0: 单中心
初代版本我们在全球只有一个中心机房,所有的信令都通过动态加速回源到这个中心。国内的用户质量还能接受,海外的质量就比较糟糕,连不通也是常有的事情。单中心还有一个更大的问题,如果这个中心机房有故障,RTC 将无法容灾。
这一阶段信令的平均延时是:
- 国内 250ms。
- 海外 1s+。
因为体验和稳定性的原因,我们在这一阶段只停留了很短的时间,就马上进行了多中心的建设。
4.2 V2.0: 多中心+中心化房间
为了解决 V1.0 版本的容灾问题,我们在全球建设了多个中心机房,并在机房内进行了单元化部署。
多个机房意味着同一房间内的用户可以连到不同的机房,信令全球化开头提到了两个注意点,其中之一是要保证房间内的用户能够互相感知,这一版本我们采用了中心化房间的设计。
中心化房间就是:一个房间(包括房间、用户、流等)的信息只属于一个中心机房,为此我们引入了一个新的服务:region,由它来负责对房间属于哪个中心机房进行决策,region 要保证全球数据的一致性,否则房间会脑裂。
简单描述下中心化房间的信令处理流程:
- 用户将信令投递给离他最近的中心机房。
- 机房内的 Gateway 从信令消息中提取 AppID,RoomID 等信息,并请求 region 服务。
- region 进行房间归属决策(保证一致性),返回给 Gateway。
- Gateway 将信令投递给对应机房的信令服务,如果房间不属于本机房,就进行跨机房调用。
注意,只有第一条消息需要请求 region,后面的信令消息根据缓存的房间归属进行投递即可。此方案使就近处理信令成为了可能,比如一个业务用户主要在东南亚,用户连接在新加坡机房,那么我们可以在 region 中针对此业务进行一些配置,让房间决策尽量落在新加坡机房,用户的信令就能直接在本机房处理。
但是如果业务的用户全球都有分布,还是会有大量信令需要进行跨机房投递,延迟依然会比较高,本阶段的平均延时大概为:
- 房间属于本机房:300~500ms。
- 房间属于其他机房:400ms+(如果跨机房网络抖动,会很差)。
中心化房间还有一些其他问题:
- region 需要保证全球一致性,对服务的要求极高,容易成为稳定性和性能的瓶颈。
- 因为信令只属于一个机房,当这个机房故障,用户切换到其他机房时,会发现并没有相关的数据,用户需要重新进房、发布、订阅,这对于用户体验也是不够友好的。
4.3 V3.0: 分布式房间
分布式房间的架构可以很好地解决中心化房间的问题。分布式房间一直是我们规划中的架构,但是因为复杂度的问题,并没有立刻投入开发。它的改造要比中心化房间复杂很多,因此先实现了的中心化房间来提升体验。现在,是时候去攀登这座山峰了。
分布式房间是指:一个房间内的信息在多个中心机房内都有完整的数据。因此,我们需要对数据进行全球化同步,此外,中心化房间中的 Gateway 和 region 服务都不再需要了。
整个改造对于业务逻辑调整很大,延时上也取得了很大的进步,这一阶段的信令平均延时在 300ms 左右。受限于篇幅,这里只介绍分布式房间架构中两个比较关键的技术实现。
4.3.1 同步模式
在进行数据同步时会发现,我们的数据量太大了,同步占用的带宽、CPU、存储占用都很多。但是对于一些接入方来说,这些数据同步并没有意义,不会被使用到。
为此我们设计了两种同步模式:全同步与半同步
全同步半同步定义实时同步房间、用户、流信息实时同步房间信息,有当房间碰撞时,开启房间内用户、流的同步适用业务用户广泛分布于世界各地,如直播连麦、跨国公司视频会议大量用户集中在单个地区,如教育
解释一下半同步中碰撞的含义,如果同一房间的用户在不同机房加入房间,在互相同步房间数据时会发现,另一个机房已经有了这个房间,这就叫做碰撞。房间数据相较于用户、流等数据量级要小很多,给合适的业务开启半同步,极大减轻了同步的压力。
同步模式自适应切换
全同步与半同步在 RTC 中会自适应切换,我们的离线分析工具会定时分析各个业务方房间的碰撞情况,如果一段时间内碰撞的次数较多,就切到全同步,提升用户体验;如果碰撞次数减少到一定阈值,就降级到半同步。
4.3.2 可靠传输通道
为了保证跨机房同步质量,我们在这几个中心机房之间架设了专线,但是从实际使用看,专线的稳定性并不高,海缆、陆缆都有经常性的故障,并且这种故障修复非常困难,导致故障时间很长。
我们为此开发了一个可靠传输通道,它有如下特点:
- 增加公网 relay 节点,摆脱对专线的强依赖。
- 多径传输,单条线路故障对传输无影响。
- 消息保序(RTC 对信令消息的顺序有极高要求)。
平均一年我们会遇到几十次专线故障,火山引擎 RTC 基本每次都能平安度过。
4.4 V4.0: 统一接入
在V1.0 版本的架构设计中,当时我们使用了动态加速这样一个服务,动态加速的原理是用户的请求直接发送到动态加速供应商的边缘节点,这些边缘节点进行内部转发,最后回源到业务的服务器。既然 RTC 有了覆盖这么广泛的边缘节点,为什么不能用来加速信令消息呢?
当然可以!我们目前已经有了一个和边缘节点通信的媒体通道,让信令通道和媒体通道统一即可,也就是我们现在说的统一接入,信令消息经由边缘节点转发给中心机房,平均延迟优化到了 230ms(优化了 70ms 左右)。
4.5 V5.0: 边缘下沉
“百尺竿头,更进一步”
我们模仿了一套动态加速的实现,效果还不错。但是让我们静下心来想一想,以前“我”是使用动态加速的服务,现在“我”就是动态加速本身呀,这些边缘都是我自己的边缘,只用来做转发是不是太浪费了,为什么不能直接处理信令呢?如果能实现,那么大量请求将在边缘直接返回,延迟将大大优化。
逻辑下沉
这一阶段我们将进房、发布、订阅等逻辑下沉到了到了边缘,加强了 RTC 的边缘计算能力,信令的平均延迟优化到了 100ms。
需要注意的是,虽然逻辑下沉到了边缘,这并不代表中心机房就没有用了,在处理完请求后,会将消息异步发送给中心机房,中心机房具有全局视野,会对信令进行进一步的处理,比如通知房间内的其他用户等。
4.6 稳定性
最后还是讲一下稳定性的话题,上面提到,我们现在在全球是多中心机房的架构,中心机房虽然比边缘机房稳定一些,但也会有故障的困扰,中心机房的故障分为两类:接入故障和服务故障。
4.6.1 接入故障
接入故障分为两类:
- 接入网络故障,为了提升体验,一般中心机房都是多线 BGP 接入,单线故障时有发生。
- 解决思路也是多径传输,摆脱对单条线路的依赖。
- 接入网关故障,比如 nginx 故障,此时所有路径都会失败。
- 上面提过我们的多机房建设,边缘机房会对多机房进行实时探测,故障时自动切换。
4.6.2 服务故障
服务故障时更常见的一种故障,比如代码的 bug 被触发,强依赖的下游故障,依赖的基础设施(mysql/redis/mq/...)故障等。
我们开发了一套自动运维系统:AIOps,它会实时监控机房的健康度,在健康度下降时自动切换到灾备机房。
4.7 回顾
信令的全球化从初版的“单中心”演进到了当前的“多中心+分布式房间+统一接入+边缘下沉”的架构,在信令的处理延时上取得了显著的进步。
5. 总结
火山引擎 RTC 的全球化架构极大降低了信令和流媒体延时,端到端延时 200ms、400ms 达标率都达到了 99.0% 以上,可以说,在绝大多数的情况下,火山引擎 RTC 都能提供愉悦的实时音视频体验。
另外,得益于我们在稳定性上的大力投入,即使面对边缘节点故障、机房故障、专线故障等突发事件时,火山引擎 RTC 也能够始终提供高质量、高可用的服务。
相关推荐
- 使用 python-fire 快速构建 CLI_如何搭建python项目架构
-
命令行应用程序是开发人员最好的朋友。想快速完成某事?只需敲击几下键盘,您就已经拥有了想要的东西。Python是许多开发人员在需要快速组合某些东西时选择的第一语言。但是我们拼凑起来的东西在大多数时候并...
- Python 闭包:从底层逻辑到实战避坑,附安全防护指南
-
一、闭包到底是什么?你可以把闭包理解成一个"带记忆的函数"。它诞生时会悄悄记下自己周围的变量,哪怕跑到别的地方执行,这些"记忆"也不会丢失。就像有人出门时总会带上...
- 使用Python实现九九乘法表的打印_用python打印一个九九乘法表
-
任务要求九九乘法表的结构如下:1×1=11×2=22×2=41×3=32×3=63×3=9...1×9=92×9=18...9×9=81使用Python编写程序,按照上述格式打印出完整的九...
- 吊打面试官(四)--Java语法基础运算符一文全掌握
-
简介本文介绍了Java运算符相关知识,包含运算规则,运算符使用经验,特殊运算符注意事项等,全文5400字。熟悉了这些内容,在运算符这块就可以吊打面试官了。Java运算符的规则与特性1.贪心规则(Ma...
- Python三目运算基础与进阶_python三目运算符判断三个变量
-
#头条创作挑战赛#Python中你学会了三步运算,你将会省去很多无用的代码,我接下来由基础到进阶的方式讲解Python三目运算基础在Python中,三目运算符也称为条件表达式。它可以通过一行代码实现条...
- Python 中 必须掌握的 20 个核心函数——set()详解
-
set()是Python中用于创建集合的核心函数,集合是一种无序、不重复元素的容器,非常适合用于成员检测、去重和数学集合运算。一、set()的基本用法1.1创建空集合#创建空集合empty_se...
- 15个让Python编码效率翻倍的实用技巧
-
在软件开发领域,代码质量往往比代码数量更重要。本文整理的15个Python编码技巧,源自开发者在真实项目中验证过的工作方法,能够帮助您用更简洁的代码实现更清晰的逻辑。这些技巧覆盖基础语法优化到高级特性...
- 《Python从小白到入门》自学课程目录汇总(和猫妹学Python)
-
小朋友们好,大朋友们好!不知不觉,这套猫妹自学Python基础课程已经结束了,猫妹体会到了水滴石穿的力量。水一直向下滴,时间长了能把石头滴穿。只要坚持不懈,细微之力也能做出很难办的事。就比如咱们的学习...
- 8÷2(2+2) 等于1还是16?国外网友为这道小学数学题吵疯了……
-
近日,国外网友因为一道小学数学题在推特上争得热火朝天。事情的起因是一个推特网友@pjmdoll发布了一条推文,让他的关注者解答一道数学题:Viralmathequationshavebeen...
- Python学不会来打我(21)python表达式知识点汇总
-
在Python中,表达式是由变量、运算符、函数调用等组合而成的语句,用于产生值或执行特定操作。以下是对Python中常见表达式的详细讲解:1.1算术表达式涉及数学运算的表达式。例如:a=5b...
- Python运算符:数学助手,轻松拿咧
-
Python中的运算符就像是生活中的数学助手,帮助我们快速准确地完成这些计算。比如购物时计算总价、做家务时分配任务等。这篇文章就来详细聊聊Python中的各种运算符,并通过实际代码示例帮助你更好地理解...
- Python学不会来打我(17)逻辑运算符的使用方法与使用场景
-
在Python编程中,逻辑运算符(LogicalOperators)是用于组合多个条件表达式的关键工具。它们可以将多个布尔表达式连接起来,形成更复杂的判断逻辑,并返回一个布尔值(True或Fa...
- Python编程基础:运算符的优先级_python中的运算符优先级问题
-
多个运算符同时出现在一个表达式中时,先执行哪个,后执行哪个,这就涉及运算符的优先级。如数学表达式,有+、-、×、÷、()等,优先级顺序是()、×、÷、+、-,如5+(5-3)×4÷2,先计算(5-3)...
- Python运算符与表达式_python中运算符&的功能
-
一、运算符分类总览1.Python运算符全景图2.运算符优先级表表1.3.1Python运算符优先级(从高到低)优先级运算符描述结合性1**指数右→左2~+-位非/一元加减右→左3*//...
- Python操作Excel:从基础到高级的深度实践
-
Python凭借其丰富的库生态系统,已成为自动化处理Excel数据的强大工具。本文将深入探讨五个关键领域,通过实际代码示例展示如何利用Python进行高效的Excel操作,涵盖数据处理、格式控制、可视...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 使用 python-fire 快速构建 CLI_如何搭建python项目架构
- Python 闭包:从底层逻辑到实战避坑,附安全防护指南
- 使用Python实现九九乘法表的打印_用python打印一个九九乘法表
- 吊打面试官(四)--Java语法基础运算符一文全掌握
- Python三目运算基础与进阶_python三目运算符判断三个变量
- Python 中 必须掌握的 20 个核心函数——set()详解
- 15个让Python编码效率翻倍的实用技巧
- 《Python从小白到入门》自学课程目录汇总(和猫妹学Python)
- 8÷2(2+2) 等于1还是16?国外网友为这道小学数学题吵疯了……
- Python学不会来打我(21)python表达式知识点汇总
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)