【问题标题】:handling large datasets in web api & odata在 web api 和 odata 中处理大型数据集
【发布时间】:2012-07-21 01:54:18
【问题描述】:

最近几周我一直在使用 asp.net web api 并取得了巨大的成功。它确实帮助我为移动客户端生成了一个界面,以便通过 http 进行编程。

我到了需要帮助的地步。

我有一个新的端点,它可以是一个数据库并且可以返回 100K 的结果。我正在使用 OData 过滤数据并返回一组分页数据。

由于多个请求可能会发生这种情况,我关心的是性能。每次从数据库中返回 100K 记录并不理想。所以我有一些想法。

第一个是缓存 100K 结果,并让 OData 每次都在这方面发挥作用。我正在使用 AppFabric 分布式缓存作为其负载平衡环境。但是,在 AppFabric 中缓存如此多的数据可能会导致内存复杂化,因此我认为最好避免这种情况。

下一个选项是忘记 OData 的魔力,将我使用的过滤器发送到数据库,每次只返回所需的数据。所以换句话说,每次都击中数据库。

我可以考虑使用类似于本文中概述的版本的缓存处理程序来缓存在 http 缓存中 -> http://byterot.blogspot.ie/2012/06/aspnet-web-api-caching-handler.html 这样做的缺点是,如果数据通过另一个可能的系统进行更新,缓存的数据是没有过期。

关于如何处理这种情况,大量数据,使用 odata 和 web api 过滤的任何其他提示?

【问题讨论】:

  • 你最终选择了哪条路线?我倾向于在数据库上运行它而不是缓存,并将 $skip 和 $top 映射到 SQL server 2012 上的动态 SQL、“OFFSET”和“FETCH”调用,到 sql server 上的视图/表值函数.这样做的一个副作用是,当客户端发出后续的 $skip 和 $top 调用时,如果在流中插入记录,它可能会关闭分页。此外,每个后续的寻呼调用都意味着使用服务重新进行身份验证(开销),但这就是无状态 HTTP 的本质!

标签: c# asp.net rest odata asp.net-web-api


【解决方案1】:

假设您使用实体框架,最好直接返回 EF 的 IQueryable。这样,OData 的魔力将直接作用于您的数据库。 $limit 和 $take 将直接映射到您的 SQL 查询。

【讨论】:

  • 我有一个分层架构,因此 odata 参数不会针对 ado.net 的数据层层执行。不过感谢您提供的信息,很高兴知道。
  • 如果您使用 WCF 数据服务来公开您的 OData 服务,无论如何它已经需要 IQueryable。那么,如果您不对数据存储运行查询(IQueryable 上的查询将包含所有过滤器等),您将如何实现这一点。如果您使用的是 Web API,我认为它也适用于 IQueryable,因此同样适用于那里。
  • 根据我的经验,EF 为此类用例创建的开销导致性能不佳。我建议分析代码并查看使用 EF 和不使用 EF 的性能数字。 IQueryable 的 EF 魔法是有代价的!​​span>
【解决方案2】:

最好的方法是使用您已经在使用的分布式缓存。但是您正在使用的缓存提供程序,即 AppFabric,有一些限制。限制是指功能限制。查看 NCache,它是一个成熟且功能丰富的第三方分布式缓存提供程序。

如果您想了解 NCache 和 Appfabric 的区别,请查看下面的 youtube 链接,仅供参考....

http://www.youtube.com/watch?v=3CPi1QlskrU

【讨论】:

    【解决方案3】:

    这个问题可能会导致各种各样的答案。也就是说,让我戴上 MSFT 之前的帽子,给你两分钱。

    顾问的回答是“视情况而定”,可以很好地回答很多架构问题。答案取决于您的具体情况。一些开发人员在缓存层方面存在问题,因为还有其他事情需要考虑。符合 ACID 的数据库为您购买了很多保险,即您至少具有非常有限的最终一致性。

    如果是我做这个决定,我会考虑几件事:

    • 我要定期返回多少行?
    • 它们是否一遍又一遍地使用相同的行?
    • 内存有多大? (100k 确实不是那么多行;您不希望这 100k 行每次都进入磁盘是正确的,但是将它们全部保存在内存中可能不是问题;SQL Server 可能会为您执行此操作。)
    • 我愿意处理什么问题:最终一致性?我需要其他软件来处理它吗? (人们经常对缓存感到害怕的是确保失效和插入能够从不同的应用程序/应用程序的不同位置正确且一致地完成。)

    鉴于您已经提供的信息(分层架构、尝试分布式缓存的意愿),我认为您应该追求缓存层。那里有很多很好的缓存。在我在 Microsoft 工作之前,AppFabric 为我们工作得很好,但我也处理过各种其他缓存层。

    【讨论】:

      【解决方案4】:

      我在博客http://byterot.blogspot.ie/2012/06/aspnet-web-api-caching-handler.html 中指出的缓存适用于HTTP 缓存,也称为输出缓存。 其实数据本身并不是缓存在服务器上,而是在客户端或者中游缓存服务器上,所以并不适合你的想法。

      【讨论】:

        猜你喜欢
        • 2016-12-12
        • 1970-01-01
        • 2023-04-02
        • 2017-09-24
        • 2019-12-27
        • 1970-01-01
        相关资源
        最近更新 更多