Chinaunix

标题: 从案例引发的对缓存设计的思考,干货讨论,绝对不玩虚的(获奖名单已公布-2012-6-13) [打印本页]

作者: yanyangtian4502    时间: 2012-05-17 09:43
标题: 从案例引发的对缓存设计的思考,干货讨论,绝对不玩虚的(获奖名单已公布-2012-6-13)
获奖名单已公布,详情请看:http://bbs.chinaunix.net/thread-3752702-1-1.html

主题:从案例引发的对缓存设计的思考

背景: 谈到性能优化,势必要谈到缓存架构的设计与使用。几乎是所有人都知道缓存的威力,但是知道终归只是知道,如何真正合理的在自己的项目中进行使用,又是另外一回事了。我们团队为不少的公司的项目进行了性能与架构的优化,遇到了不少由于误用,滥用缓存带来的问题,这些项目的缓存不仅没有使得性能进行提示,反而成为了性能瓶颈。

缓存的使用,没有定论,没有所谓“一定,必须等XXX这样”,没有这样的金科玉律,一切都是“根据项目的实际情况而定”,但是,我们看到的情况并不是这样的,我们也问过很多的人,回答让我们吃惊“上网大家都这样的用的啊,XXX就应该是这样的啊”。机械式的照搬,不带头脑的瞎用,结果可想而知。我们本次的讨论,是实实在在的干货的讨论,会给出一些常用的策略和场景,大家可以根据情况使用,希望是“授之以渔”,而不是生搬硬套。

邀请嘉宾:刘鑫(Gray1982) 资深运维架构师,ChinaUnix社区集群和高可用版版主。

讨论大纲:
        不同项目中,你认为在哪里可以使用缓存(例如。以Web项目为例子)
        缓存的策略是什么
        如何设计比较智能的缓存
        缓存中数据以及不同数据带来的性能问题
        常见的缓存误区


活动有奖:闪迪8GU盘(共3个)奖励给分享实战案例、经验的热心网友。

欢迎大家参与讨论~!

作者: 无风之谷    时间: 2012-05-17 09:53
欢迎大家参与进来~!
作者: yanyangtian4502    时间: 2012-05-17 09:55
这样吧,我先开个头,大家可以一起参与!
我首先说说在项目中可以使用缓存的地方。

我这里用一个图可能表述的更加清楚!
如图:


不仅仅如此,还有数据库本身也会有缓存,而且操作系统也有会缓存一些数据。
所以,充分的使用好缓存,对性能提升相当的大。

我们就先讨论这个话题。
作者: yanyangtian4502    时间: 2012-05-17 09:58
如果大家开发的不是Web应用程序,例如,如果是一个桌面的应用,那么上面的结构图依然是可以使用的:把浏览器缓存 换为本地的数据缓存,而不用每次都去远端获取数据。
作者: yuhongchun    时间: 2012-05-17 10:01
提示: 作者被禁止或删除 内容自动屏蔽
作者: yanyangtian4502    时间: 2012-05-17 10:07
既然我们谈缓存这个话题,那么我们就把这个话题谈细致一点,因为很多时候:谈大帽子的话很多人都会滔滔不绝,但是一到真实的细节与落实的地方,很多人就偃旗息鼓了,呵呵 有点”吹起来,天下无敌;做起来,一无是处“的感觉。

我们首先就来看看浏览器的缓存。
这个好搞啊,做过网站的朋友都知道,这个设置主要就是通过设置:Cache-Control 这个响应头来实现的,如下:


不同的技术平台,实现的方式不一样,大家也不要纠结这些平台的差异,只要最后结果是一样的就OK了,要怀着包容心去看每一种技术,如果连技术的差异性都无法容忍,未必也太小家子气了,呵呵呵。

例如,在微软技术的ASP.NET中,可以通过几种方式来实现:
1.页面中设置,如下:


2.代码中设置,如下:


3.IIS中设置,如下:

作者: yanyangtian4502    时间: 2012-05-17 10:09
另外,浏览器缓存设置起来好搞,但是也是问题多多的!大家可以想到有啥问题吗?
作者: yanyangtian4502    时间: 2012-05-17 10:10
大家多多的参与啊,不然,这几个8G的U盘,我就替大家收了啊 嘿嘿
作者: yanyangtian4502    时间: 2012-05-17 10:16
大家有点羞涩啊,我接着唠嗑!

浏览器缓存可以缓存图片,js,css,当然,还可以把一些数据,通过js对象的形式保存在浏览器中。

浏览器缓存的问题主要在于图片,js,css的更新上面。

例如如果我们设置了缓存的时间为1一个月,那么这些资源很有可能就在一个月还没有到就因为我们发布新的版本而更新了。这个时候,浏览器不会知道的,还是会使用老的版本。
这不是我们希望看到的,解决的办法也是很简单,如果大家留心点,就会发现很多的站点的js,css是这样命名的:XXX-1.2.js

这就是通过版本控制来来使得浏览器重新下载新的资源。
作者: Gray1982    时间: 2012-05-17 10:19
稍微具体一点分为页面级缓存和数据层缓存
页面级的我们常用的是Varnish和Squid
数据层的多为KV当然也有分布式的,这就比较多了,Memcache、Redis、芒果、Cassandra等
作者: yanyangtian4502    时间: 2012-05-17 10:20
回复 10# Gray1982

对,这个已经到了后面的程序后台的缓存了,等会我会谈到那里!
现在还在前端跑着。呵呵呵


   
作者: yanyangtian4502    时间: 2012-05-17 10:23
加快速度把,刚刚又朋友谈到了分布缓存等内容,
那么就看看代理缓存,代理缓存基本是不需要我们的任何成本,只要我们设置了,并且代理那边可以缓存数据,就行了。
设置也非常的简单,把Cache-Control,设置为public就行了,private就只缓存在浏览器。

设置依然简单,但是用起来也是问题多多。

作者: yanyangtian4502    时间: 2012-05-17 10:36
哟,依然使我回答,好吧,大家以后就把这个帖子作为缓存的一个参考资料吧,呵呵呵!

代理缓存的问题,主要出现在三个方面:
1.安全
2.地区问题
3.内容更新问题

首先,对于安全问题,这是最大的问题:因为代理会把根据URL,把整个页面的数据缓存起来,其中就包括了响应头,那么就包含了cookie信息。问题就在这里啦,如果用户A登录之后,代理缓存了页面的响应,那么用户B在此请求相同的页面的时候,那么整个响应就会给B了,这个时候,用户B就可以以A的身份进去瞎搞了。

对于这个问题,没有办法解决,但是有办法避免:把一些不需要用户登录就可以访问的页面,特别是那些静态的内容的页面,可以设置代理缓存;涉及到用户验证才能看的页面,不要设置了。

其次,就是地区问题,
因为代理缓存了整个页面,而且是根据URL来匹配的,如果咱们中国人去访问一个页面,例如www.agilesharp.com/blog/12344,这个时候,代理缓存就把这个中文的页面内容缓存,如果我们的站点是支持多语言的,那么,此时,如果美国人去访问了同一个URL,那么这个时候,或许,请求不会提交给我们的服务器,代理就会把中文的页面内容给老美,那叫一个郁闷,是吧。

怎么办?呵呵,方法虽然鲜为人知,但是依然简单。
设置头信息:Accept-Language

在发送中文响应的时候,设置为:Accept-Language: zh-cn,那么代理缓存就会缓存这个版本的内容
如果是请求的英文,那么,老美的浏览器发送的请求的这个Accept-Language的信息就是 en-US,代理一看这样版本的内容没有,那么就会把请求交给我们的服务器了。

最后的结果就是代理中缓存了同一个页面的不同版本的内容。


作者: yanyangtian4502    时间: 2012-05-17 10:40
对于代理缓存,刚刚忘记说“3.内容更新问题“问题了。
这里补上。

内容更新问题:因为代理缓存了页面的所有数据,包括图片,js等等,那么即使我们的页面中的图片等更新了,但是客户端是无法知道的,除非缓存的之间过期了。这个问题,无法解决!
所以,要注意!!!!


作者: yanyangtian4502    时间: 2012-05-17 10:41
本帖最后由 yanyangtian4502 于 2012-05-17 10:49 编辑

好了,现在终于开始走到服务端了。重头戏来了!
我休息一会,大家发言啊!!!!多吐干货!不玩虚的啊
作者: kns1024wh    时间: 2012-05-17 11:13
不是一一个观点么  

提高site的性能 就是多Cache
作者: kns1024wh    时间: 2012-05-17 11:14
回复 1# yanyangtian4502


    如果使用cache 那就要考虑cache的命中率 以及 交互式的web2.0的 实时数据

作者: dengbao2001    时间: 2012-05-17 11:46
支持这样的活动!
作者: yanyangtian4502    时间: 2012-05-17 11:50
回复 18# dengbao2001

多谢认可!!

   
作者: yanyangtian4502    时间: 2012-05-17 11:57
本帖最后由 yanyangtian4502 于 2012-05-17 12:00 编辑

好了,现在到了服务器端了,首先看看内核缓存!
其实这个内核缓存就涉及到操作系统和宿主(IIS,Apache等)

说实在的,我对Windows操作系统和IIS比较了解,对其他的不清楚,但是我相信:原理和思想都是一样的!

我先以Windows和IIS为例子吧,说完之后,如果熟悉Liunx,Apache等其他平台的朋友,可以一并分享一下。

首先看一个图:


当一个请求被HTTP监听者(HTTP.sys)接受之后,它根据请求的URL进行匹配,然后马上就把请求放在一个内核模式的不同的队列中,以便这些请求可以被用户模式中的应用程序池中工作进程获取,然后处理。这里之所以要把请求放在队列中是为了快速的释放HTTP监听线程,从而使得HTTP.sys可以接受其他更多的请求。另外,请求被放在不同的队列,主要是根据请求的URL来分组的,并且应用程序池中也配置了处理何种URL。              

当响应产生之后,响应会被再次发送给HTTP.sys(大家可以看到图中第5个步骤),然后再把响应发送给客户端。HTTP.sys可以基于一些配置将响应进行缓存,我们会在后面进一步的讨论。
               

这里有一点非常中的就是:HTTP.sys将响应缓存在内核中,并且这个内核中的这个缓存空间是不分页的。
不分页就意味着HTTP.sys总是将响应的内容缓存物理的内存中,而且这一块内存不会被交换出去,就是说不会被分页到磁盘上面。这涉及到了Windows操作系统的内存管理机制,大家自学去吧,呵呵。

当请求的响应被缓存在了内核模式之后,下次再次请求的时候,可以直接的读取缓存,而后续的步骤全部跳过,这会极大的提升性能。


另外,有一点我这里要提到的就是一个传说“很多人常常说要使用静态,或者伪静态”。 我常常也在面试中问别人:为什么要这么搞?
很多人就是支支吾吾,瞎扯一通,最让我崩溃的回答就是“网上说的”。

大家想知道答案吗?
呵呵 我稍后回复

我提示一点:这一内核缓存相关
作者: yanyangtian4502    时间: 2012-05-17 13:38
本帖最后由 yanyangtian4502 于 2012-05-17 20:37 编辑

看来这个问题还得我回答啊

其实windows的内核会对一些常用访问的静态文件进行缓存,把一些网页静态化,就是利用这一点,从而避免了页面动态生成的过程。但是要注意磁盘的容量问题以及文件的增长速度。

伪静态 不会缓存在内核中。

另外,如果采用了多台服务器,要考虑到文件之间的同步。


另外一个,就涉及到SEO的问题了。搜索引擎对静态页面比较的感兴趣,不过现在这方面可以不用这么管了,现在的引擎都智能的很。


作者: yanyangtian4502    时间: 2012-05-17 13:52
我们可以在windows服务器上运行下面的命令查看内核缓存的情况:
netsh http show cachestate

除了内核缓存之后,另外还有就是宿主的缓存,例如IIS,apache,这样的进程在运行的时候,也会把一些常用用的数据缓存起来,这一点,主要是通过修改相关的配置文件来实现,或者通过一些GUI来方便的配置。

例如,对于IIS而言,可以去applicationHost.config(IIS 7)中修改哪些文件可以缓存,默认是静态的,但是我们也可以使得动态页面的内容缓存。如下:



作者: yanyangtian4502    时间: 2012-05-17 13:55
我现在就坐等Liunx的朋友 说说相关的内容啊
作者: Gray1982    时间: 2012-05-17 15:50
yanyangtian4502 发表于 2012-05-17 13:52
我们可以在windows服务器上运行下面的命令查看内核缓存的情况:
netsh http show cachestate


这Windows的配置真多,IIS我是好久没搞了,一直Linux
在WEB也就是页面级缓存,常用的Varnish,Squid,Nginx+第三方模块
这三个怎么配置论坛里N多就不多说了
Varnish可以使用内存来处理缓存,这是一个很不错的选择
Nginx在小量的缓存应用上也是很理想,而且支持多CPU
作者: Gray1982    时间: 2012-05-17 15:55
yanyangtian4502 发表于 2012-05-17 10:07
既然我们谈缓存这个话题,那么我们就把这个话题谈细致一点,因为很多时候:谈大帽子的话很多人都会滔滔不绝 ...



http头的软件嘛,如果一般开发不写的话,都是缓存上的
特殊需求的话,咱们也会配置规则对各种不同类型的文件进行不同时间的缓存
常用的也就是301 302这种转向的配置

缓存一些文件什么的不是到重点,因为它本身就是做这个的,而且有N多规则。主要是根据公司的需要去开发需要的功能,比如日志模式,这比较常见。

作者: yanyangtian4502    时间: 2012-05-17 16:10
回复 24# Gray1982
这些东西不错!
选择也比较多!

   
作者: yanyangtian4502    时间: 2012-05-17 16:18
说完了服务端的内核缓存,宿主缓存之后,可以说说应用层的数据缓存了!
这里 就引入下面的话题:

1. 缓存的策略是什么
2.如何设计比较智能的缓存

至于缓存什么数据,这就不用我说了,因为网络已经有了一大堆人在讨论,也是见仁见智。

那么,我这就说说 我在优化的过程中为一些企业的项目选项的缓存的策略,即如何缓存数据,使得缓存的数据尽可能多的被命中,而且尽可能少的使用内存(即,只缓存必要的数据)。

作者: yanyangtian4502    时间: 2012-05-17 16:33
本帖最后由 yanyangtian4502 于 2012-05-17 16:35 编辑

缓存的策略是什么

我这里自己将其总结为三个:
1.全缓存
2.半缓存
3.基于统计的缓存

为了说明这个问题,我这里以分页为例子来说明这个问题,我这里给出一个图,就是平时我们看到的分页的图,


很多的时候,在大量数据展示的过程中,我们总是喜欢分页展示,那个,如何设计这个分页的。

当然,我们完全可以一页页的去数据库中获取相应的数据,但是很多的时候,我们不是这样做的,例如,每页数据有20条,我们可能会实现预加载100条数据在缓存中,每次展示将一页的数据进行展示。

下面,就开始说说这个“全缓存”。

接着上面的分页的例子,我们预先取来100条,然后用户就不断的翻页,此时,如果用户翻到了第6页,或者后面,此时,我们没有缓存后面的数据,此时,我们就开始再次去获取100条数据,那么此时,在缓存中就有了200条,并且是从1到10页的。以此类推,我将之定义为“全缓存“,因为最后的结果将会缓存用户查看的所有数据。(其实,很少有用户想翻到后面的十几页去的)

这种策略非常常用,但是不可滥用,要针对不同的类型的应用,并且还得看数据变化的频率。因为稍不注意,就是内存使用过多了。

这种方式最理想的利用场景在站点没有搜索功能,并且通过类似Tag标签来代替查询的项目中。如图的例子:


现在的很多的站点不能没有搜索功能,当然,我们可以酌情的考虑使用这种方式。我们后面会介绍将这个方法与其他的结合起来,构造更加智能的策略。
作者: Gray1982    时间: 2012-05-17 16:52
本帖最后由 Gray1982 于 2012-06-15 14:14 编辑

回复 26# yanyangtian4502


   嗯,个人觉得在Linux上,各种开源的软件比较多,而且选择范围比较大
一大部分都是C来做二次开发的,比较自由的改动

在Linux内核方面,如果你不更改,一般只参数就够了
作者: expert1    时间: 2012-05-17 18:26
回复 13# yanyangtian4502


    very good
作者: starzhestarzhe    时间: 2012-05-17 18:26
版主好勤快,友情支持下

数据库的索引缓存,对于关系型数据库,所设置的缓存尽量能把各表的索引全部缓存
以mysql为例,mysql的索引结构主要是B+树,叶结点存放着数据(非聚集索引存放主键),B+树高度一般为2-3,经过一个高度查找为一次IO,在硬盘上体现为一次随机读,所以把这个操作在内存中进行对性能会有一定的提升.

抛砖引玉
作者: 方兆国    时间: 2012-05-17 18:58
回复 4# yanyangtian4502


   典型例子就是 富因特网应用程序(Rich Internet Applications,RIA),其实我感觉只要是能上网的程序,大多是这样,把一些变化不大的内容长期存在客户端。
而且像网易的Yeah.net邮箱,在火狐等支持HTML5的浏览器中还可以存储邮件等信息,加快访问速度
作者: Moon_Bird    时间: 2012-05-17 19:09
不错,学习了。刚刚才开始接触 memcached
作者: 方兆国    时间: 2012-05-17 19:36
回复 4# yanyangtian4502


    这个方面,浏览器支持HTML5就更好了,像HTML4好像不支持太多的数据缓存吧。有图片为例

一个是Firefox11.0,一个是IE8





作者: 方兆国    时间: 2012-05-17 20:15
回复 8# yanyangtian4502


    很多书上都说JSP的运行效率很高,但是JSP的网页很少能看到,而且提供虚拟主机的网站都是仅仅区分PHP和ASP.NET,完全忽略JSP,我一直很好奇……
作者: 方兆国    时间: 2012-05-17 20:22
回复 13# yanyangtian4502


    你的那个网站是APS作的,可是主页打开的速度比较慢,ip地址是 59.173.12.209,位于湖北省武汉市,用的电信的网
作者: 方兆国    时间: 2012-05-17 20:27
另外,有一点我这里要提到的就是一个传说“很多人常常说要使用静态,或者伪静态”。 我常常也在面试中问别人:为什么要这么搞?


伪静态就是为了让搜索引擎收录,不过会降低系统的性能。我用Nginx和Tomcat弄了好半天没有成功,只能用反向代理来让主页变化,或者跳转到Tomcat服务的页面上
  1. upstream localServer
  2.         {
  3.                 #server 127.0.0.1:8080;
  4.         }
复制代码
回复 20# yanyangtian4502


   
作者: 方兆国    时间: 2012-05-17 20:28
回复 21# yanyangtian4502


    伪静态不产生实际页面的啊,不会象你说得缓存页面吧,它只是简单的替换显示的URL而已
作者: yanyangtian4502    时间: 2012-05-17 20:35
回复 38# 方兆国

伪静态 没有用到内核缓存

   
作者: yanyangtian4502    时间: 2012-05-17 20:37
回复 34# 方兆国


    这与浏览器本地缓存没有联系
作者: 方兆国    时间: 2012-05-17 20:40
回复 40# yanyangtian4502


不支持html5的浏览器不支持这种类型的缓存……(这个理由不算么)
作者: 方兆国    时间: 2012-05-17 20:44
回复 39# yanyangtian4502


    额,前一段儿时间看到一哥们自己的个人网站是html的,源代码中有php的扩展名,问他,他说是伪静态,才看这个。百度百科上说伪静态的作用就是让搜索引擎更容易收录。也能是那个词条有些老了
作者: chenyx    时间: 2012-05-17 21:11
回复 42# 方兆国


    这个伪静态,就是利用web服务器的rewrite功能,其后台依然是php或者其他web脚本语言
作者: chenyx    时间: 2012-05-17 21:15
回复 1# yanyangtian4502


    现在主要用nginx的反向代理+负载均衡功能,缓存是nginx的一个"辅助"功能,主要缓存的是图片,js,css等很场时间不会变化的东西.至于缓存的更新,nginx有个第三方的模块,可以通过浏览器手工清除,下次client访问的时候,就会自动缓存了.
作者: 方兆国    时间: 2012-05-17 21:41
回复 43# chenyx


    rewrite好像得要插件吧。我的Apache用ajp方式链接Tomcat,重写jsp,不成功
作者: 方兆国    时间: 2012-05-17 21:43
回复 44# chenyx


    我可以理解为反向代理就是为负载均衡服务的吗?一般每人设置一个刷新一下就变样子的网页吧……
作者: chenyx    时间: 2012-05-17 21:43
一般安装rpm完apache,rewrite模块就安装好了.
作者: 方兆国    时间: 2012-05-17 21:45
回复 47# chenyx


    我是Windows的。因为Windows下没安PHP,不确定是不是Apache不能rewrite JSP
作者: 方兆国    时间: 2012-05-17 21:46
回复 47# chenyx


    mod_rewrite.so我这儿有,可能是配置有问题
作者: 方兆国    时间: 2012-05-17 21:47
回复 47# chenyx


    我也只是看着网上的资料作的,由于我是拿JSP测试的,所以不成功,网上的例子都是PHP的
作者: chenyx    时间: 2012-05-17 21:51
本帖最后由 chenyx 于 2012-05-17 21:51 编辑

这个你可以测试下,我的服务器没用jsp.
不过,php和jsp不同,php是apache的模块,而jsp(tomcat)是另外的服务,感觉实现rewrite有困难
作者: 方兆国    时间: 2012-05-17 21:53
回复 51# chenyx


    很少有网站用JSP,很怪异,书上说JSP效率高,应该很流行的啊,而且跨平台
作者: chenyx    时间: 2012-05-17 21:54
很多大型的网站用的是jsp,比如很多银行,电信的网站.
但是他们用的应该不是tomcat,应该是专业的jsp服务器软件.
作者: 方兆国    时间: 2012-05-17 22:05
回复 53# chenyx


我一直对这个很好奇,谢谢你的回答

    JSP不也是免费的吗?
作者: chenyx    时间: 2012-05-17 22:09
本帖最后由 chenyx 于 2012-05-17 22:09 编辑

tomcat免费的,其他的没用过,应该不是免费的
作者: 方兆国    时间: 2012-05-17 22:13
回复 53# chenyx


    招商银行和工商银行用的是ASP,建设银行是JSP,农业银行是什么都看不出来,全是html,不过代码貌似是手写的,不像有些网站的源代码直接一大坨
作者: chenyx    时间: 2012-05-17 22:22
这个,有交互的功能,一定有后台支持动态的组件,不论是asp,jsp,php或者其他cgi等
作者: 方兆国    时间: 2012-05-17 22:41
回复 55# chenyx


    额,怪不得有人说JSP成本高
作者: 方兆国    时间: 2012-05-17 22:44
回复 57# chenyx


    农业银行一点儿破绽都看不出来,其他的,从超链接就能看出来
作者: chenyx    时间: 2012-05-17 23:03
你可以找个有输入的页面,看看页面的源代码,那个form的action后面的就是需要的后台程序
作者: 方兆国    时间: 2012-05-17 23:04
回复 60# chenyx


    额,我只是在主页上大概看了一下
作者: 方兆国    时间: 2012-05-17 23:08
回复 60# chenyx


    看到了,农业银行是ASP的
作者: coralzd    时间: 2012-05-18 08:53
Gray1982 发表于 2012-05-17 15:50
这Windows的配置真多,IIS我是好久没搞了,一直Linux
在WEB也就是页面级缓存,常用的Varnish,Squid, ...

刘鑫兄,我也知道nginx 缓存少量不错,但是这个少量怎么限定呢?按照文件数还是空间?希望不啬赐教
作者: yanyangtian4502    时间: 2012-05-18 10:04
大家回复的比较踊跃,但是,这么感觉和主题不这么相符合,
我还是继续按照之前的来说把。

2.半缓存
其实这个缓存策略,是这样的:

例如用户在查询某些数据的时候,我们把前几页的数据,假设100条,每页是20条,我们就把前5页的数据缓存起来,如果用户翻页翻到了第6页,或者更后面,那么,我们就单独的去取那一页的数据,但是取出来之后不缓存,
之所以这么做,主要是:很少有用户那么有耐心一直的翻页,很多时候,用户看前3页的数据就了不得了。

这种缓存的策略,应该非常实用,如果站点的搜索功能是主要的功能,那么,这个策略可以在内存和性能方面取得平衡。
作者: yanyangtian4502    时间: 2012-05-18 10:12
我还是把这三种缓存策略说完,现在说说第三种:
3.基于统计的缓存

顾名思义,就是收集一定的信息,然后做出分析,利用分析的结果来有效的缓存数据。

这里,我以电子商务为例子,例如用户在搜索某产品,那么,我们就把每次用户输入的一些条件的关键字收集起来进行分析,然后对关键字出现频率进行统计分析,
之后,就得出那些出现频率比较高的关键字,然后就把这些关键字对应的产品缓存起来,至于如何缓存这些数据,这个时候,完全可以结合之前的“全缓存”和“半缓存“策略一起使用。

那么,当用户在查找产品的时候,如果他输入的关键字在缓存中的缓存键之中,那么,就把数据返回给用户。

这里,我们完全可以发挥更多的思考:例如,更加关键字出现的不同频率设置不同的缓存时间。那么实现起来可能稍微麻烦一点。

但是,这样的缓存策略依然可以进一步的改进,我们在后面会谈到这个问题的。
作者: Gray1982    时间: 2012-05-18 12:06
回复 63# coralzd

简单的说
一是需要看缓存文件的数量,大小,也就是看IO是不是目前的瓶颈
一是看并发访问的数量
作者: Gray1982    时间: 2012-05-18 12:08
yanyangtian4502 发表于 2012-05-18 10:04
大家回复的比较踊跃,但是,这么感觉和主题不这么相符合,
我还是继续按照之前的来说把。


这个好像是预读吧???像UC就是可以把下页的内容预读存越来。
作者: lsstarboy    时间: 2012-05-18 22:44
本帖最后由 lsstarboy 于 2012-05-18 22:51 编辑

简单说一下LAMP(其实我最常用的是FAMP,F代表FreeBSD)中用对缓存有印象的地方:

1、php加速器的的缓存,比如Xcache,不要以为它们只是加速器,只是对php进行了“预编译”,其实它们还提供了一部分缓存。就Xcache来说,它提供了一系列的函数来进行缓存,大多数的php框架系统都已经利用这个功能,但是这些框架都很小心地使用这部分缓存,一般只是用来缓存配置,因为无法确定它的大小,一旦需要量超过这部分内存的大小,那么将出现大的问题。如果是自己搞的系统,并且内存足够大,完全可以把它弄大一些。它不仅可以缓存配置,还可以缓存数据库的查询,甚至可以把一些公用的页面部分缓存进去,比如网页的header、footer等。Xcache专门提供了一个页面来监测这部分内存的使用,统计中还包括了命中率,这对分析网站的性能很有帮助。

2、文件缓存和数据库查询的IO平衡:有很多时候必须使用文件缓存,想避开频繁的数据库查询,但是如果在程序中对文件控制不当,就会使缓存的文件数量比较多,造成了频繁的IO,结果还不如使用数据库来的快。如果发现缓存目录中有成千上万个文件,那还是把它们塞进数据库中要好一些。
  同样情况的还有tcp的生存时间,多大才是最佳的?在访问量大的服务器上,如果做的太大,将会导致大量的半连接,如果做的太小,连接能力上来了,但是传输大文件的时候却又慢下来。


3、Mysql可以用很大的缓存,只要机器有空余的内存,可以分配给mysql好几个G,它都会好好利用,不要吝啬内存,也不要怀疑mysql管理缓存的能力。

4、具体到FreeBSD的防火墙,在默认情况下,做状态规则(也类似于缓存的规则)时,访问量稍大点就会把服务器搞得拒绝服务,所以大多数情况下都是关闭防火墙,特别是ipfw,更是典型(后来才发现ipfw默认只开了4K的状态规则)。
作者: 276158394    时间: 2012-05-19 07:40
嗯·你写的已经很详细了·我也在细心阅读和学习中·你们有什么联系方式吗?我们以后好联系交流啊·当然有什么事情可以再论坛上发表的·
作者: chenyx    时间: 2012-05-19 08:15
yanyangtian4502 发表于 2012-05-18 10:04
大家回复的比较踊跃,但是,这么感觉和主题不这么相符合,
我还是继续按照之前的来说把。

这个想法很奇特.
一般的缓存策略,是前端有squid之类的缓存服务,后端做伪静态,楼主的那个是如何实现N页之后不缓存的,请教下.
作者: chenyx    时间: 2012-05-19 08:16
lsstarboy 发表于 2012-05-18 22:44
简单说一下LAMP(其实我最常用的是FAMP,F代表FreeBSD)中用对缓存有印象的地方:

1、php加速器的的缓存 ...

赞同,mysql的缓存能力还是很强的.
作者: 方兆国    时间: 2012-05-19 17:12
回复 68# lsstarboy


    现在Nginx很流行,我听过这样的叫法LNMP
作者: lsstarboy    时间: 2012-05-19 18:19
本帖最后由 lsstarboy 于 2012-05-19 18:20 编辑

回复 72# 方兆国


    用在FreeBSD上叫FNMP,呵呵,我最喜欢这么用了,不过一直没研究过nginx的缓存功能,不知道对性能影响大不?
作者: Gray1982    时间: 2012-05-19 23:09
回复 71# chenyx


    加上Googletool效果会更好
作者: Gray1982    时间: 2012-05-19 23:11
回复 72# 方兆国


    行,真佩服你
是有这总说法,就像我说的varnish squid nginx这3种页面层的,看实际情况需要
作者: Gray1982    时间: 2012-05-19 23:25
lsstarboy 发表于 2012-05-18 22:44
简单说一下LAMP(其实我最常用的是FAMP,F代表FreeBSD)中用对缓存有印象的地方:

1、php加速器的的缓存 ...

作者: lsstarboy    时间: 2012-05-20 12:34
回复 74# Gray1982


    Googletool是啥东东,讲一下呗!
作者: 方兆国    时间: 2012-05-20 15:57
回复 77# lsstarboy


    我百度了一下google tool没有相关内容,仅有google toolbar
作者: 方兆国    时间: 2012-05-20 23:43
回复 73# lsstarboy


    我发现在Apache2.2中没必要设置伪静态,直接把PHP文件的扩展名设置为html,照样可以解析
作者: rdcwayx    时间: 2012-05-21 12:15
我只谈谈我自己的经验,非产品推销啊。因为代理缓存业务都是外包给其他专业公司,所以我也只能大致了解一些。

        不同项目中,你认为在哪里可以使用缓存。
以Web项目为例子, 我接触的公司有家使用AKAMAI公司的产品做Web代理,缓存公司门户网站,公司本身web服务器只在一个数据中心(物理位置),但依靠AKAMAI全球各地布控缓存服务器,保证世界各地用户的访问快速,一致。
        缓存的策略是什么
负载平衡,页面访问加速。
        如何设计比较智能的缓存
因为是外包,有专业公司专门做代理缓存,其本身就很智能,否则收不到钱啊。 ,其内部设计就不是太了解,这个可以看其公开的文档资料。当然本身的web服务器,后台数据库也会开启缓存,这个上面已经提过。
智能设计方面,我们能做的,只是每次有新的更新,都要运行一次akamai refresh,手动刷新缓存。
        缓存中数据以及不同数据带来的性能问题
akamai主要是静态页面缓存,web 服务器带页面自动压缩和解压功能以减少loading的时间。
        常见的缓存误区
CPU,内存,硬盘要多而快,这个不一定,还是需要一定的调优过程。这些要慢慢摸索。根据不同的访问业务已经访问量的改变在缺省的参数上做调整。
作者: yanyangtian4502    时间: 2012-05-21 16:33
呵呵呵,我又来了!
朋友们之前谈了Apache,Nigx等,虽然我不同非常的懂,但愿我的一些帖子起到抛砖引玉的效果!

那我接着谈
如何设计比较智能的缓存

很多的时候,我们再添加缓存的时候,采用的是键值对的形式,
例如
key                 value
demokey          demoValue

很多的缓存组件,也是采用字典的形式进行数据的存取的。

我们在获取缓存中的数据的时候,也是通过这样的方式,例如get("demokey")

这样的方式,没有问题。但是如果需要缓存一些比较动态的信息,例如:根据用户的查询关键字来缓存数据,那么问题就出来了。

试想这样一个场景:在购物站点中,用户在查找产品的时候,肯定会输入很多的不同的关键字,而每次用户查询的关键字对应的产品有很多,而我们采用之前讲述的“全缓存,半缓存”等策略的时候,这个缓存就不是很高效。

举个例子,如果用户查询“海尔冰箱”,那么,我们在缓存中数据就是这样的:
key                   value
海尔冰箱          XXXXX(表示很多的数据)

如果用户再输入“冰箱”,那么此时,缓存结果为:
key                    value
海尔冰箱          XXXXX(表示很多的数据)
冰箱              YYYYYY(表示很多的数据)

以此类推.

其实”海尔冰箱“与”冰箱“有相似之处,或者换句话说:冰箱的结果,可能会包含”海尔冰箱“中的数据。

此时,我们很有可能就把两份数据缓存了两次。浪费了内存!

如何处理???

作者: lsstarboy    时间: 2012-05-22 11:29
回复 79# 方兆国


    这个根据配置不同会有不同结果,很容易暴露源代码,并且在nginx下此路不通,所以还是扩展名为php为好。
作者: 方兆国    时间: 2012-05-22 11:56
回复 82# lsstarboy


    我测试了,Nginx下确实不可以,不过,你说得那个暴露源代码,我不认可






对于index.html文件

我的源代码
  1. <html>
  2.         <body>
  3.                 <?php
  4.                         echo "PHP and Apache2.2 is working !";
  5.                 ?>
  6.                 <a href="./test.html">test</a>
  7.         </body>
  8. </html>
复制代码
浏览器中的源代码
  1. <html>
  2.         <body>
  3.                 PHP and Apache2.2 is working !                <a href="./test.html">test</a>
  4.         </body>
  5. </html>
复制代码
对于test.html文件

我的源代码
  1. <html>
  2.         <body>
  3.                 <?php
  4.                         echo "Test is OK !";
  5.                 ?>
  6.         </body>
  7. </html>
复制代码
浏览器中的源代码
  1. <html>
  2.         <body>
  3.                 Test is OK !        </body>
  4. </html>
复制代码

作者: lsstarboy    时间: 2012-05-22 18:11
本帖最后由 lsstarboy 于 2012-05-22 18:16 编辑

回复 83# 方兆国


    直接上图:


作者: 飞鸿无痕    时间: 2012-05-23 09:15
本帖最后由 飞鸿无痕 于 2012-05-23 09:17 编辑

讨论很热烈,楼主辛苦,看了了所有回复,收益匪浅。看到很少人提到现在linux下比较流行的lnmp架构的相关缓存情况,我这里稍微总结一下:
缓存顺序从前端(或者CDN)---代理---web server--memcache缓存--DB,从目前我较常用的架构来说:
前端缓存:我们可以设置squid、varnish缓存,这两个太常用就不详细解释了。如果公司出点钱,用CDN的效果更好。目前我们用的CDN。
代理缓存:通过nginx做代理,在上面配置expires来在客户端缓存一些图片以及js、css文件,注意图片可以设置过期时间长一点,js、css文件不要设置太长。nginx上也有自带的缓存,这个根据需要启用,如果有前端缓存就不需要在这里设置缓存了,如果前端没有设置,这里设置会取到比较好的效果。
web server缓存:楼主说的内核缓存是一方面,另外还有一些低三方的缓存,比如php的xcache以及eaccelerator等加速器,都能对php进行预编译,并执行计划进行缓存。
memcache缓存:采用memcache来缓存数据库的查询结果,尽量将压力往前推,减少数据库的压力。
DB缓存:DB缓存的就是开启query_cache。这里有一个陷阱:如果是更新非常频繁的表最好使用SQL_NO_CACHE不缓存结构,不然会频繁更新query cache内容,导致性能下降!
就说那么多,欢迎高手拍砖!

作者: sytpb    时间: 2012-05-23 09:27
学习一下,好久没来了。
作者: 飞鸿无痕    时间: 2012-05-23 11:18
回复 81# yanyangtian4502


    对这个没啥经验,期待楼主分享!
作者: Gray1982    时间: 2012-05-23 13:43
飞鸿无痕 发表于 2012-05-23 09:15
讨论很热烈,楼主辛苦,看了了所有回复,收益匪浅。看到很少人提到现在linux下比较流行的lnmp架构的相关缓存 ...



DB缓存真的会像你说的那样???
作者: chenjintao_ii    时间: 2012-05-23 13:56
回复 85# 飞鸿无痕


    看了所有留言,新学很多词汇,正一头雾水,飞鸿兄的总结来得正是时候啊。上网大致查了各种web服务器,总算有些对号入座了。
本人能看到这个帖子,主要得感谢一个打不开的网页:

nginx.png (5.91 KB, 下载次数: 56)

nginx.png

作者: lsstarboy    时间: 2012-05-23 14:51
回复 89# chenjintao_ii


    nginx的502错误确实很让人头疼,有多种原因,最常见的是php没有执行完或者是数据库返回数据不及时,一般日志里有说明,应该根据不同情况进行调整。
作者: yanyangtian4502    时间: 2012-05-23 18:25
趁大家下班 我也有点时间  发个帖子
大家还记得我之前说的那个问题吧,去参看这个:http://bbs.chinaunix.net/forum.p ... mp;fromuid=23458341

在使用缓存的时候,不管是分布式的还是非分布式的,我在查找缓存键的时候,可以采用“相似度匹配”算法进行,
我这里还是举个例子,假设在缓存中存在下面的数据:

key                              value
电冰箱                 XXXXX
容声冰箱               XXXXXXX
海尔电冰箱             XXXXXXXXXX


好,假设缓存中存在上面的数据,
那么,一般我采用缓存的时候,就是调用API,例如get("电冰箱"),来获取数据,
那么 现在我们不这么做了,而是采用相似度算法来进行,
例如,如果用户输入“冰箱”,然后查找,那么,
我们可以将用户输入的这个“冰箱”与缓存中的所有缓存键进行相似度的比较,按照相似度排序,然后我们可以自己决定如何返回数据,例如,将相似度最大的缓存键 对应的数据返回,我们可以设置一个阀值,例如,例如98%,将相似度>98%的所有缓存键对应的数据全部取出。

同时,我们也可以结合关键键的查询频率来进一步的约束返回的数据。这些都是很流行的思路。

所以,同样的东西,不一样的人使用,思路不一样,效果也是不同!

作者: 方兆国    时间: 2012-05-23 19:53
回复 84# lsstarboy


    为啥我的没有这种现象呢?我用讯雷下到的php文件还是没有php源代码的
作者: 方兆国    时间: 2012-05-23 19:58
回复 90# lsstarboy


    原来这个是Nginx的问题呀,我还一直很好奇,为什么我本机做虚拟服务器居然有502错误
作者: 飞鸿无痕    时间: 2012-05-24 09:49
回复 88# Gray1982


    是的,你可以弄个环境测试一下。
作者: 飞鸿无痕    时间: 2012-05-24 09:56
回复 89# chenjintao_ii


    大部分的502都不是nginx自己的错误,比如后端的cgi没有返回,进程僵死,脚本执行超时等等,nginx把错误都揽了过来。呵呵!
作者: Gray1982    时间: 2012-05-24 11:30
本帖最后由 Gray1982 于 2012-06-15 14:19 编辑

回复 94# 飞鸿无痕


    可能我这边没那么大家数据量,所以没发现这个问题
作者: Gray1982    时间: 2012-05-24 11:31
回复 93# 方兆国


    我的书里说过 是后面的原因
作者: chenjintao_ii    时间: 2012-05-24 15:05
飞鸿无痕 发表于 2012-05-24 09:56
回复 89# chenjintao_ii


我是进了一个投票网站,点击“提交”按钮后,浏览器给出这个回复的。朋友让我帮他投下票,而且有人投票成功,说明这个网站能够正常运行,只是不给我面子。
作者: dynamiclu    时间: 2012-05-24 15:35
本帖最后由 dynamiclu 于 2012-05-24 15:36 编辑

缓存设计:
           1. 缓存数据的增、清、改逻辑模型
           2. 热度数据大小、过期时间
           3. 缓存的持久化或半持久化


缓存的种类:
           1. 页面缓存
           2. 单个对象缓存
           3. 列表缓存
           4. 长度缓存(当记数器用)
               5. 散列的缓存


如附件 PPT 下载

缓存基础.zip

786.17 KB, 下载次数: 123


作者: 方兆国    时间: 2012-05-24 20:05
回复 97# Gray1982


    你的书?那本儿?




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2