蝈蝈俊.net

-- 用随笔来记录自己的技术感触
随笔 - 673, 评论 - 4434, 引用 - 276

导航

关于

记录自己的技术心得

标签

每月存档

最新留言

  • Gislajfo
    good material thanks <a href=" http://www.wikio.com/user/nulonouuer/bio "&a...
    by Gislajfo(匿名) on 2010/3/22 8:22:05
  • Xujaiukx
    i'm fine good work <a href=" http://www.wikio.com/user/nulonouuer/bio "&...
    by Xujaiukx(匿名) on 2010/3/22 8:22:04
  • Ipukclwa
    It's funny goodluck <a href=" http://www.wikio.com/user/nyritybos/bio "&...
    by Ipukclwa(匿名) on 2010/3/22 8:22:03
  • Qmhwngfw
    I love this site <a href=" http://www.wikio.com/user/aaganicik/bio "&gt...
    by Qmhwngfw(匿名) on 2010/3/22 7:02:52
  • Psroqiuy
    Excellent work, Nice Design <a href=" http://www.wikio.com/user/ihuopumedyq/bio &...
    by Psroqiuy(匿名) on 2010/3/22 7:02:51
  • Akmpneym
    Cool site goodluck :) <a href=" http://www.wikio.com/user/efigigoci/bio "&a...
    by Akmpneym(匿名) on 2010/3/22 7:02:50
  • Wcdgeacn
    Excellent work, Nice Design <a href=" http://www.wikio.com/user/esakoieh/bio &qu...
    by Wcdgeacn(匿名) on 2010/3/22 6:16:17
  • Fmfdfxms
    I love this site <a href=" http://www.wikio.com/user/esakoieh/bio ">...
    by Fmfdfxms(匿名) on 2010/3/22 6:16:09
  • Zhjfcjvt
    It's funny goodluck <a href=" http://www.wikio.com/user/qepinycutij/bio "&a...
    by Zhjfcjvt(匿名) on 2010/3/22 6:15:58
  • Djognbnr
    Gloomy tales <a href=" http://www.wikio.com/user/taqoeteheg/bio ">mo...
    by Djognbnr(匿名) on 2010/3/22 4:57:15

广告

 

  最近公司一直在招人,我作为主考官之一 。经常会提问的一个问题,就是让用户介绍自己在缓存方面的经验和心得。绝大多数的面试者只能说ASP.net的页面缓存和局部缓存,稍稍有点经验的,会提到企业库的缓存,只有很少的人会知道Memcached(一个分布式的缓存)。而对于缓存的一些基本思想,却没有一个人能说出来。

  现在的技术人员,很多时候,不管三七二十一,把一个个实体丢到缓存中,然后在用的时候,就从缓存中去找这个实体。而不会考虑缓存的其他方面因素。所以他们在提到缓存时,想到的才只能是一个个的缓存实现的方法,而不是缓存的思想。

  那么,肯定就有人问,蝈蝈俊,那你理解的缓存思想是如何的呢?下面我就一一来说出我理解的缓存。

 

Q:什么样的缓存才是好缓存?

  能解决问题的缓存就是好缓存。这句话简直就是废话,相当于白猫、黑猫,抓住老鼠的就是好猫。

  那在解决问题前提下,哪个缓存才是好缓存呢? 这个问题我的答案是:缓存命中率高的缓存是好缓存。

  在解决问题前提下,命中率高的缓存比命中率低的缓存,在硬件投入上可能会比较小,同时缓存的数量比命中率低的缓存数量也可能少,这样寻址的速度肯定比较快。所以命中率高的缓存是好缓存。

 

缓存的命中率

  一个缓存的实体在被丢到缓存中后,在这个实体被缓存的期间(这个实体被缓存的生命周期内),如果外部一次都没有使用过它,这个缓存实体的命中率就是0。这个实体被请求的次数越多,它的缓存命中率越高。

  上面说的是缓存中一个实体的命中率。对于缓存整体来说,它的命中率则是上面各个被缓存的个体的命中率分布图。

  对于缓存来说:通常最常使用的个体之占总体的很小一部分。最不常使用的占整体的很大一部分。如下图所示:

缓存的命中率一般分布图

  所以我们经常会看到类似这样的数据:

  缓存的1万个元素中,有100个被频繁的使用,几乎每分钟都会被使用一次。2000个数据,每小时被请求一次。3000个数据,每天被请求一次,剩下的数据,被丢到缓存中后一次都没有被使用过。

  现在硬件发展很快,如果我们只是需要缓存1万个数据的话,我们完全可以做到不管这1万个数据是否被使用到,全部丢到缓存,这样只要找数据,肯定缓存中有这个数据。而不需要作额外的运算,或者不需要向数据库发出请求。

  但是:硬件发展快,数据量发展也快。小型的网站,缓存1万条数据,也就全部缓存了。但是大型网站最少也是上百万的数据量或者上T级别的数据,这些数据量显然不能都丢到缓存。这时候设计一个合理的缓存方案,提高缓存的命中率,就非常重要。而且是必须的。

 

提高缓存命中率的一些常见方法

  纯技术的角度来说,我们只有记录了用户的单位时间的请求数,并依照这个信息来把最常被使用的数据缓存起来。

  但更多的时候,我们是根据业务逻辑来提高缓存命中率的。比如:去年,前年发表的博客,这类文章的浏览请求,一般一天至少可怜的几次。一般不应该缓存到内存中。

  又比如,回复数多的帖子,一般被请求数会比回复数少的帖子会被更多人次看到。 

  我们应该通过上面逻辑,根据我们实际业务逻辑,提供一个缓存算法,提高缓存的命中率。让在我们硬件允许的条件下,缓存适当的数据,而不是所有数据。

 

  一个反面的例子就是:不管三七二十一,一个大型的博客站点,一篇文章被用户请求的时候,发现不在内存缓存中,就从数据库中读出,然后丢到缓存。

  要知道,现在爬虫程序很多的。另外,博客这类搜索引擎友好的站点,决大多数的访问压力是搜索引擎搜索过来的。而这些访问一般都是1小时,或者1天之内,对某篇文章只有几次甚至1次请求,之后再也没有了。上面作缓存的方法,命中率会非常低的。

  这里也许就有人会问,郭红俊,既然你不建议我缓存这些博客的内容,但是我如何提高我站点的性能呀,我至少得保证我博客站点不会速度慢的无法响应用户请求呀。

  这个问题的解决方案有很多,一个最简单的方法就是把这些博客做成静态Html页面,也就是文件系统的缓存,文件系统因为硬盘的原因,可以简单理解成可以无限扩容,这样就可以把很多命中率低的内容进行缓存。

  如果你的页面需要一些动态逻辑判断,你可以把数据缓存成XML文件,然后服务器段整合这些XML文件,或者是包含文件。这也是种不错的方法。

 

说了这么多缓存命中率的问题,简单汇总一下缓存命中率的观点

  1. 小型网站可以全部数据缓存,一般压力也不会很大,可以忽略缓存命中率问题。
  2. 大型服务无法全部数据缓存,只能部分数据缓存,这时候就需要架构师设计出对该业务逻辑适用的缓存方法,尽可能的提高缓存的命中率。
  3. 提高命中率的方法大多是跟业务逻辑捆绑的,需要跟具体问题具体分析
  4. 对于不能被内存缓存的数据,最简单的提高性能方法就是使用文件缓存。
  5. 文件缓存可以整个内容缓存成一个静态文件;也可以是整个页面的一个区域被缓存成一个文件,然后被包含;也可以是把一个实体序列化成XML文件进行缓存。

 

下面我们看看缓存的其他几个不那么重要的方面:

 

缓存的生命周期内的活动

  永久不过期,永久不变更的内容,这类东西就不应该放在缓存。缓存是临时的存储,而不是永久的,所以缓存的生命周期是有限的。

  它依次可能会经历如下活动:

  1. 进入缓存。(进入缓存的时候,可能需要指定它以后的过期策略,如果不指定,需要使用系统默认的过期策略)
  2. 从缓存中获得它,注意,这时候需要处理线程安全的问题。
  3. 更新缓存,注意,也需要考虑线程安全问题
  4. 离开缓存,这个可能是外部请求,也可能是缓存根据过期策略把它清理掉。

 

缓存的过期策略

  一般我会问,你所接触的缓存中,碰到过那些缓存过期策略?

  最常见的几种过期策略如下:

  多长时间没有被请求,则过期,最典型的就是ASP和ASP.net 提供的 Section 功能。其实它就是一个缓存。

  依赖于文件变更的缓存,一旦文件被修改,缓存则过期,典型的是 WEB站点的 Web.config ,一旦这个文件变更,不但缓存重起,IIS进程也会进行一次释放工作。

  在此基础上,可能看到很多依赖关系的缓存过期策略。比如依赖于数据库的缓存过期策略。

  当然,业务逻辑里可能会有更复杂的过期策略,必须CSDN新版积分制论坛中,帖子列表缓存会在列表数据缓存达到600时,把它清理到550条数据。

  又比如新积分制论坛帖子的缓存过期,则是没有任何列表引用这个帖子后,则这个帖子过期。

 

缓存的同步问题

  使用缓存,则意味着同样的数据,可能有多份并存。如果你的代码没有考虑某种情况,导致了这两份数据不一致了。这时候就会有问题发生。

  解决方法很简单,把你的业务逻辑,代码触发情况都考虑清楚,不要遗留没有触底的地方。

  简单的方法会导致你的代码逻辑变得非常复杂。

  这也就是有些人,在非必要的时候,建议你不要用缓存的原因。一旦开始使用缓存,你就应该准备增加大量的代码来处理数据同步的问题。

 

初始化填充缓存数据

  有时候在缓存被初始化后,还需要预先填充一些数据到缓存中。这就是缓存数据的初始化操作。

  缓存数据的初始化操作需要考虑以下问题:

  1. 需要多长时间进行初始化,一般如果是站点的话,我们可能在 Global.asa 的 Application_OnStart 中处理这个初始化工作。初始化的一般不能太久,这时候就是考验我们代码优化的能力了。
  2. 初始化的时候,一般是批量导入数据,而不是我们正常使用的时候,一次处理一个数据。

 

 总结:

  本文介绍了我对缓存的一些观点,而没有深入涉及到具体的缓存技术。希望通过本文的讲述,让只会缓存用法不懂缓存思想的人有初步的了解。

打印 | 张贴于 2007-09-01 21:26:00 | Tag:.net 编程心得  技术随笔  网站开发管理相关内容  设计思路

留言反馈

#order finast 编辑
h3IB1u Howdy, and <a href="http://myambutol-fda.socialgo.com">myambutol online</a> and http://myambutol-fda.socialgo.com myambutol online and %-]] and <a href="http://lamisil-fda.socialgo.com">discount lamisil</a> and http://lamisil-fda.socialgo.com discount lamisil and 892 and
2010-03-17 16:48:53 | [匿名:order finast]
#re: 理解缓存 编辑
解决方法很简单,把你的业务逻辑,代码触发情况都考虑清楚,不要遗留没有触底的地方。

“没有触底的地方。”??
2008-02-24 13:36:21 | [匿名:solorez]
#SQL Server 索引基础知识(5)----理解newid()和newsequentialid() 编辑
在SQL Server 2005 中新增了一个函数:newsequentialid(),MSDN 中对这个函数的描述如下: 在指定计算机上创建大于先前通过该函数生成的任何 GUID 的 GUID。NEWSEQUENTIALID() 不能在查询中引用。NEWSEQUENTIALID() 只能与 uniqueidentifier 类型表列上的 DEFAULT 约束一起使用。 这个函数的具体用法在下面这篇博客中已经有详细的描述了。 使用NEWSEQUENTIALID解决GUID聚集索引问题http://www.cnblogs.com/Mirricle/archive/2007/08/15/856726.html...
2008-01-08 15:06:00 | [匿名:ghj1976]
#理解缓存 编辑
理解缓存!
2008-01-02 13:25:00 | [匿名:张天利]
#回复: 理解缓存 编辑
请教一下,经常更新但访问次数也较高的数据适合放入缓存吗?
2007-12-19 15:23:00 | [匿名:土豆爱吃地瓜]
#回复: 理解缓存 编辑
sorry,上篇回复有错别字。
Asp.net 2.0中的Profile是不是一种缓存机制,或者是不是使用了某种缓存机制
2007-12-08 22:06:00 | [匿名:beginner]
#回复: 理解缓存 编辑
Asp.net 2.0中的Profile是不是一种缓存机制,或者是不是使用了某种环粗机制
2007-12-08 22:04:00 | [匿名:beginner]
#回复: 理解缓存 编辑
经典~~~~~~~~~~~~
2007-10-30 17:25:00 | [匿名:阿瑞]
#回复: 理解缓存 编辑
JIVE论坛提供的缓存策略也值得我们去学习学习的
2007-09-28 23:01:00 | [匿名:java开发者]
#回复: 理解缓存 编辑
最典型的就是ASP和ASP.net 提供的 Section 功能。其实它就是一个缓存。



是Session吧?
2007-09-17 11:22:00 | [匿名:在线代理]
#回复: 理解缓存 编辑
看到这样帖子,受益匪浅.非常感谢 请教一些问题
使用缓存的作用是能减少数据库访问量,提高访问速度.我有一个问题那缓存中的数据是存储在内存中,那是不是对计算机内存的要求特别高呢?我想知道缓存它对计算机的内存使用率是多少?
2007-09-13 10:50:00 | [匿名:firm]
#回复: 理解缓存 编辑
:) memcached 真的好用

另学习一下你们的缓存策略
2007-09-13 10:42:00 | [匿名:guoadou]
#回复: 理解缓存 编辑
我曾做的一个项目中,主要是针对数据集缓存,但是简单地设置了过期/优先级策略。
比如:首页的数据集,首分页页码段(比如2-10页)的数据集,以及根据数据集内容的大小,分别设置了不同的优先级和过期时间。
这能算是一个好的缓存方式吗?
2007-09-09 16:29:00 | [匿名:simpsons]
#回复: 理解缓存 编辑
我只是想说,memchaced(记得是case sensitive的,你打Memcached会找不到的:p),光这个d字就决定了它是一个unix世界的东东(虽然真的特别好用),你是ms的,你面试的人不知道memcached很正常吧……为什么ms不出一个 Microsoft Enterprise Caching Services 200X 之类的?
2007-09-07 15:35:00 | [匿名:uuu]
#留个记号(缓存) 编辑
2007-09-06 09:37:00 | [匿名:Chatterley]
#回复: 理解缓存 编辑
对企业级应用来说,自定义的缓存机制,不论从算法还是可用性都不如数据库直接支持的彻底。而且在应用程序侧进行缓存,有一些问题解决起来非常麻烦,比如负载均衡下各个节点缓存的更新。

最简单解决缓存的办法是拆DB。增加一台DB服务器的成本比软件成本低多了,更加稳定、可靠不说,单提命中率,一般情况下DB也比应用程序缓存彪悍的多。

当然,对十分简单的应用,十分频繁使用的数据,写上三五百行缓存一下挺好。

btw:没有读过Hibernate相关的代码,它解决了负载均衡下各节点缓存更新的问题吗?粗略的翻了翻MemCache,它提供的是master/slave型的多节点支持,类似于DB的复制,也不直接支持负载均衡。

如果不支持负载均衡,称之为“企业库”可能有些勉强,呵呵。
2007-09-04 10:21:00 | [匿名:Nineteen@newsmth]
#回复: 理解缓存 编辑
不错...值得学习




┌┐﹎﹎﹎﹎ .﹎﹎.﹎﹎.﹎﹎.﹎
└□ㄗs: ☆﹎.﹎.﹎. ゝつ
┊″..友情加盟 ..oo
┊[url=http://www.broadmesse.com]展览[/url] | [url=http://www.broadmesse.net]展览公司[/url] | [url=http://www.broadmesse.org]展览展示[/url] | [url=http://www.expo-overseas.com]会展[/url]
┊ .... oo...
2007-09-03 15:56:00 | [匿名:broadmesse]
#回复: 理解缓存 编辑
@shanyou
现在的人不是没有思想,而是没有形成一个系统的思维,由点到线,然后到面。。。

博客堂和博客园的用户群整体上是要差一些的,博客堂的成员需要审核,而博客园成员随意注册,
而且你所谓的思想肯定不是一蹴而就的,这个需要长时间的积累沉淀的。你没看到,并不代表别人没有(反正我是没有的)。
2007-09-03 15:34:00 | [匿名:kisskiki]
#回复: 理解缓存 编辑
太复杂了,缓存在的意义何在?它可以为我们提高程序性能提供帮助,减少与数据物理存储的交互,但是我们绝不能把缓存作为一种“存储依赖”,使用缓存要适度而行,有些数据是打死也不能放到缓存里的,比如说在线购物网站中用户的余额。如果你还考虑“缓存更新”(这点不知道你说的是通过程序去修改缓存中的数据,还是指缓存过期后再次构造),如果你说直接去修改缓存中的数据,那你还要考虑与物理存储存同步的问题,这样问题就更复杂了。呵,一点点个人意见
2007-09-03 12:21:00 | [匿名:天天向上]
#回复: 理解缓存 编辑
缓存的过期策略
是比较难于把握的, 论坛,blog, news之类的, 时间性要求不是非常高的还好处理。
对于一些业务型的Cache处理, 最难的是过期策略!
2007-09-03 10:06:00 | [匿名:sharper]
#回复: 理解缓存 编辑
强!! 不错 ,好文章
2007-09-03 09:50:00 | [匿名:gyf19]
#回复: 理解缓存 编辑
2007-09-03 09:49:00 | [匿名:gyf19]
#回复: 理解缓存 编辑
看了後很有想法!
2007-09-03 08:57:00 | [匿名:千年之夏]
#回复: 理解缓存 编辑
看了後很有想法!
2007-09-03 08:55:00 | [匿名:.NET面试题]
#回复: 理解缓存 编辑
Myspace有一个不错的缓存机制。
2007-09-03 01:52:00 | [匿名:怡红公子]
#回复: 理解缓存 编辑
java中的hibernate还分一级缓存,二级缓存,.net的应该借鉴一下...
2007-09-02 21:45:00 | [匿名:wang]
#回复: 理解缓存 编辑
好文章 用好缓存不容易
2007-09-02 21:32:00 | [匿名:jecray]
#回复: 理解缓存 编辑
好帖子,这样实用性的帖子真的好!如果有时间讨论一下数据库设计方面的内容就好了!
2007-09-02 01:33:00 | [匿名:周巍 MyNameEPC]
#回复: 理解缓存 编辑
什么样的缓存是好缓存,但从 IO 角度上看,收益高的算是好的

2007-09-01 23:56:00 | [匿名:Fenng]
#回复: 理解缓存 编辑
但从--单从
2007-09-01 23:56:00 | [匿名:Fenng]
#回复: 理解缓存 编辑
同意缓存命中率的观点,可以建立一个数学模型来求解这个问题的.
在.net领域的很多开发人员就是这样的没有思想。不仅仅是缓存,你到博客园去看看就知道那里讨论最多的就是控件等等,很少涉及领域驱动建模阿等等的话题。
2007-09-01 22:04:00 | [匿名:shanyou]
#回复: 理解缓存 编辑
赞一个!
2007-09-01 21:48:00 | [匿名:宝玉]

发表留言

标题
姓名
邮件
主页
留言 

Powered by: Joycode.MVC引擎 0.5.2.0