V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
RunningRabbit
V2EX  ›  Android

高并发场景下如何设计播放器上报播放进度?

  •  
  •   RunningRabbit · 55 天前 · 2923 次点击
    这是一个创建于 55 天前的主题,其中的信息可能已经有所发展或是发生改变。

    视频播放进度如何合理设置上报事件?保证最新的播放进度记录,目前是每 30 秒上报一次,离开时上报一次,高并发情况下,接口处理不过来,前端从播放器返回或者直接杀死 app 保证会上报吗?

    36 条回复    2023-02-07 11:20:10 +08:00
    joesonw
        1
    joesonw  
       55 天前 via iPhone
    进度放本地呗,被杀掉的话,下次启动上传。
    tramm
        2
    tramm  
       55 天前
    处理不过来? 不可能吧, 又没啥业务逻辑啊...
    yazinnnn
        3
    yazinnnn  
       55 天前
    多高的并发?
    aplusfran123
        4
    aplusfran123  
       55 天前 via iPhone
    是并发高到缓存 buffer 啥的都不够用?不太理解
    documentzhangx66
        5
    documentzhangx66  
       55 天前
    处理不过来,应该先找瓶颈。

    当然,省级系统,1C1G1M 的云主机,那肯定处理不过来。
    RunningRabbit
        6
    RunningRabbit  
    OP
       55 天前
    @joesonw 放本地更换设备这些记录是不是没看不到了?
    yidinghe
        7
    yidinghe  
       55 天前
    处理不过来的具体 QPS 是多少,如果服务端只是简单的将进度缓存起来,没有业务逻辑的话,不存在处理不过来的。
    RunningRabbit
        8
    RunningRabbit  
    OP
       55 天前
    @tramm
    @yazinnnn
    @aplusfran123
    @documentzhangx66 用户量比较大,10 万用户,每 30 秒上报一次,请求量确实挺大的。后端接口后面也做下优化
    RunningRabbit
        9
    RunningRabbit  
    OP
       55 天前
    @yidinghe 是的,后端需有优化下存储这块,同时也想着优化下前端的上报逻辑
    yazinnnn
        10
    yazinnnn  
       55 天前
    @wangxl999999
    10 万用户分钟两次请求也不过 20 万请求, 平均下来 qps 也就不到 4000 啊...
    存到什么地方呢?
    joesonw
        11
    joesonw  
       55 天前 via iPhone
    @wangxl999999 你每 30 秒上传以外的数据临时放本地。

    10 万用户是同时在线吗?不是每时每刻满负载的话,队列存一下,慢慢入库呗。
    documentzhangx66
        12
    documentzhangx66  
       55 天前
    @wangxl999999

    你这请求量:

    1.建议用云 Redis 。

    2.用之前,先问问产品经理,大概的性能。

    3.问下产品经理能否开一台测试的,或者开一台按量计费的,压测一下性能,因为是按量计费,前期脚本准备齐全的情况下,系统部署 + 测试大概半小时能搞定,花不了几块钱。用完后记得把实例删掉,防止继续扣钱。

    4.单台扛不住,用负载均衡。别用云主机做负载均衡,直接问产品经理买云负载均衡。

    5.给你个数据,某省级视频播放系统,每天高峰期大概 5-8w 在线用户,10s 保存一次播放进度,云负载均衡 + 3 台 Redis 平均 CPU 负载 80% 左右。
    RunningRabbit
        13
    RunningRabbit  
    OP
       55 天前
    @yazinnnn 存 mysql 数据库了,分表处理
    RunningRabbit
        14
    RunningRabbit  
    OP
       55 天前
    @wangxl999999 好的,后面使用 redis 负载均衡优化下这块问题
    FrankAdler
        15
    FrankAdler  
       55 天前 via iPhone
    就这点 qps 和数据量 随便一个 mq 都打发了
    swulling
        16
    swulling  
       55 天前 via iPhone   ❤️ 2
    看评论是直接落库了。

    可以写到 redis 里或者写到 mq 里异步消费。

    以你这个量级写到 redis 里最简单
    blankmiss
        17
    blankmiss  
       55 天前
    确实 这种情况得选择 redis 或者 rabbitmq
    yazinnnn
        18
    yazinnnn  
       55 天前
    提供一个从程序上优化的思路, 播放进度只有最新的数据有意义, 把你的进度放到数据流里, 给数据流一个时间窗口, 比如 10 分钟, 10 分钟内每个(uid,vid)最新的进度才去落库
    paopjian
        19
    paopjian  
       55 天前
    视频不是切片了吗,应该是获取切片的时候或者长时间暂停的时候发送进度信息吧,而且可以全扔给 mq,反正不是重要信息
    janus77
        20
    janus77  
       55 天前
    你这个属于后台的问题吧,发到安卓节点有啥用。。。
    RunningRabbit
        21
    RunningRabbit  
    OP
       55 天前
    @janus77 我的问题描述有点跑偏了,想确认前端的上报时机是不是存在可优化的空间
    richard1122
        22
    richard1122  
       55 天前
    “每 30 秒上报一次” 是分布开的吧?
    而不是写了在固定的每分钟的 0 秒和 30 秒上传吧。。
    neptuno
        23
    neptuno  
       55 天前 via iPhone
    @RunningRabbit #8 把用户均分一下,虽然是 30 秒一次,例如 uid 结尾是 1 的就是每分钟第 1 秒和 31 上传,每秒没多少请求的
    RunningRabbit
        24
    RunningRabbit  
    OP
       55 天前
    @swulling
    @blankmiss
    @FrankAdler 这种方案可以解决问题
    yuanchao
        25
    yuanchao  
       55 天前
    放队列里跑就行了,后端接口收到请求后直接塞队列,数据量较大就加消费者就行,我司就是这么干的,支撑了一百多万学生在线上课
    yuanchao
        26
    yuanchao  
       55 天前
    并且我们是 3s 上报一次,当用户产生行为时也会上报(拖动进度,关闭浏览器)
    yufeng0681
        27
    yufeng0681  
       55 天前
    这个视频播放进度的特性不那么重要,不能影响主要业务的接口性能
    1 、建议走其他域名(比如统计行为类的)的服务器进行上报
    2 、redis 定时清掉不再播放的视频进度条数据(存到数据库里去,下次用户上来的详细接口里返回进度条数值)
    shellwen
        28
    shellwen  
       55 天前
    这个一定要上 Redis 之类的,直接写 MySQL 肯定慢
    night98
        29
    night98  
       55 天前
    10 万用户咋可能顶不住,除非你接口直接写数据库,不然随便上个 mq 或者本地队列都不会有问题
    realpg
        30
    realpg  
       55 天前
    服务端用 golang 写,后面 redis ,猴子都能写出单机 4C4G 跑 12 万 QPS ,挂个负载均衡猴子都能写出省资源的百万并发

    现在我的项目,15 万同时在线播放视频用户,视频长度 1 小时每个(教育类),1 秒上报都扛得住
    realpg
        31
    realpg  
       55 天前
    没写完就发出去了
    现在 4C4G*2 跑 25 万用户(单机 4C4G 也没问题,只是为了热更新方便两台前面 SLB ),同时播放一般是 15 万用户左右(课程有时限,一节 40-70 分钟,但是总共开播的窗口就很短的,所以这些用户都得短时间集中看完并发很大)。

    现在的上报机制是默认 1s 上报位置,服务器端每 10 秒钟会后台 routine 计算一下当前负载,如果负载过大的话,就会下发客户端上报时间变为 2s ,如果下 10 秒仍然负载过大,就变为 3s 以此类推,最大间隔 30 秒。而降低的机制是,如果接下来两个 10 秒负载降低到门槛,就会减少 1 秒,最少 1 秒

    实际监控上看,服务器从来没高负载过,累计间隔变为 2s 以上的时候加起来一天不超过 5 分钟,而且更多的时候不是由于自身负载过大,而是进行热更新啊之类的,这时候 cpu 资源被其他进程占用堆起来的
    cassyfar
        32
    cassyfar  
       54 天前
    关键是要用一个消息队列,然后负载均衡到后台一堆实例上写进数据库。这也是大并发分布式系统设计基操。
    RunningRabbit
        33
    RunningRabbit  
    OP
       54 天前
    @yuanchao
    @yufeng0681
    @shellwen
    @night98
    @realpg
    @cassyfar 大佬建议已收到,开搞
    hopingtop
        34
    hopingtop  
       54 天前
    瓶颈 Mysql 写入,核心解决思路,控制 Mysql 写入更新量。

    如果可以容忍最新进度的丢失的容忍性,和粒度放大问题。最低成本的解决方案:
    本地记录最新的时间。拉长上报 最新进度上报时间间隔比如 3 分钟? TPS 约 600 了。
    退出立即记录退出时间。
    客户:异常退出再进来利用本地记录恢复。本地没有取远端最新,导致进度可能不准,但是异常退出量少
    正常退出再进来,利用远端退出时间记录。准确进度

    1.这样改动最少 2 不引入其他额外组件,最低成本
    缺点:统计的粒度不够细。
    work220602
        35
    work220602  
       54 天前
    这不是 10qps 用户该考虑的问题
    uyoungco
        36
    uyoungco  
       52 天前
    Redis 可以完美解决啊
    关于   ·   帮助文档   ·   博客   ·   nftychat   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   实用小工具   ·   1663 人在线   最高记录 5556   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 00:45 · PVG 08:45 · LAX 17:45 · JFK 20:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.