案例分析——快手百万在线直播
一、前言
首先分享出原文链接http://www.infoq.com/cn/news/2017/09/streaming-Pipeline-kuaishou。自己平时并未用过快手,但是通过“宇宙中心”——五道口 快手巨大的LOGO以及 老家小伙伴的聊天内容来看,快手还是相当火爆的。虽然,直播这个技术看起来很简单,但是能够同时支撑百万人的实时直播就需要很强的技术功力了。
二、博文整理
- 挑战:通常情况下主播都是用手机,网速无法保证,如何保证观众观看的流畅度
解决方案:实时监测主播手机网络状态,根据网络状态动态调整视频码率。因为视频的录制、编辑(美颜、水印等)、编码压缩等操作都是在主播手机上发生的,因此直播视频的码率还需要根据主播的手机配置(CPU,摄像头像素等)调整,在保证直播流畅的前提下尽量的提升画质。另一方面,就需要购买足够的带宽、CDN等资源了。
- 挑战:主播和观众互动的时候,如果解决跨线路、CDN的数据不同步的问题(秒杀顺序问题)
解决方案:主播的直播内容会推送到一个CDN源,然后这个CDN源将编码后的视频流分发到各个CDN厂商的服务器上,观众通过连接CDN厂商的服务器来获取直播内容;在分发视频源的过程中,需要保证各个CDN得到的视频与直播信号的延时以及各个CDN之间传输的延时在一个可接受的范围内(需要与每个CDN厂商协调),这样才能保证不同地区的用户同步(相差不大)看到直播。最好的方法是:自建CDN;
- 链路运行监控
解决方案:在直播端,统计主播手机的各个参数信息,直播过程中将手机CPU、内存、视频帧率等信息上传到监控中心;视频向CDN源站推送的过程中,监测连接质量以及网络延时。用户播放端,统计DNS解析、网络延时(从发送请求到收到应答包)、缓冲区大小(缓冲区越大,一次请求传输的数据越多,播放效果越流畅)。
从手机端统计到的监控数据会发送到监控中心的服务器,数据处理流程是:kafka作为可靠的消息队列负责接收上报的统计数据,kafka中的数据可以被消费两次,一次是用于实时处理展示(通过Flink从kafka消费数据并进行清洗,然后写入到Elastic Search集群,利用Kibana实时展示Elastic Search中存储的信息,存储量小导致只能保存最近一段时间的数据),另一种是非实时的(Hadoop集群消费Kafka中的数据并进行对应的处理,将处理后的数据写入Hive数据库,实时性差但是存储量大)主要用于存储历史数据供后期复盘分析使用。
- 监控数据分析、使用
解决方案:利用Elastic Search或者Hive中存储的数据可以从两个维度来进行分析展示:1、用户体验质量(QoE):直播在线人数、直播跳出率等,通过分析这些数据以及相关的直播内容,可以推断出这些指标的变化是直播内容(无聊、违规等)导致的还是技术原因导致的。利用这些监控指标,可以及时的处理一些违规直播内容或者找出产品存在的某些缺陷。2、服务质量(QoS):纯技术参数(如视频帧率变化、直播延迟等问题),很多时候可以结合QoE来精确定位一些问题。
- 上线流程
解决方案:添加新模块、bug修复等操作完成后,需要通过灰度验证、AB测试的方式进行上线,上线前需要测试回滚流程以保证在灰度的过程中出现BUG可以很快的回滚到之前可用版本。(PS:阿里内部灰度步骤是:5% 10% %30 %50 %100,每个步骤之间通常会间隔4个小时左右,用以确认灰度效果)
- 开播跳帧优化
解决方案:通常情况下CDN直播服务器都会缓存一小部分内容(延时),一遍用户在任何时候打开都可以立即获取到内容。每个客户端从CDN拉取的数据都会存到接收缓冲区,这个缓冲区只能接收一定长度的数据,而CDN服务器为了使直播尽量流畅,每次都会向用户多发数据,如果超出缓冲区的长度,数据就会被丢弃,如果下次请求接收被丢弃的数据,直播延时就会进一步增大(观众无法参与互动),如果拉取新数据就会出现跳帧等情况,效果非常差。制定统一的发送数据长度与app上的接收缓冲区匹配,协调每个CDN厂商配合修改。另外还可以在客户端播放时,通过提高播放帧数来加速播放,解决与直播相差加大的问题。
- DNS解析耗时过长
解决方案:通常情况下,用户访问一个互联网资源DNS解析都是必须的,但是由于标准的DNS解析服务器没有负载、延时监测,会造成后端DNS负载不均衡的情况,间接影响到了直播流畅度。采用app内置内部的DNS(改进后的)地址,来加快DNS解析速度,解决负载不均衡问题。
三、个人总结
整个分享的文章中,个人感觉最受益的是:
- 全链路监控以及监控数据可视化,这对于一个庞大的分布式系统来讲是相当重要的。
- 大数据的运用,分析用户的观看行为可以对直播内容以及资源配置进行有针对性地优化,增加用户粘性的同时降低资产成本。在这个互联网时代,每个人都需要了解一些大数据的东西。
- 这一点是我自己想的,运用机器学习等现代方法对海量数据进行挖掘,找出一些有用的信息。
- 上线的整个过程需要认真学习,这都是经验之谈。
- 要么有钱(自建CDN),要么有人(运用技术解决CDN、DNS等问题)
上学的时候,写过一个简单的聊天工具,无界面、无认证的方式,当时觉得想要做出一款聊天软件只需要加上界面以及登录认证就可以了。工作后,接触的东西多了,才发现同样的一件事,并发100和并发100w有着天壤之别。任何一个小事被放大100w倍之后,都是很大的一件事。写程序时,必须提前做好设计,考虑多种情况,然后严格测试、灰度上线、故障回滚。这些东西都是需要很深的技术、工程积累的。
欢迎技术探讨:sxhlinux@163.com