搜狐视频P2P技术揭秘 - 分享率控制篇

《搜狐视频P2P技术揭秘 - 架构篇》中指出播放器P2P客户端的一个重要任务就是寻找一个兼顾流畅率和分享率的平衡点,本文将介绍搜狐视频P2P客户端使用的方法。

1 业务决定控制逻辑

一个完整的播放器APP至少有以下两个基本功能:

  • 播放;
  • 下载。

实际上这两个业务功能定义还不够细,播放可以分为在线播放和离线播放,下载根据播放器逻辑又可以分为普通下载和预加载。

  • 播放:
    • 在线播放:直接播放来自网络的媒体文件;
    • 离线播放:播放已经下载到本地的媒体文件;
  • 下载
    • 普通下载:用户直接发起的下载请求;
    • 预加载:预先加载当前播放分段的后续若干分段。

对不同的业务来说,流畅率和分享率的优先级有所不同。

业务分享率流畅率下载速度
在线播放
普通下载
预加载

流畅率又体现为上报给播放器的有序数据的速度稳定性,流畅率和分享率的冲突,往往就是使用P2P和CDN两个通道的冲突。主要体现在:

  • P2P的Peer质量参差不齐,使用UDP协议,有比较高的几率出现丢包、抖动、乱序,导致上报播放器的有序数据的速度不稳定,也就是流畅率不足;
  • P2P的Peer数量可能不足,导致下载速度不够,需要CDN的弥补,两个通道的切换、同时使用的逻辑需要比较好的控制,否则可能导致流畅率不足。

在在线播放业务中,首开时间、流畅度直接影响用户体验,因此分享率的重要性降低,但是并不会太低,当缓冲的数据足够后,应尽可能使用P2P。至于缓冲的数据来自CDN还是P2P,根据不同的前提有不同的策略,假设CDN的部署足够好,那么CDN下载是最优选择,首开的前几秒数据应该优先从CDN下载。但是也有例外,CDN的带宽往往是比较昂贵的,一些小运营商可能会提供免费的CDN,但质量就无法保证,这个时候就需要权衡。移动P2P的一个可选策略是同时从CDN和P2P两个通道下载前几秒的数据,一旦数据缓冲完成,则根据CDN和P2P的当前质量对比,切换到合适的通道。

在普通下载业务中,下载速度和分享率优先级比较高,数据的有序性并不重要。但是既然是下载速度优先,那么最终主要使用P2P还是使用CDN决定于Peer的数量和质量,如果Peer不足,质量不佳,那么速度不足的时候仍然要切换到CDN。

预加载业务对用户来说是不可见的,可以在播放到当前分段末尾若干时间的时候开始,这个时候应该以P2P为主,速度和流畅率优先级降低。

2 搜狐影音/搜狐视频

搜狐影音(Windows)和搜狐视频(移动端)都实现了基于P2P的在线播放和离线下载业务,但是搜狐影音P2P的分享率比搜狐视频高,主要原因是:

  • 搜狐影音在PC端,机器性能、网络环境整体更好;
  • 搜狐影音开启了P2P的预加载,预加载的分段基本都使用P2P下载;
  • 搜狐影音开启了P2P的本地缓存,已经播放过的视频被缓存到本地,再次播放时将直接加载本地缓存,而本次播放的数据被统计到P2P通道中。

除了以上差异,两者的P2P实现没有本质的区别,尤其是在分享率控制的算法实现。

算法思想:用有限状态机来描述一次业务调用中P2P、CDN状态的切换。一个状态的输入是当前P2P、CDN的各种参数,包括P2P下载速度、CDN下载速度、P2P Peer数、当前上报连续数据的速度、已经上报的数据量、文件的码率等,通过一定的逻辑来计算下一个状态是P2P还是CDN。在任务开始时,针对不同的业务创建不同的状态机,例如,为在线播放业务创建紧急状态机,为下载业务创建下载状态机,为预加载业务创建预加载状态机,根据状态机的当前状态来判断下载任务应该分发给P2P Peer还是CDN。

2.1 状态定义

typedef enum state {
0:初始状态;
1:P2P状态;
2:CDN状态;
3:P2P+CDN组合状态;
} state;

2.2 输入事件

typedef struct event {
0:当前P2P速度;
1:当前CDN速度;
2:连续上报播放器的速度;
3:已经上报播放器的数据量;
4:已经上报播放器的数据比例;
5:已经上报播放器的时间;
6:视频文件的码率;
7:活跃种子数; 
8:播放器已经缓存的视频时长;
9:播放准备时间(广告时间);
10:本状态已经维持的时间;
……
} event;

2.3 状态转换

由于有4个状态,因此有以下几个状态转换动作:

  • on_state_init(in event),在初始状态下执行;
  • on_state_p2p(in event),在P2P状态下执行;
  • on_state_cdn(in event),在CDN状态下执行;
  • on_state_p2p_cdn(in event),在P2P+CDN混合状态下执行;

在这些状态转换动作中,根据状态机类型、输入事件参数、当前状态来决定下一个状态:

  • 从初始状态可能进入P2P状态、CDN状态或P2P+CDN 状态;
  • 从P2P状态可能进入CDN或P2P+CDN状态;
  • 从CDN状态可能进入P2P状态或P2P+CDN状态;
  • 从P2P+CDN状态可能进入P2P状态或者CDN状态。

2.4 转换逻辑

不同状态机的区别主要体现在初始状态以及状态转换逻辑。

举个例子,在线播放业务的紧急状态机下,初始状态可能是CDN,如果上报的数据量已经超过了播放器的缓冲若干秒,并且P2P打通的活跃Peer数超过一定的阈值,那么会切换到P2P+CDN混合状态,在混合状态下,如果P2P的速度超过一定的阈值,就会切到纯P2P状态,否则如果P2P的速度不足,Peer质量也不佳,那么会切换到纯CDN状态……

这些用到的所有阈值都是从Navigation服务获取的,从数据层面得到了一定的灵活性。后来,我们发现转换逻辑也可能需要动态调整,因此把状态机的实现放到lua脚本中,脚本部署在服务端,这样转换逻辑的实现就更灵活。

状态机脚本的更新依赖于统计数据,P2P的每次请求都会上报一次请求中的各种数据,主要包括状态切换的输入、输出,后台分析脚本将分析状态切换的详细数据并进行统计,根据统计的数据,可以分析出目前的状态转换逻辑的问题,形成一个反馈闭环。

3 Flash 播放器/H5 播放器

页面的播放器主要负责在线播放业务,并没有下载业务,因此P2P、CDN的切换逻辑比较简单。

首开的几秒数据从CDN下载,然后设置一个缓冲,播放过程中,当缓冲中的数据不足时主要由CDN来快速填充,缓冲时间外的数据则主要由P2P来下载。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页