基于linux和php的稳定的分布式数据采集架构
数据采集对于一些网站至关重要,在开发这种采集程序时会遇到如下一些问题:
一、单进程采集慢,采集任务的间隔时间无法控制。
二、数据下载部分和分析部分不分离导致可移植性不强,调试困难。
三、采集程序受机器性能瓶颈和网速瓶颈限制。
四、遭受数据源的封锁。
等等。。。。
这就要求采集程序必须足够智能化,有如下几点要求:
一、可以多机器分布运行,以适应大量数据的采集。
二、能够多并发采集,使采集任务的运行周期可控。
三、下载程序和分析程序分离,不仅是程序上的分离,也需要机器上的分离。
四、能够很容易的加入新的采集任务,很容易的调试。
五、对采集页面内容的分析能够模糊匹配。
六、下载时能够调用代理。
七、长期自动维护一个有效的代理列表
经过几次大的改动,我现在设计的基于linux和php的采集程序架构如下:
Snatch(主目录)
|-Lib(类库、函数、配置的目录)
| |-Config.inc.php(主程序变量配置)
| |-OtherConfig.inc.php(其他配置文件若干)
| |-Functions.inc.php(函数文件若干)
| |-Classes.inc.php(类库文件若干)
| |-ClassLocalDB.inc.php(连接本地数据库的操作类)
| |-ClassRemoteDB.inc.php(连接远程数据库的操作类)
| |-ClassLog.inc.php(写下载分析的日志)
|-Paser(分析器程序目录)
| |-WebSite1(针对WebSite1的分析程序目录)
| | |-WebSite1Paser1.php(针对WebSite1的分析程序1)
| | |-WebSite1Paser2.php(针对WebSite1的分析程序2)
| |-WebSite2(针对WebSite2的分析程序目录)
| |-ProxyWebSite1(分析代理服务器列表的站点1,取得代理服务器地址并入库)
| |-ProxyWebSite2(分析代理服务器列表的站点2,取得代理服务器地址并入库)
| |-... ...
|-Log(日志目录)
| |-WebSite1.log(WebSite1的下载及数据分析日志)
| |-WebSite2.log(WebSite2的下载及数据分析日志)
| |-... ...
|-Files(下载后的文件保存目录)
|-Main.php(主入口程序,分配下载任务)
|-Assign.php(取得下载任务,分配给Down.php执行)
|-Down.php(进行下载并将下载保存的文件调出来分析)
|-DelOvertimeData.php(清除很老的下载文件)
|-ErrorNotice.php(监控下载程序,在其出错时发信通知相关人)
|-Proxy.php(校验数据库中的代理列表,分析其有效性及连接速度)
|-Fork(钩子程序,使下载和分析并发)
|-Main.sh(封装Main.php,使其在shell下运行不出现包含路径错误)
|-Assign.sh(封装Assign.php)
|-DelOvertimeData.sh(封装DelOvertimeData.php)
|-ErrorNotice.sh(封装ErrorNotice.php)
|-Proxy.sh(封装Proxy.php)
本地数据库表结构如下(简单介绍):
DownloadList表:ID
int(10) unsigned NOT NULL auto_increment, 自增IDParentID
int(11) NOT NULL default '0', 父ID,也就是该记录由哪个下载记录衍生来的SiteName
char(32) NOT NULL default '', 采集网站的名称或代号LocalServerName
char(32) NOT NULL default '', 该采集任务由本地若干台机器里的哪一台来完成URL
char(255) NOT NULL default '', 需要下载的数据页地址FileName
char(64) NOT NULL default '', 下载后保存的文件名FileSize
int(11) NOT NULL default '0', 下载后文件的大小Handler
char(64) NOT NULL default '', 分析器的php文件路径,如./Paser/WebSite1/Paser1.phpStatus
enum('Wait','Download','Doing','Done','Dead') NOT NULL default 'Wait', 该任务的状态ProxyID
int(11) NOT NULL default '0', 该任务使用的代理ID,为0则不使用代理下载Remark
char(100) NOT NULL default '', 备注字段WaitAddTime
datetime NOT NULL default '0000-00-00 00:00:00', 记录加入进行等待的时间DownloadAddTime
datetime NOT NULL default '0000-00-00 00:00:00', 记录开始下载的时间DoingAddTime
datetime NOT NULL default '0000-00-00 00:00:00', 记录开始分析的时间DoneAddTime
datetime NOT NULL default '0000-00-00 00:00:00', 记录完成的时间
ProxyList表:ID
int(11) NOT NULL auto_increment, 自增IDProxy
char(30) NOT NULL default '', 代理地址,如: 127.0.0.1:8080Status
enum('Bad','Good','Perfect') NOT NULL default 'Bad', 该代理状态SocketTime
float NOT NULL default '3', 本地连接该代理socket时间UsedCount
int(11) NOT NULL default '0', 被使用的次数AddTime
datetime NOT NULL default '0000-00-00 00:00:00', 代理被加入列表的时间LastTime
datetime NOT NULL default '0000-00-00 00:00:00', 代理被最后一次验证的时间
其它相关表:(略)
介绍几个文件(只介绍,不贴代码):
一、Main.php
close();
?>
二、Assign.php
/dev/null";
}
$LocalDB->close();
?>
三、Down.php
四、Proxy.php (维护有效的代理列表)
方法有两种:
1、对代理地址的代理端口进行socket连接。设定连接超时为3秒(3秒仍旧连不上的代理就别要了)
如果连接上了,计算连接时间,并更新该代理记录的数据SocketTime字段,判断其Status是Bad, Good,还是Perfect
2、对于非Bad的代理,进行下载文件的实验,如果没使用代理下载的文件和使用代理下载的文件一样,则该代理真实有效。
程序略
多台机器分布式采集:
只有一台运行Main.sh,2分钟运行一次。
其他机器运行Assign.sh,1分钟一次,Assign.php会根据DownloadList表里的LocalServerName字段来取回任务并完成它。
LocalServerName值由Main.php加载采集任务时分配。这个也可以根据各采集机器负载情况来自动调整。
日志:
采集分析的日志写如Log目录,以便方便的查看到是否采集到数据,分析程序是否有效,在出现错误时也可以找到错误的可能地点和时间。
有点复杂,我只写了大体思路,页面分析部分没有涉及,但是也非常重要。
后台管理也没谈。
架起来之后很爽,只要你采集的机器多,建一个qihoo没问题。
我给以前公司做的采集就是这个架构,采集sina, tom, 163等等一共143个频道的内容。
对某几个网站收费数据的精确采集和分析也用的这个(当然,需要模拟登录)。
还是相当稳定的
评论 (0)