强大的SqlCacheDependency

最近我在忙于研究负载平衡、并发性容错性等性能优化问题,ASP.NET有太多强大的功能等待学习和挖掘。今天,Bosnma和大家一起研究在ASP.NET中缓存机制如何帮助我们在高流量网站中减少服务器负担。

何为缓存 
         缓存无处不在,尤其是流量较高的网站。对于某些页面(尤其是带有一个或更多数据库操作的页面)可能会对数据库服务器带来过大的负载,而这些负载经常是不必要的。比如某公司的商品清单页面可能在一个小时,一天甚至更长时间并未改变,遗憾的是每一个浏览该页面的用户都会造成数据库的连接及查询。缓存就是为了解决这样的问题应运而生。
缓存的简单实现 
          在ASP.NET中实现缓存的最简单的方法就是在页面上加一个OutputCache标签。
<% @ OutputCache Duration ="20" VaryByParam ="*" %> 
    其中Duration指定了缓存的过期时间。上面的句子表示该页面的数据库查询操作在20秒内会自动保存到缓存中,不再重复连接数据库,在高流量的网站中大大减轻了数据库的负载。
没有免费午餐 
         PageCache简单好用,可是有点小小的问题。例如在一个论坛中的首页往往都会用到PageCache,这样最新发表的帖子不会立即显示在首页上,而是需要等待一段时间(缓存过期)后才会出现,而这种延迟在某些场合是完全不允许的。比如购物商城的网站,某人已经订购了最后一批货物,而由于缓存机制,其他人查看状态时依然是订购前的(未被订购),我想你不会希望两个人买你仅有的一件商品。ASP.NET里面的Cache并不能自动根据数据库中相应数据发生了变化,而使相应的Cache过期,ASP.NET 2.0中新增的SqlCacheDependency特性使这成为了可能。我们今天的主题就此引出。
强大的SqlCacheDependency 
SqlCacheDependency在保证更新同步的前提下通过缓存减小数据库负载。那么如何使用它呢?
1、 使数据库支持SqlCacheDependency 
 
在.Net Framework 2.0 的安装目录下(通常是WINDOWS\Microsoft.NET\Framework\v2.0.XXXXX),有一个aspnet_regsql.exe,这个命令行工具可以帮助我们使数据库支持SqlCacheDependency特性,

首先:“aspnet_regsql  –S 服务器名 –U 登陆名 ID –P 密码 –d 数据库名  –ed”,这个命令使指定数据库支持SqlCacheDependency,  
然后我们再加入要追踪的数据表:“aspnet_regsql –S 服务器名  –U 登陆名 ID –P 密码 –d 数据库名 –t 追踪的数据表 –et”,这个命令使指定的Table支持SqlCacheDependency。 
指令运行后,在指定的数据库中会新建一个Table,叫做“AspNet_SqlCacheTablesForChangeNotification”,这个表有三个字段,“tableName”记录要追踪的数据表的名称,“notificationCreated”记录开始追踪的时间,“changeId”是一个int类型的字段,每当追踪的数据表的数据发生变化时,这个字段的值就加1。 
它还会在指定的数据库中增加几个存储过程,用来让ASP.NET引擎查询追踪的数据表的情况。 
然后,它会给我们要追踪的Table加上几个Trigger,分别对应到Insert、Update、Delete操作,这几个Trigger的语句非常简单,就是把“AspNet_SqlCacheTablesForChangeNotification”表中对应“tableName”字段为这个追踪的表的名称的记录的“changeId”字段加上一个1。 
ASP.NET引擎通过执行它加上的存储过程“AspNet_SqlCachePollingStoredProcedure”,这个存储过程直接返回“AspNet_SqlCacheTablesForChangeNotification”表的内容,让ASP.NET引擎知道哪个表的数据发生的变化。默认每500毫秒执行这个存储过程一次,不过可以在web.config里面修改这个间隔时间。

2、 web.config配置 
  < system.web > 
    <!-- 配置Cache 结点 , 使网站 支持SqlCacheDependency --> 
    < cache > 
      < sqlCacheDependency enabled = " true " pollTime = " 500 " > 
        < databases > 
          < add name = " CacheDB " connectionStringName = " CS " /> 
        </ databases > 
      </ sqlCacheDependency > 
    </ cache > 
</ system.web > 
3、 在页面上的outputCache标签中指定SqlCacheDependency特性: 
 
<% @ OutputCache Duration ="9999" VaryByParam ="None" SqlDependency ="CacheDB:TableName" %> 
其中TableName为追踪的表名,只要在这个追踪的Table上执行了Insert、Update、Delete操作,数据表上的Trigger就会将数据库中“ AspNet_SqlCacheTablesForChangeNotification”表的相应记录的相应“changId”字段值修改,然后ASP.NET 引擎就会通过获取新的值来得知追踪的Table的内容发生了变化,自动使这个页面的cache失效 
最后 
        同样的网站,同样的功能,在 安全性 、 并发性 、 容错性 很多方面都会有所不同,而网站的好坏并不是看他有多少花哨的功能或多么华丽的界面,而是他是否实用、稳定、效率、安全。 ASP.NET 博大精深,看来好多东西,都是“越学越浅”的。

原文地址:https://www.cnblogs.com/soundcode/p/2958886.html