C# 在web api中处理大型数据集&;奥达塔

C# 在web api中处理大型数据集&;奥达塔,c#,asp.net,rest,odata,asp.net-web-api,C#,Asp.net,Rest,Odata,Asp.net Web Api,最近几周,我一直在使用asp.net web api,并取得了巨大成功。它真的帮助我为移动客户端制作了一个接口,可以通过http进行编程 我到了需要帮助的地步 我有一个新的端点,它可以创建一个数据库,可以返回100K个结果。我使用OData过滤数据并返回一组分页的数据 由于这种情况可能发生在多个请求中,因此我关心性能。每次从数据库返回100K条记录并不理想。所以我有一些想法 第一个是缓存100K的结果,让OData每次都在这上面发挥它的魔力。我正在使用AppFabric分布式缓存作为负载平衡环境

最近几周,我一直在使用asp.net web api,并取得了巨大成功。它真的帮助我为移动客户端制作了一个接口,可以通过http进行编程

我到了需要帮助的地步

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

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

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

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

我可以考虑使用本文中概述的缓存处理程序在http缓存中进行缓存->缺点是,如果数据通过另一个系统进行更新,那么缓存的数据不会过期


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

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

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

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


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

很多架构问题最好用顾问的答案来回答:“这取决于情况。”在您的案例中,答案取决于一些具体的事情。一些开发人员在缓存层时遇到问题,因为还有其他事情需要考虑。一个符合ACID的数据库为您带来了很多保险,您至少有一个非常有限的最终一致性

如果是我做出这个决定,我会考虑以下几点:

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

考虑到您已经提供的信息(分层体系结构,愿意尝试分布式缓存),我认为您应该采用缓存层。那里有很多好的储藏室。在我加入微软之前,AppFabric对我们来说工作得很好,但我也处理过各种其他缓存层。

我在博客中指出的缓存适用于HTTP缓存,也称为输出缓存。实际上,数据本身不是缓存在服务器上,而是缓存在客户机或中流缓存服务器上,因此不适合您的想法。

我有一个分层体系结构,因此odata参数不会针对数据层(即ado.net)执行。不过,感谢您提供的信息,很高兴知道。如果您使用WCF数据服务公开OData服务,则无论如何都需要IQueryable。那么,如果不对数据存储运行查询(iQueryTable上的查询将包含所有过滤器等),如何实现这一点呢。如果您使用的是Web API,我认为这也适用于IQueryable,因此同样的情况也应该适用于IQueryable。根据我的经验,EF为此类用例创建的开销导致性能不佳。我建议对代码进行分析,并查看带有EF和不带EF的性能数字。IQueryable的EF魔法是有代价的!你最终选择了哪条路线?我倾向于在DB上运行它,而不是缓存,并将$skip和$top映射到SQL server 2012上的动态SQL、“OFFSET”和“FETCH”调用,或者映射到SQL server上的视图/表值函数。这样做的一个副作用是,当客户端发出后续的$skip和$top调用时,如果在流中间插入记录,它可能会关闭分页。此外,每个后续的分页调用都意味着使用服务进行重新身份验证(开销),但这就是无状态HTTP的本质!