移动视频直播经过 2017 年的井喷期,已经进入下半场,大家的关注点已经从如何构建完善的直播平台的粗放增长阶段,转入精细化运营阶段。如何在巨大的流量、复杂的应用场景、复杂的网络条件下,持续优化用户体验,是业界十分关注的话题。
2020年3月25日,罗永浩正式宣布抖音成为其独家直播带货平台,2020年4月1日,罗永浩正式开启了自己在抖音的带货生涯。
罗老师开播到8点前,短短数十分钟冲上音浪榜第一名。
八点之后一个小时内直冲2000万+音浪,稳定直播人数220万+。
那么,我们是如何在庞大的用户基数下保证直播的流畅度呢?我将从四个方面进行解析。
抖音直播有四个显著的特点,这些特点给抖音带来了机遇,也让我们面临着巨大的挑战:
针对线上纷繁复杂的直播体验问题,抖音视频团队在实践过程中总结出了一套数据驱动的优化方法论,归纳一下有三点:
这套方法论的基础是数据,那么,抖音直播到底用到哪些数据,怎么判断用户的播放体验是否 OK 呢?下面先介绍一下抖音的直播系统端到端的处理流程:视音频信号实时采集,经过预处理和音视频编码,封装发送到 CDN 源站,播放端从 CDN 边缘拉到数据,然后进行解码,经过音视频同步之后,给观众展现出来。
我们在推流端和播放端分别做了非常完善的质量监测体系。
我们再来看看拉流(播放)端,拉流端整体的流程和推流端是一个反过来的流程。
这些复杂的过程在用户点击一个直播之后,绝大部分情况下在几百毫秒以内就会完成,我们也进一步分解了首帧各个环节的时间,能够对它进行深入的分析和优化。
在提取了详细的质量数据之后,接下来就是后端处理的事情了,我将从直播质量数据处理 Pipeline、用户体验质量数据 & 服务质量数据、数据可视化监测流程三个角度为大家全面解析抖音是如何发现直播当中的问题,以及是如何解决的。
下图是抖音现在所使用的直播数据处理 Pipeline,可以很清晰的看到整个流程为数据采集→数据缓存→数据分类处理→数据索引 / 展示。
我们具体看看这个流程的工作细节,数据从抖音 APP 收集,然后经过上报服务器的简单处理之后,会存到 Kafka 的 Topic 里面,Kafka 是非常可靠的数据队列服务,只要 Kafka 的机群够多,即使部分机器宕了数据都不会丢的;接下来,Kafka 的数据会分出两条处理路径:
抖音每天经过这个系统处理的直播相关的数据,在百亿条的量级,直播相关的所有的数据展示和监控都依赖于这整个 Pipeline,要在分钟级要求下,支持各种业务查询需求,保证系统的平稳运行,是很不容易的。
采集到了数据并且对数据进行清洗入库之后,怎么去分析数据呢?我们把数据可视化的监测分为两类:
我们以下图的“进入房间人数”和“退出房间人数”分析,说明一下我们是怎么做联合 QoE 数据和 QoS 数据进行监测和分析的。
首先看看 QoE 数据,左上角是抖音某次直播房间的同时在线人数曲线,在直播过程中在线人数有一个“掉坑”的现象,右下角的“退出房间人数”曲线显示在九点三十多分有一个峰值,说明有大量用户退出房间,我们推测这里可能发生了某些问题导致了观看人数的大量减少,有可能是非技术性的,比如主播做了一件事情观众们不太喜欢,会导致观众大量流失。
奇怪的是,右上角的“进入房间人数”曲线显示,进入房间在同样时刻也有一个峰值,这个时候说明虽然有大量用户退出了房间,但是同时也大量的进入了该房间。
这里我们可以通过 QoE 数据得出一些结论,这一次观众大量退出,应该不是由于直播内容导致的,而是抖音的直播服务有问题导致的,因为观众大量退出同时也大量进入,是因为观众觉得重新打开直播可能可以解决问题,退出直播并不是因为他们不再想看这个直播了 。
为了证实这个判断,我们观测 QoS 数据曲线。下图两条曲线是所有 CDN 节点进入房间人数曲线和退出房间曲线,可以看到在用户大量退出的时候,基本上各个 CDN 节点都会有大量的退出和进入,而不是只有少数节点才有这个行为,这样就可以进一步判断应该不是个别拉流节点的问题的问题,极有可能是主播推流发生了问题。
之后我们联合 CDN 把主播的录像和推流曲线拿到之后,基本上可以断定主播当时的网络发生了抖动,导致短暂的卡顿,之后又立刻恢复,短暂的卡顿导致观众大量退出直播间。
从这个例子我们可以看出 QoE 的指标是一个综合衡量指标,它很直观,虽然并不能直接对应到 QoS 服务质量指标,但我们可以通过它来全局监控,判断是技术还是内容原因出现了体验问题,如果是技术原因,我们再去详细的查看 QoS 指标的时候就可以查出问题的根源。
接下来,我将通过开播跳帧优化和 httpDNS 首屏优化两个例子,以实例说明如何利用大数据做直播系统调优。
拉流端开播的过程,如前面所述,主要是连接 CDN 节点拉取数据,数据的解码、渲染这几个步骤。CDN 的边缘节点一般都会缓存一部分数据,便于拉流端在任何时刻开始拉流都能拉到数据。
为了让用户尽可能的播放流畅,CDN 会尽量的向用户多发一些数据,有时候甚至超过播放端拉流的缓冲区,超过的这部分数据会造成的显著问题是,如果照单全收并且按照正常的速度播,会导致直播延时增大,互动效果变差。
业界公认的互动直播延时标准是小于 5 秒钟,超过 5 秒评论礼物互动效果就会变差。因此我们需要在保证延迟的前提下,尽量缩短首屏,提高流畅度。
如上图,拉流端接收缓冲区长度一般等同于延时,我们把它的长度设置为 5s,如果 CDN 下发的数据大于了接收缓冲区的长度,假设超过的部分是 4 秒,那么如果不做任何处理,正常播放的延时是 5 秒加 4 秒等于 9 秒,9 秒的延时在直播过程中基本上没办法做评论或者交互,体验很差。于是我们一开始尝试从客户端来单独解决这超出的部分数据导致的问题。
尝试了两种的解决办法:直接快进和跳帧,直接快进的方案就是将超过的部分数据快速的播放过去,视频和声音都被加速播放了,这个方案上线之后很快就收到了用户的投诉,怀疑抖音的直播是假直播,真正的直播怎么会出现“快进”的现象。
然后修改了方案,将超出的部分数据直接跳过不进行播放,但是这又带来了新的问题,直接跳帧会导致用户的声音和画面出现突变,主播可能从画面的左边突然出现在画面的右边,体验也不是很好。总之,只在客户端做优化无法做到体验的最优。
由于导致这个问题的真正原因是 CDN 下发数据过多导致的,为了做到最优的体验,必须和 CDN 联合优化。这时,抖音的多 CDN 策略带来一个新的问题:各家 CDN 开播下发数据的策略完全不同, 在开播时下发的数据长度都不一样,很难定量的评价哪一家 CDN 做的更好一些。
于是制定统一的评价标准成为第一个要解决问题,这里抖音使用“开播前 10 秒跳帧时长”作为衡量 CDN 下发数据长度的标准,具体是指拉流端播放的前 10 秒内丢弃数据的总时长。
在制定统一的评价标准之后,通过线上数据观察各家 CDN 的跳帧指标,尝试让各 CDN 优化自己的指标,尽量接近最优的那一家。但是由于各 CDN 的开播策略都大不相同,可配置参数也完全不一样,不同的 CDN 之间很难做到数据完全一致。而且即使是指标最优的 CDN 也无法将开播前 10s 调整时长调整到让抖音满意的程度。
于是,统一各家 CDN 开播数据下发策略成为第二个要解决的重要问题。
我们设计了一套统一的开播数据下发策略,让各家 CDN 都按照这个方案来实现。该方案总的来说遵循三个原则:1. 下发数据长度不能超过抖音拉流端接受缓冲区长度 2. 必须从一个 GOP(Group of Pictures)的开始下发 3. 在不违背前面两点的情况下,下发尽可能多的数据。上图是两个根据服务端缓存的不同 GOP 结构,决定下发数据策略的实际 case,假设抖音拉流端接收缓冲区长度是 5 秒:
制定了统一的开播数据下发策略之后,在多家 CDN 分别上线灰度,对比观察各家 CDN 覆盖节点和未覆盖节点的数据,然后逐步扩大灰度范围直至全量上线。对比优化前的日均值,开播前 10s 跳帧时长从 1500ms 降低至 200ms。
经过上一轮的 CDN 端优化之后,观察全网的开播跳帧数据,各家 CDN 的指标保持在相同的水平(开播 10 秒平均跳帧 200ms 左右),基本可以判断 CDN 端的优化已经到了瓶颈,客户端能否进一步优化解决掉最后的 200ms 呢?这里抖音使用了缓慢快进的方案:将多余的 200ms 在用户无感知的情况下,进行加速播放,控制缓冲区的大小。
只要将加速程度控制在一定范围内,用户基本是没有察觉的,而正常播放时长为 200ms 的数据,经过加速,能很快的播放完,之后就恢复成正常速度播放,这样就保证了不会再有跳帧的现象,最后的 AB TEST 数据显示开播跳帧时长完全为 0,而卡顿情况也有比较明显的降低。
在解决了开播跳帧的问题之后,我们来回顾一下开播跳帧优化的整个过程:
在这整个过程中可以明显看到对抖音整个数据平台的测试监控和统计的依赖,无论是评价 CDN 的质量,还是 CDN 优化后的对比测试,客户端的 AB TEST 效果验证,都需要观察对比全网的数据,才能确认优化效果,证明确实完美解决了跳帧问题。
我们要分享的第二个优化点是首屏的优化,首屏的整个过程,大致可以分为下图的这六个步骤,抖音对各步骤的耗时做了详尽的分析,分析结果显示,DNS 解析其中是最耗时的环节,因此要降低首屏时间,必须先降低 DNS 解析时间。
传统的 DNS 解析(业界统称 localDNS 方案)的过程很简单。整个过程如下图,APP 向所在网络运营商的 DNS Server 发起域名解析的请求,而运营商 DNS Server 会向 CDN 的 GSLB 系统发起递归查询,GSLB 通过运营 DNS Server 所属 IP 地址判断查询来自于哪个运营商和地理位置,然后返回若干合适的 CDN 边缘节点 IP 给它。
这个过程中,APP 和 CDN 之间隔了运营商 DNS Server 这一层,CDN 在分配节点的时候其实没有办法获取任何 APP 的信息。为了解决传统 localDNS 调度不精确,容易被劫持等缺点,近年业界起兴起了另一种方案 httpDNS。其原理是 APP 通过 HTTP 协议直接调用 CDN 提供的 httpsDNS API,获取一组合适的边缘节点 IP。这两种方案互有优劣:
localDNS 和 httpDNS 各有优劣,而且都有一定的失败率,为了提升 DNS 解析的成功率,抖音的 DNS 解析方案是 localDNS 和 httpDNS 结合使用。
为了结合 localDNS 和 httpDNS 的优点,并且考虑到解析返回的多个 CDN 边缘节点的优选,抖音设计了独特的 DNS 解析方案:
于是我们对 IP 优选方案进行了进一步优化,测速后并不是直接选用结果最优的那一个,而是在测试结果可以接受的一定范围内进行随机挑选,这样就避免了大量用户都聚集到少数节点,导致的节点负载不均衡。
对这个优化方案进行 AB TEST,质量数据完全符合预期:
首屏时间下降了 30%,卡顿也有明显改善,节点优选的策略使得连接失败率也下降了 2 个百分点!一个为了优化首屏而提出的策略,对多个指标都有如此明显的正向影响,是我们一开始没有预料到的。
抖音的直播业务现在还处于高速发展之中,对流媒体大数据分析平台也提出了新的挑战:
为了应对这些挑战,我们会持续加强投入,完善数据方面的核心能力。
在大数据平台之上,从整个直播体验优化层面来看,为了真正做到用户体验的端到端可控,我们需要有能力深入所有环节监测和调优,因此抖音将建设核心技术能力作为下一步优化的基础:
抖音的直播业务仍在高速增长,用户数量快速的上涨对服务质量有更高的要求,流媒体大数据平台是各项视频业务的一个基础平台,需要提供完善且稳定的数据收集,数据处理,数据监控,数据分析等服务。
另外还有一些关于c++ Linux后台服务器开发的一些知识点分享:Linux,Nginx,MySQL,Redis,P2P,K8S,Docker,TCP/IP,协程,DPDK,webrtc,音视频等等视频。