立博名家

Caching Application Block

如果你遇到以下情况,Caching Application Block是你的一个很好的选择:
必须重复访问静态数据或很少改变的数据。 
数据访问在创建、访问或传输方法代价高昂。 
数据必须总是可以访问,即使当源服务器不能访问。

一个程序域对应多个缓存,不同程序域之间不能共享。
例程2.1
CacheManager productsCache = CacheFactory.GetCacheManager();

string id = "ProductOneId";
string name = "ProductXYName";
int price = 50;

Product product = new Product(id, name, price);

productsCache.Add(product.ProductID, product, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromMinutes(5)));

//检索缓存项目
product = (Product) productsCache.GetData(id);

选择后备存储
一般缓存管理器在内存中缓存数据,也就是说,没有后备存储,但是也可以配置为既使用内存也使用后备存储,这使得程序重新启动也不会导致缓存数据的丢失,目前,CAB支持两种后备存储:
独立存储和数据库储存
独立存储适用于用户数量少,缓存数据少,例如智能客户端,每个程序域包含各自缓存的场合
数据库存储适用于需要访问数据库的每个程序域包含各自缓存一些服务端程序。
无论是独立存储还是数据库存储,不同程序域间是无法共享缓存数据的

注意以下情况,当同一个程序的多个实例运行时,你可以如下部署:
1.隔离缓存
使用相同数据库实例,不同存储区域。在这种情况下缓存管理器的操作都是相互独立的,虽然他们使用了相同的数据库存储,但是由于缓存区是相互独立的,因此程序重新启动时,各个程序独自取回自己缓存的数据。
2.共享存储
使用相同数据库,相同的存储区域,每个缓存管理器都可以对缓冲区进行读写操作。当多个程序实例同时启动,从后备存储中装载数据到内存中,这时,每个实例在内存中的缓存数据是相同的,但是随着时间的运行,各自在内存中的缓存数据不一定相同,而内存中的数据和后备存储中的也不一定相同。
当一个实例缓存中的数据改变时,缓存管理器更新后备存储以反映更改,这时其他实例内存中的数据就与后备存储中的数据不相同了,当程序重新启动后,装载的数据也就不等同与启动前内存中的缓存数据
程序可以订阅缓存管理器更新事件已及时刷新缓存。
3.单个写多个读
    使用相同数据库,相同的存储区域,每个缓存管理器都可以对缓冲区进行读操作,只有一个缓存管理器可写。

典型应用
1.向缓存中添加缓存项
例程2.2 使用Add方法
CacheManager productsCache = CacheFactory.GetCacheManager();

string id = "ProductOneId";
string name = "ProductXYName";
int price = 50;

Product product = new Product(id, name, price);

productsCache.Add(product.ProductID, product, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromMinutes(5)));

2.向缓存中加载数据
有两种方法来加载数据:
Proactive loading:该方法首先检索所有需要的数据,然后在应用程序或进程整个生命期内缓存数据。
Reactive loading:该方法根据应用程序的需要检索必要的数据,然后将数据存放在缓存中,用于将来的请求。

预缓存的优势和劣势
当采取预缓存时你的程序的性能有了提高,程序的响应时间也加快了。

在一些经过优化的程序中,预缓存可能没有多大用,因为不是所有的数据都需要缓存,在超过100个进程程序中,很有可能经常要读取一些缓存数据,而对于单个活动进程的程序,缓存数百项目则显得没有必要。
预缓存可能导致常规技术下实现变得更加复杂,如果你不正确使用预读取方法,可能会导致你的程序初始化非常慢。

当你使用预缓存技术时,你应该在程序初始化时尽可能多的加载状态,并使用异步模型在后台检索数据。

按需缓存的优势和劣势
由于你没有在初始化时加载全部的数据,程序资源有可能不可用,但是这个方法将导致一个最优化的系统,因为只在需要时才读取它。
当第一次读取某些数据时,有可能造成程序性能的降低,因为要加载需要的数据,当你使用数据之前,你必须检查它是否在缓存中,在每个代理服务中检索将造成大量的额外的负担。

当你有很多状态并没有足够的资源来存储它时,并且使用的是可靠的外部数据源时推荐使用该方法。
例程2.3 向缓存中添加数据
预缓存
public List<Product> GetProductList()
{
  // This returns a list of product objects.
}

public void LoadAllProducts()
{
  CacheManager cache = CacheFactory.GetCacheManager();

  List<Product>list = GetProductList();

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

按需缓存
public Product GetProductByID(string anID)
{
  // This returns a product object with the specified ID.


public Product ReadProductByID(string productID)
{
  CacheManager cache = CacheFactory.GetCacheManager();

  Product product = (Product)cache.GetData(productID);

  // 需要的项是否已在缓存中?
  if (product == null)
  {
    // 如果不在则从源中检索它,并缓存
    product = this.dataProvider.GetProductByID(productID);

    if (product != null)
    {
      cache.Add(productID, product);
    }
  }
  return product;
}

3.清空缓存
使用Flush方法使得各种资源能更有效地利用。使用该方法将移除缓存中所有项。

4.移除缓存项
使用Remove方法以移除缓存项。

5.读取缓存项
使用GetData方法
例程2.4
//从缓存中读取特定项,如果该项不在缓存中则返回Null
public Product GetProduct(CacheManager cache, string key)
{
  return (Product)cache.GetData(key);
}

posted on 2007-08-22 15:44  大李  阅读(255)  评论(0)    收藏  举报

导航

立博名家