千万级用户直播APP——服务端结构设计和思考

一直播产品是一下科技今年五月份刚上线的产品。得益于与微博的深度合作,以及与小咖秀、秒拍共同运营,一直播开始时就有一个很高的起点,短短半年内,达到同时在线用户百万级规模。在2016杭州云栖大会的“开发者技术峰会”上,来自一下科技的技术副总裁张华伟给大家解密了一直播千万级用户服务端架构设计和成长历程。

以下内容根据演讲PPT及现场分享整理。


直播行业是今年最为火爆的行业,作为新兴的产品形态,直播产品最大的特点是:快。推流速度足够快,主播通过移动端快速推流,用户能快速看到直播场景,延迟需要足够低,而且移动端类型十分复杂、种类繁多,这是一个很大的挑战;首帧加载速度要足够快,用户打开直播页面时,能立即观看画面;支付也需要足够快,用户给主播送礼物时,保证直播时的互动效果;录制、转码、存储都需要足够快。

那么一直播是如何在短短半年内应对这些如此之快的要求呢?下面从业务结构、缓存、互动、调度四个方面为你揭开秘密。

业务结构——集群+模块化

千万级用户直播APP——服务端结构设计和思考

一个优秀的互联网项目架构至少应该做到两点:第一点模块化拆分;第二点资源分层。将一个复杂的系统拆分成N个小系统,之后再对小系统进行功能优化。如上图所示,一直播平台架构的最前端是安全防护接入层,用于系统的安全防护;此后是URL路由,将流量从入口通过负载均衡按照用户请求URL下发到不同的模块上,再导流到后端不同的集群上,从源头上进行分流;URL路由之后是接口层,将后端的服务、功能模块的接口进行整合,之再后提供给前端用户。

下面具体看一下每个模块的功能与结构。

路由调度

千万级用户直播APP——服务端结构设计和思考

目前,一直播平台中采用二级域名+分层目录路由的方式进行URL分层,如member层、评论层、直播层等一级目录直接下发到不同集群上;二级目录做成对外的接口,如API、OpenAPI、Web层,再将其划分到内部接口、外接口或H5、PC上;第三层目录是真正处理的业务逻辑。

这样分层处理之后,后期的分集群优化就变得十分简单。

模块化拆分

千万级用户直播APP——服务端结构设计和思考

前端进行URL分层之后,后端需要按照业务功能进行模块拆分,将复杂的功能拆解,例如将用户系统拆解成一个独立的用户服务,再将用户服务拆分成用户注册、用户中心、关注关系等。模块化拆解之后,单模块资源共享,无交叉影响;同时,还可以将核心业务与非核心业务分开,核心业务放在核心资源池内,在突发流量到来时,可以优先保证核心业务的可用性,非核心业务进行降级或者关闭处理;此外,消息队列异步持久化,如图中所示的用户、缓存的后端持久化都是相互独立的,保证消息响应速度。

资源分层治理

千万级用户直播APP——服务端结构设计和思考

接下来看一下资源分层治理,整个系统按照功能模块拆分后,各种资源分层之后,后期的资源治理就变得十分简单。在接入层,搜集全部日志资源,对所有的请求做分析,便于后期监控、数据分析等处理;在接口层,用户请求进来之后,下发到不同的接口集群上,接口集群对后端的服务进行组合封装。接口层承载了大量的压力,在预知大的活动发生前,可以在该层人工或系统自动扩容一批机器,例如在赵本山直播前,在该层将机器的数目增加一倍。服务层是真正的业务处理层,它包含了业务处理、缓存、数据持久化。服务层下侧是缓存和持久化层,之所以将二者分开,是因为缓存在互联网架构中的重要性不言而喻,在突发流量到来时,缓存至少可以承载系统80%-90%的压力。

数据库

千万级用户直播APP——服务端结构设计和思考

一直播架构中按照模块、功能划分数据库,不同的数据库再分配到不同的物理机上,并非整个项目共用数据库。由于绝大数应用读远远大于写,因此,在该场景下可以对数据库进行读写分离,如Master-Slave、MySQL等方式;同时对数据库进行水平、垂直拆分。

缓存——多级缓存之演变

千万级用户直播APP——服务端结构设计和思考

基本的缓存模型如上图所示,服务层直接调用后端的缓存集群,但在一直播架构中增加了本地缓存。当某一大明星的直播开始时,在极短的时间内大量的粉丝会同时涌进一个直播间,此时主播的热度是非常高的,如果将全部请求都导入后端集群,势必给后端集群带来非常大的压力。当大量数据在短期内变化不是特别大时,可以在前端的业务层上本地缓存(可以采用Memcached、Reids等方式),通过在本地缓存3-5秒就可以承受80%-90%系统压力,瞬间化解后端缓存集群的压力。

后端的缓存集群的常规设计有两种:

  • 第一种是将大数据通过HASH模式分拆到后端不同机器上,加大可承载的数据量,这种方式的缺点是:当无法进行本地缓存只能采用远程集群时,如果过HASH模式将某Key下发到后端的某个节点上,会瞬间给该节点带来较大的压力,一旦该节点挂掉,前端的接口层和业务层会出现卡顿现象,进而导致整个系统瘫痪为了应对这种情况;
  • 第二种方式是目前一直播架构中采用的方式,在前端挂一层HASH模式,通过HASH将Key分布开,后端通过主从模式,做成一主多从的模式,进而解决热点key读取量大的难题。

在缓存中,还有一点需要注意的是:重点数据单独布署。如果对所有的集群全部按照第二种方式搭建,成本势必很高。由于大量的主播访问量并不是很高,如果进行主从部署时也会导致资源的大量浪费,因此对于大明星、网红等重点主播的Key可采取单独部署的方式,以节约资本。

互动——百万在线聊天室搭建

千万级用户直播APP——服务端结构设计和思考

谈到移动直播,互动必然是绕不开的话题。移动直播聊天室和传统的聊天室不同,他主要具有以下几个特点:

  • 用户集中在热点直播间
  • 热点直播消息量巨大
  • 消息实时性强
  • 用户进出直播间随机性大

刘烨和本山大叔的直播,单个直播间有百万级别的用户实时在线聊天、送礼互动。

 

千万级用户直播APP——服务端结构设计和思考

那么支撑如此庞大用户的聊天室架构是如何设计的呢?如上图所示,一直播的聊天室架构主要分为接入层、路由层,其中接入层又分为连接保持层和业务逻辑处理层。通过在接入层保持用户的连接;路由层进行消息中转;业务层对接入层传入的消息进行处理。该架构需要保障可用性、扩展性和低延迟,首先接入层需要扩展,因为接入层需要挂在全平台在线的用户,所有消息的下发都是通过接入层处理;在路由层,消息量反而减小。

 

千万级用户直播APP——服务端结构设计和思考

上图是平台消息的流转图。客户端上行消息之后,通过接入层接入业务逻辑处理;由于整个直播平台是构建在阿里云ECS上,而ECS单机挂载的用户量有限,因此消息经业务逻辑处理之后需要进入本地队列,将请求平滑后进行业务处理,平滑的过程取决于后端的处理线程,根据平台规模动态调整线程数量,保持消息队列中消息数目最少,从而保证消息到达的及时性。

业务逻辑层对消息进行处理后,将消息转发给后端的路由层;路由层根据消息的信号记录,通过路由层的索引规则发给其他路由节点;其它路由节点下发给自身挂载的接入节点;接入节点收到消息之后,同样进入消息队列,线程处理方式同上,对消息进行判断,如果是单方向的消息直接转发,多方向的消息循环转发给节点用户。

千万级用户直播APP——服务端结构设计和思考

对于大型直播间,由于移动端资源有限,对所有消息全部转发是不可能实现的,因此需要对消息进行限流。流控原则第一种方式式根据消息类型,如果将用户评论全部转发给客户端,则会出现滚屏现象,导致信息无法识别,这时需要对消息按时间维度进行管控(一分钟内下发定量消息);第二种方式是按照在线人数,将在线人数分区(几万个用户为一区),各分区间消息互通;第三种方式根据用户特征,对级别较低的用户和刚注册的用户的发言进行适当屏蔽。

调度——推流+播放

调度主要包括推流调度和播放调度。移动端和传统秀场直播不同,传统秀场通过PC端进行推流,移动端的网速、性能相比于PC端都存在一定的差距,因此移动端的推流受限于用户的设备和地理位置的不确定性,例如在一直播平台上,明星主播或网络红人的位置非常随机,有可能在非洲或者在巴西奥运会现场亦或是偏僻的山区,在这些场景下如果本地调度出现偏差,推流的质量就会非常差。

千万级用户直播APP——服务端结构设计和思考

目前一直播平台在推流和播放的调度方面采用的是第三方的CDN。如上图所示,用户需要推流,首先到调度中心获取离他最近的推流节点;用户将流上传到推流节点后,该节点将流分发到流控中心;流控中心再将流分发到内部的CDN网络上,内部的CDN网络再将该流下发到各个节点上。当用户需要播放直播时,首先到最近的调度节点上获取最近的播放节点,获取播放节点之后播放即可。目前播放协议上行支持RTMP;下行时Http/flv和M3U8效果更好,在H5上一般采用M3U8,移动端、PC端采用Http/flv。

上一篇:记录一次Quartz2D学习(六)


下一篇:HPU1460: 杨八方的表面兄弟