代码改变世界

浅谈缓存的设计与使用注意项(下)

2010-12-28 00:46 姜 萌@cnblogs 阅读(...) 评论(...) 编辑 收藏

缓存的加载策略--Proactive Reactive

proactive的策略就是一开始就将所有backing store中的数据加载到进程内存中,这样做的好处是在数据量相对不大的时候会显得很有效率,无需频繁的访问backing store调出数据,并且也不用再代码中判断缓存中是否缓存有数据,是否要从backing store中加载。

reactive策略是“按需加载”,在程序初始化阶段仅加载必要的数据到内存缓存起来,其余数据只有在需要时才从数据库中调出再缓存。这种策略比较保守,缺点是在数据量比较大且频繁访问之初由于要多次频繁的向backing store获取数据,但通常我们使用这种的就是这种策略。

下面是两种方案的示例代码比较:

proactive的方式
public List<Product> GetProductList()
{
  
return Respository<Product>.ResolveAll();
}
public void LoadAllProducts(ICacheManager cache)
{
  List
<Product>list = GetProductList();

  
for (int i = 0; i < list.Count; i++)
  {
    Product newProduct 
= list[i];
    cache.Add(newProduct.ProductID, newProduct);
  }
}

 

 

reactive的方式
public List<Product> GetProductList()
{
  
return Respository<Product>.ResolveAll();
}
public Product ReadProductByID(ICacheManager cache, string productID)
{
  Product newProduct 
= (Product)cache.GetData(productID);

  
// Does our cache already have the requested object?
  if (newProduct == null)
  {
    
// The requested object is not cached, so retrieve it from
    
// the data provider and cache it for further requests.
    newProduct = this.dataProvider.GetProductByID(productID);

    
if (newProduct != null)
    {
      cache.Add(newProductID, newProduct);
    }
  }
  
return newProduct;
}

 

 

 

 

缓存隔离:Partitioned Caches

一个caching block中CacheManager不能被多个进程或是一个进程的不同应用程序域所共享。但多个进程或是同一进程的多个应用程序域共享一个缓存的需求还是很必要的。关键在于如何设计合理。

三种情形:

A.Partitioned Caches:每个进程/同一进程的不同应用程序域使用不同的backing storage。这是最简单的情况,也不需要我们进行额外的同步处理。每个进程/应用程序域你用你的我用我的大家互不干涉。但这无法是多个进程共享一个backing storage。比如isolatedstorage作为backing storage,如果是不同用户会自动分配不同的隔离存储空间,对于同一用户的话只需将partition配置为不同值即可。

image

B.Shared Partition:n个进程中只有1个进程能够修改backing storage,所有进程都能够读取backing storage的数据。这种情况是最理想的,但需要逻辑上的支持。

C.Single Writer:n个进程都能够修改和读取backing storage,这是最糟糕的情况,很容易产生错乱,会导致不同步的现象。