Linux运维最佳实践
上QQ阅读APP看书,第一时间看更新

最佳实践12:实践视频点播CDN

视频点播CDN系统概述

Woyo视频CDN系统基于Linux系统。基本属性如下。

·以Lighttpd作为FLV请求服务器。

·以Tokyo Cabinet作为HASH表数据库。

·以Python、Perl开发各类控制模块。

本系统主要面向Woyo网的视频CDN分发与访问需求而开发,因此针对性较强。该系统具有以下特点。

·实现未完全加载视频的即时拖动功能。

·实现跨IDC的缓存资源共享。

·主动式同步与删除,根据视频文件访问量决定缓存位置和缓存次数。

·对缓存服务器的空间与流量可控。

·提供源站文件存储的扩展性。

·提高节点缓存服务器的空间利用率。

·方便实现防盗链。

系统模块分类

根据本CDN系统的服务器类型,将整套系统分为4大模块(不考虑DNS解析等常规的CDN组件)。

·同步源站服务器。它的功能是提供所有的视频文件下载,仅提供给缓存服务器作文件同步。

·视频源站服务器。当缓存服务器上不存在用户所需视频文件时,将访问源站服务器。根据存储目录分布服务器挂载点,支持视频拖动。

·视频转发服务器。它的功能是提供某一节点的URL分发服务,根据数据库信息决定URL转向目标。

·缓存服务器。分布于各个节点,由视频转发服务器决定缓存内容,它同时支持视频拖动。

用户访问流程

用户访问某个URL的视频点播文件的流程如图2-3所示。

图2-3 视频点播CDN用户访问流程图

同步源站服务器

1)服务列表:

·Lighttpd提供给各节点服务器的文件下载。

·Woyoflv.py提供给各节点服务器下载文件的md5值。

2)服务器用途:

当请求格式为以下时,下载原始文件:

http://xxx.xxx.xxx.xxx/v2/video/1/000/327/021/200810/200810201828327021P0viOc.flv

当请求格式为以下时,先将URL解析为实际路径,然后返回文件的md5值:

http://xxx.xxx.xxx.xxx/hash/v1.woyo.com/video1--c6f3d45b8dac7ce0855bbf1e200810225320317887o5ZL8C.flv

结果类似于:

v1/video/1/000/317/887/200810/200810225320317887o5ZL8C.flv
7ce1e9bfffb0d737914d9a0af8be2d8c4a477dba

3)存储方式:挂载主存储所有视频分区(NAS)。

10.29.21.2:/vol/video1 on /var/www/woyo/v1/video/1 type nfs (rw,addr=10.29.21.2)
10.29.21.1:/vol/video2 on /var/www/woyo/v2/video/1 type nfs (rw,addr=10.29.21.1)
10.29.21.2:/vol/video3 on /var/www/woyo/v3/video/1 type nfs (rw,addr=10.29.21.2)

4)配置:在lighttpd.conf中加载以下模块。

"mod_rewrite",
"mod_proxy_core",
"mod_proxy_backend_fastcgi",

获得文件md5值:

$HTTP["url"] =~ "^/hash/" {
allow-x-send-file = "enable"
proxy-core.balancer = "round-robin"
proxy-core.protocol = "fastcgi"
proxy-core.backends = ( "unix:/usr/local/lighttpd/log/py.sock")
proxy-core.max-pool-size = 5
}

启动fastcgi daemon:

./spawn-fcgi -s /usr/local/lighttpd/log/py.sock -u nobody -g nobody -- woyoflv.py

视频源站服务器

1)服务列表:

·Lighttpd:提供视频文件的下载。

·rewrite.pl:提供用户访问的URL到实际存储位置的重写转换。

·404.cgi:视频文件不存在时的广告跳转。

2)服务器用途:提供视频文件的用户访问。

3)存储方式

·SAN架构,iSCSI方式挂载存储至本地。

·提供相应目录下的视频文件访问。

·不同存储间文件做即时同步(另外的同步系统)。

4)配置:在配置文件lighttpd.conf中加载以下模块。

"mod_rewrite",
"mod_cgi",
"mod_flv_streaming",

支持视频拖动:

flv-streaming.extensions = ( ".flv" )

将请求URL rewrite为实际路径:

include_shell "/usr/local/lighttpd/conf/rewrite.pl"

若文件不存在,指向广告视频:

server.error-handler-404 = "/404.cgi"
cgi.assign = ( ".cgi" => "/usr/bin/perl")

注意:此404.cgi用Perl写,与缓存服务器的404.cgi作用不同。

视频转发服务器

1)服务列表:

·Nginx:接收用户对视频的URL请求,转发到实际进行视频文件判断的程序url302.py。

·Ttserver:存储视频文件的缓存信息条目。

·url302.py(daemon port:8080):根据文件缓存情况返回不同的访问地址(如视频文件未被缓存时跳转到源站、视频文件缓存后跳转到边缘节点等)。

·checking.py(daemon):维护服务器信息和视频文件缓存信息。

·listswap.py(daemon port:8088):维护各缓存服务器的访问。

2)服务器用途:

·所有视频请求都先指到本服务器。

·Nginx将相应域名的请求(v1 v2 v3…)转发至本地8080端口。

·由url302.py根据请求URL,获取并更新数据库中的URL信息后返回302,重定向至源站或者缓存或者广告的地址。URL的相应信息由ttserver获得(ttserver和另外一台服务器配置同步镜像)。

·Checking.py这个进程定时检查各个服务器状态,根据服务器状态更新当前服务器列表。同时,该进程定时检查数据库内URL的状态,生成需缓存的文件列表和需删除的文件列表。

·将列表同步至listswap.py进程。

·listswap.py提供各缓存服务器的访问,返回各服务器需同步和删除的文件列表。

3)配置:在配置文件nginx.conf中增加以下内容。

upstream url302 {
server 10.252.3.1:8080;
}
server {
listen 80;
server_name v1.woyo.com v2.woyo.com v3.woyo.com;
access_log logs/access.log main;
location ~ .*\.flv {
valid_referers none blocked *.woyo.com;
if ($invalid_referer) {
rewrite ^/(.*) http://err.woyo.com/$1;
}
proxy_pass http://url302;
}
location ~ .*\.xml {
root /dev/shm/;
}
location / {
rewrite ^/(.*) http://err.woyo.com/$1;
}
}

url302.conf:

name = 'lnsy1'
host = '10.252.3.1'
port = 8080
check_port = 8088
memdb = (('10.252.3.1', 11211),
('10.252.3.2', 11211))
basedir = '/usr/local/url302/'
url302_logfile = 'log/access.log'
url302_pidfile = 'run/url302.pid'
listswap_logfile = 'log/listswap.log'
listswap_pidfile = 'run/listswap.pid'
checking_logfile = 'log/checking.log'
checking_pidfile = 'run/checking.pid'
errorhost = 'err.woyo.com'
errorurl = '/url302.flv'
expire_time = 86400 #过期时间
click_time = 2 #访问超过%s 后即缓存
source_server = (('v1.woyo.com' , '125.76.236.107'),
('v1.woyo.com' , '125.76.236.110'),
('v2.woyo.com' , '125.76.236.108'),
('v2.woyo.com' , '125.76.236.111'),
('v3.woyo.com' , '125.76.236.109'),
('v3.woyo.com' , '125.76.236.112'))
cache_server = (('218.60.34.247', 'cache1:4096'),
('218.60.34.247', 'cache2:4096'),
('218.60.34.247', 'cache3:4096'),
('218.60.34.247', 'cache4:4096'),
('218.60.34.248', 'cache1:4096'),
('218.60.34.248', 'cache2:4096'),
('218.60.34.248', 'cache3:4096'),
('218.60.34.248', 'cache4:4096'),
('218.60.34.249', 'cache1:4096'),
('218.60.34.249', 'cache2:4096'),
('218.60.34.249', 'cache3:4096'),
('218.60.34.249', 'cache4:4096') )

4)缓存算法:

·url302.py在每次URL请求时,将该click值增1,time值更新至当前时间。

·url302.py获得URL请求后,首先判断URL是否合法,然后查询数据库信息,若存在location值,则301重定向至Location值所示的服务器和缓存目录;否则302重定向至源站的随机服务器。

·checking.py进行健康检查时,若在线服务器列表发生变化,则修改数据库内容,并请求url302.py监听端口发出指令,强制其更新列表。

·checking.py遍历数据库,分析每一条URL的相关信息。算法如图2-4所示。

图2-4 URL缓存信息检查算法

·checking.py将生成的缓存和删除列表发送给listswap.py进程。

·生成缓存列表时,根据URL_HASH,参考各台缓存服务器的磁盘空间来决定缓存位置。

缓存服务器

1)服务列表:

·Lighttpd:提供视频文件的用户访问。

·rewrite.pl:提供用户访问的URL的重写功能。

·404.cgi:用户访问视频不存在时重定向到广告视频。

·Syncing.py:从节点控制服务器的listswap.py进程中获取更新列表,从源站同步或者删除本地文件。

2)服务器用途:

·提供视频文件的用户访问。

·由syncing.py进程从节点控制服务器的listswap.py进程中获取更新列表,从源站同步或者删除本地文件。

3)存储方式:本地磁盘,不做raid,分别mount在Web root下的cache1、cache2...目录下。

4)配置:在Lighttpd.conf中加载以下模块。

"mod_rewrite",
"mod_cgi",
"mod_flv_streaming",

支持视频拖动:

flv-streaming.extensions = ( ".flv" )

将请求URL rewrite为实际路径:

include_shell "/usr/local/lighttpd/conf/rewrite.pl"

若文件不存在,指向广告视频:

server.error-handler-404 = "/404.cgi"
cgi.assign = ( ".cgi" => "/usr/bin/python")

注意:此404.cgi用Python写,与源站服务器的404.cgi作用不同。

Syncing.conf:

source_host = '125.76.236.26'
node_host = '10.252.3.1'
node_port = 8088
local_ip = '218.60.34.248'
memdb = (('10.252.3.1', 11211),
('10.252.3.2', 11211))
root_dir = '/var/www/flv/'
base_dir = '/usr/local/syncing/'
pid_file = 'pid'
log_file = 'log'

5)同步流程:

①从节点控制服务器listswap.py上获取更新列表。

②加上/hash/控制符,获得所有文件的md5值。若文件不存在,则返回no_file。

③若返回no_file时,设置数据库的Location值为广告视频地址。

④对于需缓存视频,根据返回的实际路径,从源站下载视频到本地,然后计算本地文件的md5值。若正常下载完全,则更新数据库的Location值为本地IP和相应目录。

⑤对于需删除视频,根据返回的实际路径删除文件,而后删除数据库内该URL所有相关信息。