web中缓存的使用

很多人都知道什么叫缓存,甚至学习过,但用起来还真难用。我经过几天的学习cache想跟大家分享和讨论。

我是带着疑问去学习的。缓存是用在什么地方,有什么好处。

缓存就是把获取的数据暂时存到内存中,当获取的数据没有变化时就还是用内存里的东西。评论中有人说缓存可用文件,数据库存。这个我同意,但一般编程都用微软中system.web.caching.cache 类,它是在把数据放在内存中。可能有人会问怎么判断获取的数据没有变化?这个等下会说到。这样从缓存数据可是获取数据速度快很多,但要求数据不时时常变化的。像博客园里的博客排行榜,基本没变化,这是虽是数据不怎么变化,但这样页面每个人浏览都是一样的东西,那又何必用缓存干什么呢?直接把此页面生成html,这样打开的速度比用缓存还快。

当一个页面既有公共部分(每个人浏览的都一样)又有个性部分(自己的信息)。比如当当网里就有个购物车当你购完物时,底单上面有推荐买的产品(这也产品可能一天换一次),当然推荐的产品跟你买的产品有关,此时不能生成html了,因为不是每个人浏览此页面都相同,只有当用户买的产品相关到推荐的产品相同时。此时就要用缓存存此推荐产品的数据,当然这个缓存键值是跟买的产品有关,只要买的产品相关得到的推荐产品(这里面有一种关系在里面)才能该缓存的东西。

打个比方:当你买书时就会推荐其他好书给你,此时买书的推荐书都一样,调用的缓存都一样,而买电脑的话可能会推荐你各种好电脑给你,这时调用推荐电脑的缓存。

上面可能讲了下缓存用在什么地方,当然我只知道这种情况,可能还有其他情况,那位知道可评论下。

缓存的好处当然是减轻服务器的负担,加快浏览速度。但如果缓存用得不好,可能得到的数据是过时的,或者反而使浏览熟读更慢。(当你缓存经常变化的数据时)

 

缓存有分客户端缓存服务器端缓存吗?

两个都有,只是客户端缓存内嵌在浏览器中,基本上是浏览器自动处理缓存。

.

客户端缓存可以有效地减轻服务器端负载。首先了解一下 HTTP 头:Last-Modified If-Modified-Since。简单的说,Last-Modified If-Modified-Since 都是用于记录页面最后修改时间的 HTTP 头信息,只是 Last-Modified 是由服务器往客户端发送的 HTTP 头,而 If-Modified-Since 则是由客户端往服务器发送的头实现。

在浏览器可设置浏览器如何使用缓存的。一般默认是自动。操作步骤如下:

工具-internet选项-》常规-》设置-》检查网页的较新版本中有四个选项来控制缓存的运用

当然代码可控制客户端缓存,比如比想要浏览器缓存东西可用下面代码

html禁用客户端缓存

<META HTTP-EQUIV="pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
<META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1978 08:21:57 GMT">

 

C#中禁止cache的方法!
Response.Buffer = true;
Response.ExpiresAbsolute=System.DateTime.Now.AddSeconds(-1);
Response.Expires=0;
Response.CacheControl="no-cache";

我对客户端缓存知道太少,而且我们写程序也很少写客户端缓存, 希望有人提供更多关于客户端缓存的东西。

 

服务端缓存有System.Web.Caching.cahe和memcached

当然System.Web.Caching.cahe是微软写的类,而memcached是第三方插件。System.Web.Caching.cache目前还不是分布式缓存,只能在一台电脑上(07时候),而

memcached是分布式的高速缓存。

服务器缓存可分为三种缓存

1.输出缓存:

要实现页面输出缓存,只要将一条 OutputCache 指令添加到页面即可。  
  <%@ OutputCache Duration="60" VaryByParam="*" %>  
  如同其他页面指令一样,该指令应该出现在 ASPX 页面的顶部,即在任何输出之前。它支持五个属性(或参数),其中两个是必需的。 
  Duration
  必需属性。页面应该被缓存的时间,以秒为单位。必须是正整数。 
  Location
  指定应该对输出进行缓存的位置。如果要指定该参数,则必须是下列选项之一:AnyClientDownstreamNoneServer ServerAndClient。 
  VaryByParam
   必需属性。Request 中变量的名称,这些变量名应该产生单独的缓存条目。"none" 表示没有变动。"*" 可用于为每个不同的变量数组创建新的缓存条目。变量之间用 ";" 进行分隔。  
  VaryByHeader
   基于指定的标头中的变动改变缓存条目。  
  VaryByCustom
   允许在 global.asax 中指定自定义变动(例如,"Browser")。

 

2.片段缓存:

示例

<%@ OutputCache Duration="60" VaryByParam="*" %> 该示例将缓存用户控件60秒,并且将针对查询字符串的每个变动、针对此控件所在的每个页面创建单独的缓存条目。<%@ OutputCache Duration="60" VaryByParam="none"
VaryByControl="CategoryDropDownList" %> 该示例将缓存用户控件60秒,并且将针对CategoryDropDownList控件的每个不同的值、针对此控件所在的每个页面创建单独的缓存条目。<%@ OutputCache Duration="60" VaryByParam="none" VaryByCustom="browser"
Shared="true" %>

最后,该示例将缓存用户控件60秒,并且将针对每个浏览器名称和主要版本创建一个缓存条目。然后,每个浏览器的缓存条目将由引用此用户控件的所有页面共享(只要所有页面都用相同的ID引用该控件即可)。

 

3.编程用得最多的缓存:数据缓存

System.Web.Caching.cahehttpRuntime.CacheHttpContext.Current.Cache实例化。httpRuntime.CacheHttpContext.Current.Cache是内置对象就想当与seesion

 

HttpContext.Current.CacheHttpRuntime.Cache区别:

HttpContext.Current.Cache:为当前 HTTP 请求获取Cache对象。 HttpRuntime.Cache:获取当前应用程序的CacheHttpContext.Current.Cache是调用了 HttpRuntime.Cache,且HttpContext.Current.Cache是用在web程序上,而HttpRuntime.Cache是用在任何程序上。System.web命名空间下。

其实HttpContext.Current.Cache是通过 HttpRuntime.Cache来实现的,所以一般实例化最好通过HttpRuntime.Cache来实例化:

例如:System.Web.Caching.Cache cache = HttpRuntime.Cache

 

System.Web.Caching.Cache有很多方法,但方法中add中是存缓存

参数中有缓存时间,依赖项。

缓存时间即到当缓存的东西达到指定时间就让缓存失效,而依赖项是当依赖项发生变化就会使缓存失效。

依赖项有一般依赖项 CacheDependency和数据库依赖项SqlCacheDependency

虽然CacheDependency类完成了很重要的功能,但其组成结构却比较简单,主要有两个属性和一个方法。
属性“HasChanged”:判断CacheDependency对象是否已更改。
属性“UtcLastModified”:返回上次依赖项的修改日期
方法“Dispose”:释放CacheDependency对象所占有的资源。因为缓存类继承了接口“IDispose”,所以必须实现此方法。

CacheDependency

例如 Cache.Insert("key", myXMLFileData, DateTime.Now.AddMinutes(1),,new
System.Web.Caching.CacheDependency(Server.MapPath("users.xml")));

 users.xml文件就相当一般依赖项,当xml文件被改了,则此缓存失效。

SqlCacheDependency一般是增对数据库的,这个设置需要在config里设置,而且还要启动数据库的这样服务。

Cache.Insert 中可设置跟数据库中那个表关联,一旦表有变化就会导致cache失效。

可到网上查询如何使用


dewin
关注 - 0
粉丝 - 1
0
0
(请您对文章做出评价)
« 上一篇:web 编程的流行技术
» 下一篇:浏览器(客户端)缓存
posted @ 2009-06-24 23:01 dewin 阅读(2741) 评论(27) 编辑 收藏

 回复 引用 查看   
#1楼2009-06-24 23:17 | 灰色X      
"可能有人会问怎么判断获取的数据没有变化?这个等下会说到。"

没找到答案,能说具体点么。

 回复 引用 查看   
#2楼2009-06-24 23:22 | Old      
呵呵:-)
 回复 引用 查看   
#3楼[楼主]2009-06-24 23:25 | dewin      
一般依赖项CacheDependency和数据库依赖项SqlCacheDependency
这是微软写的类,具有上面的你问的功能

 回复 引用   
#4楼2009-06-25 08:03 | seagreen77[未注册用户]
建议下次这些基础的东西不要发布在首页,浪费别人浏览的时间。
 回复 引用 查看   
#5楼2009-06-25 08:29 | 木白      
@seagreen77

不要打击人家的积极性嘛!

 回复 引用 查看   
#6楼2009-06-25 08:42 | Beggar      
东西还算可以。。但是字号太小了。。看着很费劲。下次注意
 回复 引用 查看   
#7楼2009-06-25 08:47 | wd900      
--引用--------------------------------------------------
seagreen77: 建议下次这些基础的东西不要发布在首页,浪费别人浏览的时间。
--------------------------------------------------------
你认为是基础,就不要看好了, 有什么浪费的, 最讨厌你这样的人了。JJYY的,连登录都不敢。

 回复 引用 查看   
#8楼2009-06-25 08:48 | koorise      
不错。在zzk里找到的没有这个理解的透彻
 回复 引用   
#9楼2009-06-25 09:13 | un-un[未注册用户]
不错....
 回复 引用   
#10楼2009-06-25 09:26 | 路过人[未注册用户]
@seagreen77 同志:

貌似你很懂?登录看看你写过什么发表过什么,请不要在这里装孙子......(俺是路过的)

 回复 引用 查看   
#11楼2009-06-25 09:44 | James.Ying      
前几天是不是有人也发过同样的文章?
 回复 引用 查看   
#12楼2009-06-25 09:47 | 沉默杨仔      
请问:
类似于博客园的这种文章发布方式.该怎么样缓存文章和评论.不可能文章表和评论表全缓存起来吧.求解.

 回复 引用   
#13楼2009-06-25 10:17 | 李华顺[未注册用户]
--引用--------------------------------------------------
seagreen77: 建议下次这些基础的东西不要发布在首页,浪费别人浏览的时间。
--------------------------------------------------------
同意!
另外强列楼主好好整理一下文章排版

 回复 引用 查看   
#14楼2009-06-25 10:37 | 缘易姿姿      
@沉默杨仔

博客园应该是使用了分布式缓存的,文章和评论应该都是缓存了的。只是在你评论的时候去更新一下相应的缓存而已。

还有,缓存的时间有两种,一种是平滑时间,一种是绝对时间,比如缓存1分钟后更新。

 回复 引用 查看   
#15楼[楼主]2009-06-25 10:40 | dewin      

博客园的这种文章发布用缓存速度没有生成html快所以不用缓存,因为他对任何浏览者都一样,而且是一个小时左右发表一篇文章,所以发表一篇文章生成一个html。可评论就太多了,一篇文章有多个评论,如果生成html的话就频度太高了,因为一篇文章有多个评论,没改增加个评论就生成html就太频繁了。此时可缓存前一页文章的所有品论,即一篇文章的评论用个键值来存,这样也只要十几个键值缓存。因为前一页文章的评论可能浏览次数多,所以缓存啊,至于后面没什么人看的,觉得就不要缓存了。你再看看上面的文章。

 回复 引用 查看   
#16楼2009-06-25 10:58 | 沉默杨仔      
--引用--------------------------------------------------
dewin:
博客园的这种文章发布用缓存速度没有生成html快所以不用缓存,因为他对任何浏览者都一样,而且是一个小时左右发表一篇文章,所以发表一篇文章生成一个html。可评论就太多了,一篇文章有多个评论,如果生成html的话就频度太高了,因为一篇文章有多个评论,没改增加个评论就生成html就太频繁了。此时可缓存前一页文章的所有品论,即一篇文章的评论用个键值来存,这样也只要十几个键值缓存。因为前一页文章的评论可能浏览次数多,所以缓存啊,至于后面没什么人看的,觉得就不要缓存了。你再看看上面的文章。
--------------------------------------------------------
缓存最前几篇文章是一个较好的解决方法.但是感觉博客园不是采用这种方式,如此多文章.
* 博客 - 53150
* 随笔 - 473541
* 文章 - 115077
* 评论 - 968534
如此多评论和文章.在搜索和分页的时候速度还是比较快的.如果只缓存前几篇文章.在分页浏览和搜索的时候这个速度应该没这么快

 回复 引用 查看   
#17楼2009-06-25 11:06 | fphuang      
非常好,简单易懂;帮助记忆
 回复 引用 查看   
#18楼2009-06-25 11:21 | 缘易姿姿      
@dewin

你知道博客园是生成静态?

你看过.Text没有啊?

哈哈。

不过不知道现在博客园改成什么样子了!

----
另外什么叫缓存前面几条?。。。。

--
即一篇文章的评论用个键值来存,这样也只要十几个键值缓存

------
缓存是这样用的?还是头回看见!

建议楼主多去学习再说吧。

 回复 引用 查看   
#19楼2009-06-25 11:24 | 缘易姿姿      

还有,I/O和缓存之间有一个平衡取舍。

静态文件增加了I/O的压力。任何东西都是不绝对的

 回复 引用 查看   
#20楼2009-06-25 11:25 | Jeffrey Zhao      
缓存就是把获取的数据暂时存到内存中,当获取的数据没有变化时就还是用内存里的东西。
===========================
和“内存”无关啦

 回复 引用 查看   
#21楼2009-06-25 11:59 | Sky_Dream      
挺不错 学习了
 回复 引用 查看   
#22楼[楼主]2009-06-25 12:07 | dewin      
缘易姿姿
我不知道博客园的首页生成,只是我认为这样,当然可能有更好的方法。
对于缓存用键值存评论,这个我觉得没问题的。我所说的评论是评论的数据,不是html。其实用缓存也不是一定要用,也是看情况,刚才说的静态文件增加了I/O的压力,但我说了一小时才生成一个html。
这个我确定是对的。如果你觉得错,你举个例子,上面有例子用键值存。

Jeffrey Zhao。楼下的评论让我不是很清楚你的话

 回复 引用 查看   
#23楼2009-06-25 13:16 | 沉默杨仔      
博客园采用的是URL重写.已得到DUDU证实.
 回复 引用   
#24楼2009-06-25 15:10 | 李华顺[未注册用户]
@dewin
哎,别把无知当自知!

别乱做猜测,多用 Google 查查,多做做
什么一个小时才生成一个HTML,别人评论了你不刷新缓存呀

另外Jeffrey Zhao说的意思不是你想的哪样
缓存是一种定义,它可以是内存、文件、数据库、或存放在其它一些地方,缓存只是一种名字而且,把处理好的简单数据根据情况放在适当的地方。

 回复 引用 查看   
#25楼[楼主]2009-06-25 16:07 | dewin      
我只知道这么多,至于你理解的缓存我不太理解,不知阁下可写写文章给我们大家看, 让我们更清楚了解。
 回复 引用 查看   
#26楼2009-06-25 22:48 | lsjwzh      
@李华顺
言辞激烈的点。。。不过博客园现在的人确实比以前多了,水平也层次不齐了,博客园是不是可以考虑在首页开一个基础专栏,分配一点版面给俺们这些菜菜

 回复 引用 查看   
#27楼2010-02-06 14:52 | Mr.Cantus      
引用李华顺:@dewin<br/>哎,别把无知当自知!<br/><br/>别乱做猜测,多用 Google 查查,多做做<br/>什么一个小时才生成一个HTML,别人评论了你不刷新缓存呀<br/><br/>另外Jeffrey Zhao说的意思不是你想的哪样<br/>缓存是一种定义,它可以是内存、文件、数据库、或存放在其它一些地方,缓存只是一种名字而且,把处理好的简单数据根据情况放在适当的地方。


我同意他的说法。数据存到缓存只是缓存众多方法中的一个,也是速度很快的一个。不能说“缓存就是把获取的数据暂时存到内存中”。