直播弹幕系统设计

news2024/11/18 2:29:55

本文仅提供思路参考,并非完备的详细设计。

特点

其实很类似IM即时通讯系统,是个变种,本质也是在一个空间内收发消息

  • 消息及时性强,过期消息意义不大
  • 用户松散,随时来随时走
  • 可能有瞬时大批量弹幕(比如比赛精彩部分)
  • 流量特点:读多写少

弹幕数据结构

type Bullet struct {
	UserId    int // 用户ID
	Content   string // 内容
	Timestamp int // 弹幕发送时间
	Extra     *Extra // 效果、样式
}

视频弹幕才有偏移时间,直播应该不用(因果一致性)

MVP版本

整体设计

读写分离架构,短连接+拉模式

  • 写:若不考虑历史弹幕可回放,可以直接使用 Redis 作为唯一存储
  • 读:Redis 主要用于读缓存,缓存直播间最新的弹幕数据

在这里插入图片描述

存储

数据结构选择Redis的ZSet

  • 需要弹幕按时间排序,而ZSet可保证有序
  • 此外,score允许重复,那我们就用timestamp来做score

使用

  • 发弹幕:ZADD 直播间ID, 弹幕val, timestamp(优化:时间只存相对于某个时间点的delta)
  • 拉取弹幕:ZRangeByScore 定时轮询(秒级,准实时即可)

问题

  1. 弹幕怎么持久化(Redis扩容成本高)
  2. 热门直播会有大量瞬时弹幕,挑战Redis并发瓶颈
  3. Redis重复请求多,相同直播间会存在很多重复的轮询请求

问题cover

  1. 持久化

    1. 若考虑支持弹幕的回放,数据还是需要持久化,可以考虑使用 MySQL

      1. 弹幕在直播结束后迁移至 DB(可以专门拿一台从redis做回放)
      2. 异步刷入(开线程/监听redis日志刷/发MQ消费)
    2. 如果有更高性能的写需求,可以考虑NoSQL DB,如:HBase、OpenTSDB 等

    3. 新问题:Write-Behind 这种以cache为主的模式,是可能会丢数据的

      1. DB挂了,少写数据,但是只要数据还在redis能追回来
      2. redis挂了,服务感知到后降级,请求回源,“缓存击穿”
  2. 使用MQ来消化瞬时弹幕,削峰;弹幕返回条数根据直播间的大小自动调整(热门直播间对时间跨度以及消息条数做更严格的限制)

  3. 对弹幕读请求,使用local cache缓存最近5s的数据在应用服务的内存中(过期了才回源redis)

    1. 新问题:如果直播间变多,本地内存使用量随直播间线性膨胀,本地cache的命中率下降,还可能频繁触发GC

    2. 解决:(1)只针对热门直播间使用本地cache使用“一致性hash”,控制同一直播间尽可能打到同一台服务器,降低本地cache使用量

优化:热门直播间

  • 需要对每个直播间进行指标采样

    • 标准:粉丝数、在线粉丝数、是否有活动
    • 弹幕系统需要与直播间系统隔离
    • 请求时带上直播间的“热门”标识
  • 根据服务器机器资源来分配所承载的热门直播间

长连接轮询

此前短连接的方式,每次轮询请求后都要重新建立连接。如果使用长连接轮询,客户端保持连接处于打开状态,就不会一直重新建立链接,减少重复的资源消耗,缩短响应时间。

不过,长连接轮询还是有一些缺点的:

  • 发送者和接收者可能并没有连接到同一个服务器

    • HTTP协议的服务器通常是无状态的,如果使用Round Robin的方式来做负载均衡,接收到弹幕的服务器可能并没有与等待接收消息的客户端保持长轮询连接
  • 服务器没有好的方法来判断客户端有没有断开连接

架构图

在这里插入图片描述

推模式

上面MVP版本是拉模式,适合前期;中后期规模和性能要求上来了,需要引入推模式。

架构图

在这里插入图片描述

长连接推送

为了保障客户端消息的推送性能和实时性,需要引入长连接

  • Push Server:负责推送(不感知直播业务)

    • 存储:从 Redis 中获取用户和直播间的关系以及长连接信息
    • 推送:分批并发推
  • connection proxy:只负责与客户端保持长连接

使用技术

  • WebSocket(HTTP 2.0支持的全双工通信+长连接)
  • Session(基于redis,通过用户会话来推)

优化

  • 有状态服务需要做好路由
  • 两个批量推送:消费 MQ 后批量推;从 push server 到连接代理的每个连接上也批量
  • 推拉结合,可以把短连接的拉作为长连接推的降级方案(服务端监控+客户端上报)

其他挑战

  • 写扩散(m条消息*n次扩散,平方级别)⇒ MQ控制推送速率
  • 丢弹幕 ⇒ push 失败引入重试;落 DB 引入 ACK
  • 带宽压力
  • 灰度拉切推

其他思路

  • 使用 redis 的 Stream 来做弹幕的发送(生产)和阅读(消费)
  • 前端展示上的优化
    • 弹幕去重
    • 发送弹幕后,本地优先展示(即使它丢了 or delay)

参考

  • https://cloud.tencent.com/developer/article/1645888
  • https://www.bilibili.com/video/BV1Uu411u7Cm/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1594504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

整数在内存中的存储和内存操作函数

目录 整数在内存中的存储1. 整数在内存中的存储2. 大小端字节序和字节序判断2.1 什么是大小端?2.2 为什么有大小端 3. 练习3.1 请简述大端字节序和小端字节序的概念,设计⼀个小程序来判断当前机器的字节序。(10分)-百度笔试题3.2 练习23.3 练…

Linux三剑客-sed、awk、egrep(上)

一、知识梗概 二、正则表达式 定义:正则表达式是一种强大的文本处理工具,用于在文本中搜索符合特定模式的字符串。它由一系列特殊字符和普通字符组成,可以定义复杂的搜索模式。正则表达式被广泛应用于各种编程语言和文本处理工具中。 简单来…

【DNS】

文章目录 DNS域名解析系统(Domain Name System)DNS系统需要解决的问题DNS域名解析系统(Domain Name System)问题1:DNS名字空间(The DNS Name Space)DNS名字空间(The DNS Name Space)DNS名字空间(The DNS Na…

解锁生成式 AI 的力量:a16z 提供的 16 个企业指南

企业构建和采购生成式AI方面的16项改变 生成式 AI 领域趋势洞察:企业构建和采购生成式 AI 的方式正在发生重大转变,具体表现在:* 专注于可信度和安全性:75% 的企业将信任和安全性视为关键因素。* 优先考虑可扩展性和灵活性&#x…

Go语言入门|包、关键字和标识符

目录 Go语言 包文件 规则 关键字 规则 标识符 规则 预定义标识符 Go语言 Go语言是一种静态类型、编译型和并发型的编程语言,由Google开发。Go的源代码文件以.go为扩展名,文件名通常与包名保持一致。一个Go文件可以包含多个顶级声明,…

WXML模板语法-条件与列表渲染

wx:if 在小程序中&#xff0c;使用wx:if"{{condition}}"来判断是否需要渲染该代码 也可以用wx:elif和wx:else来添加else判断 <!--pages/ifIndex/ifindex.wxml--> <view wx:if"{{type 1}}">男</view> <view wx:elif"{{type …

基于ICEEMDAN-SVD的信号去噪算法

一、代码原理 ICEEMDAN-SVD算法是一种结合了Improved Complete Ensemble Empirical Mode Decomposition with Adaptive Noise (ICEEMDAN) 和奇异值分解 (SVD) 的信号去噪方法。这种算法结合了两种先进的信号处理技术&#xff0c;旨在提高信号去噪的效果。以下是该算法的基本原…

深入理解信号上升沿与带宽的关系

信号的上升时间&#xff0c;对于理解信号完整性问题至关重要&#xff0c;高速pcb设计中的绝大多数问题都和它有关&#xff0c;很多信号完整性问题都是由信号上升时间短引起的&#xff0c;你必须对他足够重视。 信号上升时间并不是信号从低电平上升到高电平所经历的时间&#xf…

Ubuntu-22.04安装KVM虚拟机并安装Windows10

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、KVM是什么&#xff1f;二、安装步骤1.检查虚拟化2.查看KVM虚拟化3.安装KVM4.启用后台进程5.添加用户组6.重启电脑 三、使用步骤1.添加虚拟机2.配置虚拟机3.…

数据可视化高级技术Echarts(堆叠柱状图)

目录 一.如何实现 二.代码展示 1.stack名称相同&#xff08;直接堆叠&#xff09; 2. stack名称不相同&#xff08;相同的堆叠&#xff0c;不同的新生成一列&#xff09; 一.如何实现 数据堆叠&#xff0c;同个类目轴上系列配置相同的 stack 值可以堆叠放置。即在series中…

Rust取代C++? 保守了!关于未来的讨论

当各种平台在大肆讨论rust即将取代C/C的时候&#xff0c;已经有不少人意识到这种讨论是聒噪而无聊的。笔者和老师们通过周末茶会的讨论&#xff0c;认为现今世界常见的大多数编程语言都会在50-80年内被AI取代&#xff0c;同时供人类审计而诞生的“审计语言”会兴起。届时计算机…

LeetCode刷题记(三):61~90题

61. 旋转链表 给你一个链表的头节点 head &#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], k 2 输出&#xff1a;[4,5,1,2,3]示例 2&#xff1a; 输入&#xff1a;head [0,1,2], k 4 输出&…

虚拟机VMware的下载、注册码(Mac与Windows)

1. 虚拟机的下载 windows 版的虚拟机叫 VMware Workstation mac版的虚拟机叫 VMware Fusion 官网下载地址: window 下载地址 https://www.vmware.com/content/vmware/vmware-published-sites/us/products/workstation-pro.html mac 下载地址 https://www.vmware.com/prod…

【ELFK】Filebeat+ELK 部署

FilebeatELK 部署 在 Filebeat 节点上操作 环境准备 Node1节点&#xff08;2C/4G&#xff09;&#xff1a;node1/192.168.67.11 Elasticsearch Kibana Node2节点&#xff08;2C/4G&#xff09;&#xff1a;node2/192.168.67.12 Elasticsearch Apache节点&…

解放双手,批量绕过403

将dirsearch扫描出来的结果复制到url.txt&#xff0c;如下所示 url.txt [21:18:16] 502 - 0B - /var/log/exception.log [21:18:21] 502 - 0B - /WEB-INF/jetty-env.xml [21:18:22] 502 - 0B - /WEB-INF/weblogic.xml [21:18:27] 502 - 0B - /wp-json/wp/v2/u…

【域适应】基于域分离网络的MNIST数据10分类典型方法实现

关于 大规模数据收集和注释的成本通常使得将机器学习算法应用于新任务或数据集变得异常昂贵。规避这一成本的一种方法是在合成数据上训练模型&#xff0c;其中自动提供注释。尽管它们很有吸引力&#xff0c;但此类模型通常无法从合成图像推广到真实图像&#xff0c;因此需要域…

Pandas相比Excel的优势是哪些?

熟悉Pandas的同学会知道&#xff0c;Pandas相当于Python中的Excel&#xff0c;都是基于二维表的进行数据处理分析&#xff0c;不同的是&#xff0c;Pandas基于代码操作数据&#xff0c;Excel是图形化的分析工具。 不少人会问Excel比Pandas更简单&#xff0c;为什么还要学习Pan…

SSL Pinning之双向认证

双向认证处理流程 概述获取证书逆向app 获取证书的KeyStore的 key通过jadx 反编译 app 获取证书&#xff1a;frida hook 证书转换命令行转换portecle 工具使用 charles 配置 p12 格式证书 概述 本篇只介绍怎么解决ssl pinning&#xff0c; 不讲ssl/tls 原理。 为了解决ssl pinn…

【Java】内存可见性问题是什么?

文章目录 内存模型内存可见性解决方案volatile 内存模型 什么是JAVA 内存模型&#xff1f; Java Memory Model (JAVA 内存模型&#xff09;是描述线程之间如何通过内存(memory)来进行交互。 具体说来&#xff0c; JVM中存在一个主存区&#xff08;Main Memory或Java Heap Mem…

MySQL优化慢SQL的6种方式

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《mysql经验总结》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途 目录 写在前面 优化思路 优化方法 1.避免查询不必要的列 2.分页优化 3.索引优化 4.JOIN优化 5.排序优化 6.UNION 优化…