Loading... # [基于linux和php的稳定的分布式数据采集架构](https://blog.p2hp.com/archives/1427) 数据采集对于一些网站至关重要,在开发这种采集程序时会遇到如下一些问题: 一、单进程采集慢,采集任务的间隔时间无法控制。 二、数据下载部分和分析部分不分离导致可移植性不强,调试困难。 三、采集程序受机器性能瓶颈和网速瓶颈限制。 四、遭受数据源的封锁。 等等。。。。 这就要求采集程序必须足够智能化,有如下几点要求: 一、可以多机器分布运行,以适应大量数据的采集。 二、能够多并发采集,使采集任务的运行周期可控。 三、下载程序和分析程序分离,不仅是程序上的分离,也需要机器上的分离。 四、能够很容易的加入新的采集任务,很容易的调试。 五、对采集页面内容的分析能够模糊匹配。 六、下载时能够调用代理。 七、长期自动维护一个有效的代理列表 经过几次大的改动,我现在设计的基于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, 自增ID `ParentID` 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.php `Status` 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, 自增ID `Proxy` char(30) NOT NULL default '', 代理地址,如: 127.0.0.1:8080 `Status` 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个频道的内容。 对某几个网站收费数据的精确采集和分析也用的这个(当然,需要模拟登录)。 还是相当稳定的 最后修改:2023 年 08 月 07 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏