弹幕设计
视频的弹幕设计(B站)
直播的弹幕设计
需求分析
70w 在线人数的弹幕系统
带宽压力
假如说每3秒促达用户一次,那么每次内容至少需要有15条才能做到视觉无卡顿。15条弹幕+http包头的大小将超过3k,那么每秒的数据大小约为8Gbps,
带宽优化
- Http 压缩(小数据的 Http 压缩的性价比?)
通过查阅资料,http gzip压缩比率可以达到40%以上(gzip比deflate要高出4%~5%)
-
弹幕的 Response 结构简化,降低传输字节数
-
内容排列顺序优化,将字符串和数字内容放在一起摆放,增加压缩比;
-
频率控制
-
带款控制:通过添加请求间隔参数(下次请求时间),保证客户端的请求频率服务端可控
- 通过添加请求间隔参数(下次请求时间),保证客户端的请求频率服务端可控
弹幕卡顿、丢失分析
根据了解腾讯云的弹幕系统,在300人以下使用的是推送模式,300人以上则是采用的轮训模式。
促达机制,推送 vs 拉取
- Long Pulling
- 减少轮询次数,低延迟,浏览器兼容性较好
- 服务器需要保持大量连接
- WebSocket:
- 较少的控制开销(相对于 HTTP 请求每次都要携带完整的头部),更强的实时性;
- 每个客户端使用一个持久化的连接
Long Polling 能发现连接异常的最短间隔为:\(min(keepalive\_intvl, polling\_interval)\)
Websockets能发现连接异常的最短间隔为:\(min(keepalive\_intvl, client\_sending\_interval)\)
弱网情况下Websockets其实已经不能作为一个候选项
- 即使Websockets服务端已经发现连接断开,仍然没有办法推送数据,只能被动等待客户端重新建立好连接才能推送,在此之前数据将可能会被采取丢弃的措施处理掉;(没有缓存/入库?)
- 在每次断开后均需要再次发送应用层的协议进行连接建立。
可靠与性能
将逻辑较为复杂、调用较少的发送弹幕业务与逻辑简单、调用量高的弹幕拉取服务拆分开来。
- 不同服务的QPS往往是不对等的,例如像拉取弹幕的服务的请求频率和负载通常会比发送弹幕服务高1到2个数量级
拉取弹幕
- 数据更新的策略是服务会定期发起RPC调⽤从弹幕服务拉取数据,拉取到的弹幕缓存到内存中
- 缓存:按照时间进行分片(采用 RingBuffer),最多保留60秒的数据,只保留了尾指针,它随着时间向前移动,每⼀秒向前移动一格
-
读请求:缓冲环会根据客户端传入的时间戳计算出指针的索引位置,并从尾指针的副本区域往回遍历直至跟索引重叠,收集到一定数量的弹幕列表返回
-
写操作是单线程,读和写是相反的方向,⽽决定读和写的位置是否出现重叠取决于index的位置,
- 保证读操作最多只能读到30秒内的数据,因此缓冲环完全可以做到无锁读写
发送弹幕
- 用户一定时间能看得过来弹幕总量是有限
- 对弹幕进行限流,有选择的丢弃多余的弹幕