【问题标题】:What is the best way to cache XML feeds locally?在本地缓存 XML 提要的最佳方式是什么?
【发布时间】:2010-08-10 08:58:36
【问题描述】:

我有一个 XML 提要,其中包含 1000 多条物业记录(租金、销售)。

目前我在主页上调用这个提要 16 倍,总是只返回 3 个特定标准的属性,例如 3 个新房子、3 个新公寓等、5 个推荐的房子、5 个推荐的公寓等。

这个场景运行了 7 个月,当时有 200 多个属性,每天只有 100-200 次查看。现在已经到了我每天有 700 多次访问和 1000 多个属性并分别下载 16 个提要的阶段,只是为了显示主页越来越慢,流量越来越大。

因此我想缓存这些流,我只希望我的“机器人”直接从源下载流,所有访问者都使用我的本地副本来加快速度并大量减少流量负载。

我在本地下载 XML 和本地调用文件以显示数据没有问题。但我想知道如何解决可能出现的问题,例如:

  • 不向客户端显示数据,因为机器人正在更新 XML 文件,并且在加载新数据时原始文件将被覆盖并为空
  • 使用 XML 文件作为本地备份,意味着如果源服务器离线,主页仍然可以工作和加载
  • 确保我不会以机器人无法更新文件的方式为客户端锁定数据

我的第一个任务是为每个流使用 2 个 xml 文件,一个将显示给客户端,一个将被下载。如果下载正确,则下载的 XML 将用作实时数据,而其他数据将被删除。一种增量标记,一个文件作为实际数据的文件名。

有什么办法可以缓存这些 XML 文件,让它做类似的事情吗?真正的主要问题是要有防弹解决方案,这样客户就不会看到错误页面或空结果。

谢谢。

【问题讨论】:

    标签: .net xml caching


    【解决方案1】:

    使用 HttpWebResponse 中内置的缓存选项。这允许您以编程方式选择直接从缓存中获取(忽略新鲜度)、忽略缓存、强制刷新缓存、强制重新验证缓存以及使用缓存的正常行为(如果根据原始响应的年龄认为它是新鲜的)信息,并以其他方式重新验证它。

    即使您确实有需要超越的特定缓存要求,也要在正确执行 HTTP 缓存的基础上构建它,而不是完全替代。

    如果您确实需要管理自己的 XML 流缓存,那么正常的文件锁定以及如果确实需要,.NET ReaderWriterLockSlims 应该足以防止不同的线程相互混淆。消除过高争用风险的一种可能性是在缓存争用的情况下默认为直接访问。考虑到缓存最终是一种优化(从概念上讲,您是“从服务器”获取文件,缓存只是使这以更有效的方式发生)。因此,如果您未能快速获得读锁,您可以恢复直接下载。这反过来减少了写锁可能发生的等待(因为在请求写锁时,挂起的锁不会随着时间的推移而堆积)。在实践中,它可能不会经常发生,但它会让您避免围绕一个文件建立不可接受的争用并导致整个系统崩溃的风险。

    【讨论】:

    • 哦,我应该补充一下——因为它在这里可能是相关的——处理普通缓存的另一个选择是增加一个可接受的陈旧程度,例如(“如果它是新鲜的,或者如果您通常认为它已过时但不到 4 小时,请给我这个”)。
    • 是否可以检查文件的实际大小或状态以及缓存/同步是否仅在不同的情况下?
    • 它会,尽管您必须更进一步,因为更改可以(并且在现实生活中经常这样做)导致文件大小相同。您可以存储 WebResponse 获得的文件或 E-tag 的 MD5(如果正在发送 E-tags,后者会更好;如果可能的话,如果不责备运行 Web 端的人,直到它们发送)或最后一个-mod 网络响应上的日期(如果在此系统中不可能进行亚秒级更改)。同样,当您使用适当的选项时,通过适当使用 HttpWebResponse 内置的网络缓存,检查 last-mod 和 etags 会自动发生。
    • (MD5 被认为出于多种目的而损坏,尽管我们只是将其用作类固醇上的 CRC - 意外碰撞的风险要低得多 - 而不是出于安全目的,所以这些反对意见不'不适用于此处)。
    • 数据缓存在哪里?它可以重新启动吗?如果我从远程服务器收到(200 以外的)响应,是否会清除缓存?
    【解决方案2】:

    我将首先假设您不拥有生成源 XML 提要的代码?因为如果你这样做,我会考虑为你想要运行的查询添加一些特定的支持。

    我在使用第三方提要时遇到了类似的问题,我构建了一个每天运行几次的作业,下载提要并对其进行解析,并将结果本地存储在数据库中。

    每次更新数据库时都需要进行一些比较,并且只添加新记录并删除旧记录,但这可以确保您始终有数据可以提供给您的客户,并且数据库可以解决文件等简单问题锁定。

    然后我会看一个简单的服务层来公开本地存储中的数据。

    【讨论】:

    • 比在数据库中进行比较更简单的只是拥有一个在更新时自动更新的版本列。然后,您可以将它用于最后修改的值(如果它是数据时间并且单秒分辨率足以满足您的应用程序)和/或创建电子标签(使用更高分辨率的日期时间,以及更改计数适用于更新之间的任何时差)。
    • 不,我无权访问原始 XML 馈送代码。我有一个结构,需要使用它。我正在考虑每 5 分钟缓存一次,因为数据波动很大。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多