最佳实践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所有相关信息。