解析大型XML Feed时处理重复数据

时间:2011-04-01 08:28:30

标签: xml feeds polling feedparser stockquotes

我正在编写一个组件,用库存报价解析xml Feed并将结果保存在数据库中。问题相当简单,除了不能逐步读取Feed。也就是说,没有办法指定你只想要X最后一次引用更改,或者只更改比X分钟更新的更改。我知道真正的问题是提要是愚蠢的,提供者应该修复他们的东西,但这不是一个选项。

Feed是一个巨大的xml文件,其中包含提供商的100000个最后股票报价。每分钟对进料进行一次轮询,在此期间有大约50-100个变更的报价。其余的是重复的引号,一次又一次地读取。

在每次调查Feed期间,我会将所有引号(使用lxml)解析为对象。然后,对于每个引用对象,我检查引用是否已存在于数据库中。如果是的话,我会丢弃它,如果没有,我保存它。这个过程非常浪费,因为只有大约0.1%是新数据,其余的是重复数据。为了优化它,我通过查询数据库一次创建查找表,以获取在过去X小时内更新的报价。引号在(last_update,stock_id)键的数据库中是唯一的,因此此优化可将查询数量减少约50%。

但仍然有50k db查询,如果存在或不存在,则必须单独检查每个引用,这对数据库非常重要。

所以我正在寻找的是关于如何更快地使我的feed解析器的想法。也许有一种方法可以将最后一个获取的xml文件与新文件区分开来?

2 个答案:

答案 0 :(得分:1)

Feed中顶部或底部的最新项目是?如果它们位于顶部,那么当您看到已经存在的第一个项目时,您可以停止解析 数据库。

如果最新的项目是最后一次,你可以缓存报价键,只需在内存中查找它们,并在你进入非缓存的数据库后开始点击数据库。或者你可以记住你在数据库中放入的最后一个引用,以及解析你查找它的所有项目,并且仅在数据库中找到它之后的项目。

答案 1 :(得分:1)

您的问题分为两个方面:1)如何避免解析您不需要解析的内容,以及2)如何避免您不需要的数据库操作。

如果引号本身很小,你可能不会从试图解决(1)中获得太多收益。否则,您可以创建一个过滤器(例如,使用XSLT或SAX),它会丢弃您不关心的引号,然后对其余的进行完整的DOM解析。

要解决(2),一般来说,区分XML文件可能会很棘手,因为XML文档中的空白更改(某些提供程序中非常常见)会导致误报,并且您通常需要一些分析实际的内容XML结构,而不是简单的文本逐行diff。如果您认为这对您来说不是一个问题,那么您可以探索几个Stack Overflow主题,但我认为它们还将证明XML差异仍然是一个毛茸茸的领域,特别是在开源领域:

另一种可行的方法是使用本地或分布式内存缓存来快速查找已更新的内容。您可以避免尝试过滤或区分内容,并且如果您正在构建长期基础架构,则可以随时调整缓存基础架构以适应其他用例。 OTOH,创建可扩展的分布式缓存基础架构并不是一个特别便宜的解决方案。