BILIBILI 高并发实时弹幕系统那些事(项目开源、架构演变)

B 站建立开源工作组:ijkplayer 等多个项目开源

SegmentFault 兄弟 + 基友单位弹幕视频 Bilibili(B 站)近日在 GitHub 站上建立了开源工作组(BOSTF)(此处 1024 赞),用以分享与维护自己的开源项目,其中包括 DanmakuFlameMaster(燃烧吧!烈焰弹幕使)与 ijkplayer。前者是免费提供 Android 平台下应用弹幕集成的解决方案,而后者则提供 Android 和 iOS 双平台视频播放器的解决方案。

DanmakuFlameMaster

项目地址:https://github.com/Bilibili/DanmakuFlameMaster

ijkplayer,基于 ffplay 的跨平台播放器,实现的特性有:

  • 移除 FFmpeg 中不常用的特性以减小体积。
  • 对一些在线视频播放的 BUG 修复
  • 支持安卓 API 9-22 和 iOS 5.1.1-8.3.X
  • 使用各种平台原生的渲染方式进行优化

作为国内首屈一指的弹幕视频 站,B 站的两个开源项目已经被多个 App 使用。其中美拍和斗鱼使用了 ijkplayer 项目,DanmakuFlameMaster 项目则被包括优酷土豆、开迅视频、MissEvan、echo 回声、斗鱼 TV、天天动听、被窝声次元、ACFUN 等 App 使用。

技术上,ijkplayer 实现了跨平台功能,支持 Android 和 iOS 双平台;API 易于集成;编译配置可裁剪,方便控制安装包大小;支持 硬件加速解码,更加省电。而DanmakuFlameMaster 架构清晰,简单易用,支持多种高效率绘制方式选择,支持多种自定义功能设置。

Bilibili,也被称为哔哩哔哩、B 站,是中国大陆一个动画、游戏相关的弹幕视频分享 站,因为其深厚的宅文化和实时评论功能,已经在 90 后中收到广泛的欢迎。据悉,B 站的程序员也多为 90 后。

哔哩哔哩~( ゜- ゜)つロ 乾杯~

  • 开源项目介绍 
  • 开源软件

  大舒 2015年05月08日发布

https://segmentfault.com/a/1190000002739762

BILIBILI 高并发实时弹幕系统的实战之路 | 架构师实践日

  • 高稳定性,为了保证互动的实时性,所以要求连接状态稳定。
  • 高可用性,相当于提供一种备用方案,比如,互动时如果一台机器挂了,此时必须保证可以和另外一台机器连接,这样就从侧面解决了用户连接不中断的问题。
  • 对于低延迟,弹幕的延迟周期控制在 1 秒以内,响应是比较快的,所以可以满足互动的需求。  

B 站直播弹幕服务架构(下面简称 GOIM )的出现就是为了解决这一系列的需求。下面将对此进行详细的介绍。

B 站直播弹幕服务架构 GOIM 的出现

直播聊天系统本质上也是一种推送系统,所谓推送系统就是,当你发送一条消息时,它可以将这个消息推送给所有人。对于直播弹幕来说,用户在不断地发送消息,不断地进行广播,当一个房间里面有 10 万人时,一个消息就要发出 10 万次请求。在 GOIM 出现之前,也用过另一个名为 Gopush 的项目,这个项目推出的目的就是进行推送。在此之后,基于一些针对性的应用场景,GOIM 对 Gopush 进行了优化,从而出现在我们视野当中。GOIM 主要包含以下几个模块(图 1):

  • Kafka(第三方服务)
    消息队列系统。Kafka 是一个分布式的基于发布/订阅的消息系统,它是支持水平扩展的。每条发布到 Kafka 集群的消息都会打上一个名为 Topic(逻辑上可以被认为是一个 queue)的类别,起到消息分布式分发的作用。
  • Router 
    存储消息。Comet 将信息传送给 Logic 之后,Logic 会对所收到的信息进行存储,采用 register session 的方式在 Router 上进行存储。Router 里面会收录用户的注册信息,这样就可以知道用户是与哪个机器建立的连接。
  • Logic
    对消息进行逻辑处理。用户建立连接之后会将消息转发给 Logic ,在 Logic 上可以进行账 验证。当然,类似于 IP 过滤以及黑名单设置此类的操作也可以经由 Logic 进行。
  • Comet
    维护客户端长链接。在上面可以规定一些业务需求,比如可以规定用户传送的信息的内容、输送用户信息等。Comet 提供并维持服务端与客户端之间的链接,这里保证链接可用性的方法主要是发送链接协议(如 Socket 等)。
  • Client
    客户端。与 Comet 建立链接。
  • Jop 
    消息分发。可以起多个 Jop 模块放到不同的机器上进行覆盖,将消息收录之后,分发到所有的 Comet 上,之后再由 Comet 转发出去。

以上就是 GOIM 系统实现客户端建立链接,并进行消息转发的一个具体过程。一开始这个结构并不完善,在代码层面也存在一些问题。鉴于这些问题,B 站提供了一些相关的优化操作。在高稳定性方面,提供了内存优化、模块优化以及 络优化,下面是对这些优化操作的介绍。

GOIM 系统的优化之路

内存优化

内存优化主要分为以下三个方面:

1.一个消息一定只有一块内存

使用 Job 聚合消息,Comet 指针引用。

2.一个用户的内存尽量放到栈上

内存创建在对应的用户 Goroutine(Go 程)中。

3.内存由自己控制

主要是针对 Comet 模块所做的优化,可以查看模块中各个分配内存的地方,使用内存池。

 

模块优化

模块优化也分为以下三方面:

1.消息分发一定是并行的并且互不干扰

要保证到每一个 Comet 的通讯通道必须是相互独立的,保证消息分发必须是完全并列的,并且彼此之间互不干扰。

2.并发数一定是可以进行控制的

每个需要异步处理开启的 Goroutine(Go 协程)都必须预先创建好固定的个数,如果不提前进行控制,那么 Goroutine 就随时存在爆发的可能。

3.全局锁一定是被打散的

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2016年9月11日
下一篇 2016年9月11日

相关推荐