1

I read a lot of documents about AppFabric caching but most of them cover simple scenarios. For example adding city list data or shopping card data to the cache. But I need adding product catalog data to the cache.

I have 4 tables:

Product (1 million rows), ProductProperty (25 million rows), Property (100 rows), PropertyOption (300 rows)

  • I display paged search results querying with some filters for Product and ProductProperty tables.
  • I am creating criteria set over searched result set. For example (4 Items New Product, 34 Items Phone, 26 Items Book etc.)
  • I query for grouping over Product table with columns of IsNew, CategoryId, PriceType etc.
    and also another query for grouping over ProductProperty table with PropertyId and PropertyOptionId columns to get which property have how many items

Therefore to display search results I make one query for search result and 2 for creating criteria list (with counts)

Search result query took 0,7 second and 2 grouping queryies took 1,5 second in total. When I run load test I reach 7 request per second and %10 dropped by IIS becasue db could not give response.

This is why I want to cache Product and property records.

If I follow items below (in AppFabric);

  • Create named cache
  • Create region for product catalog data (a table which have 1 million rows and property table which have 25 million rows)
  • Tagging item for querying data and grouping.

Can I query with some tags and get 1st or 2nd page of results ? Can I query with some tags and get counts of some grouping results. (displaying filter options with count) And do I have to need 3 servers ? Can I provide a solution with only one appfabric server (And of course I know risk.) Do you know any article or any document explains those scenarios ?

Thanks.

Note:

Some additional test: I added about 30.000 items to the cache and its size is 900 MB. When I run getObjectsInRegion method, it tooks about 2 minutes. "IList> dataList = this.DataCache.GetObjectsInRegion(region).ToList();" The problem is converting to IList. If I use IEnumerable it works very quicly. But How can I get paging or grouping result without converting it to my type ?

Another test:

I tried getting grouping count with 30.000 product item and getting result for grouping took 4 seconds. For example GetObjectByTag("IsNew").Count() and other nearly 50 query like that.

4

1 回答 1

2

不幸的是,在 V1 中没有用于 AppFabric 的分页 API。任何批量 API,例如,都将在服务器上执行查询并将所有匹配的缓存条目GetObjectsByTag流回客户端。从那里您显然可以在(例如)上使用您想要的任何 LINQ 运算符,但请注意,您总是从服务器拉回完整的结果集。IEnumerableSkip/Take/Count

我个人希望 AppFabric V2 将通过IQueryable而不是 IEnumerable 提供支持,这将提供远程将完整请求发送到服务器的能力,因此它可以在返回客户端之前将结果分页,就像 LINQ2SQL 或 ADO.NET EF 一样。

目前,根据应用程序的功能,一个潜在的解决方案是,您可以在将项目注入缓存时实际计算某种分页。您可以构建表示每个页面的实体键的有序列表,并将它们作为单个条目存储在缓存中,您可以在一个请求中提取这些条目,然后单独(并行)或从缓存中批量获取列表中的项目并将它们连接在一起使用内存中的 LINQ 查询。如果您想以 CPU 换取内存,只需缓存完整实体的实际列表而不是 ID,并且必须为实体进行连接。

您显然必须想出某种键控机制来根据传入的搜索条件从缓存中快速提取这些对象列表。像这样的某种键控可能会起作用:

private static string BuildPageListCacheKey(string entityTypeName, int pageSize, int pageNumber, string sortByPropertyName, string sortDirection)
{
   return string.Format("PageList<{0}>[pageSize={1};pageNumber={2};sortedBy={3};sortDirection={4}]", entityTypeName, pageSize, pageNumber, sortByPropertyName, sortDirection);
}

您可能需要考虑使用单独的进程或工作线程执行此类操作,以使缓存保持最新状态,而不是按需执行并在尚未填充缓存条目时强制用户等待。

这种方法最终是否适合您取决于您​​的应用程序和数据的几个因素。如果它不完全适合您的场景,也许它至少会帮助您将思想转变为解决问题的不同思维方式。

于 2011-02-22T03:44:47.380 回答