2009-11-13 63 views
3

我目前正在编写一个web爬虫(使用python框架scrapy)。
最近我不得不实现一个暂停/恢复系统。
我实施的解决方案是最简单的方法,基本上,它们在计划时存储链接,并在它们实际存在时将其标记为“已处理”。
因此,当恢复蜘蛛时,我能够获取这些链接(显然,存储的内容比只包含URL,深度值,链接所属的域等等要多一些),至今一切正常好。存储爬虫状态的最优化方式?

现在,我刚刚使用了一个mysql表来处理这些存储操作,主要是为了快速建立原型。

现在我想知道如何优化这个,因为我认为数据库不应该是唯一可用的选项。通过优化,我的意思是,使用一个非常简单和轻的系统,同时仍然能够处理大量的短时间内写入的数据。

现在,它应该能够处理几十个域的抓取,这意味着存储几千链接第二...

预先感谢建议

回答

3

坚持事物的最快方式通常是将它们附加到日志中 - 这种完全顺序的访问模式可以最大限度地减少磁盘搜寻,这通常是存储时间成本的最大部分。重新启动后,您将重新读取日志并重新构建您正在构建的内存结构,因为您首先追加到日志中。

您的具体应用程序可能会进一步优化,因为它不一定需要100%的可靠性 - 如果因为突然崩溃而错过了几条记录,那么您只需再次爬行即可。所以,你的日志文件可以被缓冲,并且不需要被fsync所迷惑。

我想象的搜索结构也会适合内存的舒适(如果只有几十个网站,你可能只需要保留一组网站,不需要布隆过滤器或任何幻想) - 如果它没有't,你可能不得不在内存中保存一组最近的条目,并且周期性地将该集合转储到磁盘(例如,将所有条目合并成一个Berkeley DB文件)。但我并没有深入讨论这些选项的细节,因为它没有出现,你会需要它们。

+0

数十个网站并行抓取,但我需要保留过去完成的每个抓取作业的跟踪,我猜 – Sylvain 2009-11-13 16:07:05

+0

也是如果顺序写入文件,将如何我'下载链接'链接? – Sylvain 2009-11-13 18:51:29

+0

@Sylvain,那么你肯定需要定期将内存后备“set”转储为更持久的查找形式 - 而Berkeley DB可能会或可能不会顺利地扩展到数百万或数十亿...你会需要进行基准测试,但是我怀疑PostgreSQL(或者一些雄心勃勃的非关系密钥/价值商店,但除了Google自己的Bigtable之外,我几乎没有经验),如果您的规模足够大,这的确是您最好的方法。关键的一点是,您无需一直更新该数据库 - 使用内存和日志可以使数据库更新“仅需一次”! – 2009-11-13 18:54:19

1

有2009 PYCON谈话,你可能会觉得有趣,Precise state recovery and restart for data-analysis applications由比尔·格里布尔。

保存应用程序状态的另一种快速方法是使用pickle将应用程序状态序列化到磁盘。

+0

我很确定咸菜不能用,因为有些对象(来自扭曲的库)。感谢您的链接,我会尝试尽快看看它。 – Sylvain 2009-11-13 20:34:02

+0

终于花了一些时间来看看谈话。很有意思。然而,我认为这有点超出我的简单需求:-) – Sylvain 2009-11-16 11:11:47