收藏本站腾讯微博新浪微博

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 网站开通淘帖功能 - 蓝色理想插件 论坛内容导读一页看论坛 - 给官方提建议

论坛活动及任务 地图和邮件任务 请多用悬赏提问 热夏来袭,选一款蓝色理想的个性T恤吧!

手机上论坛,使用APP获得更好体验 急需前端攻城狮,获得内部推荐机会 论坛开通淘帖功能,收藏终于可以分类了!

搜索
查看: 6623|回复: 21

[php] PHP企业级应用之常见缓存技术篇

[复制链接]
发表于 2009-4-8 22:33:55 | 显示全部楼层 |阅读模式
别每天OO,这个配置怎么改,这段代码哪错了,没劲,好的程序不光是代码写的好,整体架构很重要,多了解程序之外的东西,这篇不再单单是程序方面的东西了,会写到从程序到服务器的设置,会比较多,但个人的经验有限,知道的就这么多,不知道的我也没法写呀, 文章说的不好大家就当我说梦话得了。
所有程序例子都来自网络

普遍缓存技术

数据缓存:这里所说的数据缓存是指数据库查询缓存,每次访问页面的时候,都会先检测相应的缓存数据是否存在,如果不存在,就连接数据库,得到数据,并把查询结果序列化后保存到文件中,以后同样的查询结果就直接从缓存表或文件中获得。

用的最广的例子看Discuz的搜索功能,把结果ID缓存到一个表中,下次搜索相同关键字时先搜索缓存表。

举个常用的方法,多表关联的时候,把附表中的内容生成数组保存到主表的一个字段中,需要的时候数组分解一下,这样的好处是只读一个表,坏处就是两个数据同步会多不少步骤,数据库永远是瓶颈,用硬盘换速度,是这个的关键点。

页面缓存:
每次访问页面的时候,都会先检测相应的缓存页面文件是否存在,如果不存在,就连接数据库,得到数据,显示页面并同时生成缓存页面文件,这样下次访问的时候页面文件就发挥作用了。(模板引擎和网上常见的一些缓存类通常有此功能)

时间触发缓存:
检查文件是否存在并且时间戳小于设置的过期时间,如果文件修改的时间戳比当前时间戳减去过期时间戳大,那么就用缓存,否则更新缓存。

内容触发缓存:
当插入数据或更新数据时,强制更新缓存。

静态缓存
这里所说的静态缓存是指静态化,直接生成HTML或XML等文本文件,有更新的时候重生成一次,适合于不太变化的页面,这就不说了。

以上内容是代码级的解决方案,我直接CP别的框架,也懒得改,内容都差不多,很容易就做到,而且会几种方式一起用,但下面的内容是服务器端的缓存方案,非代码级的,要有多方的合作才能做到

内存缓存:
Memcached是高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度。

这里说下Memcached的例子

  1. <?php
  2. $memcache = new Memcache;
  3. $memcache->connect('localhost', 11211) or die ("Could not connect");
  4. $version = $memcache->getVersion();
  5. echo "Server's version: ".$version."\n";
  6. $tmp_object = new stdClass;
  7. $tmp_object->str_attr = 'test';
  8. $tmp_object->int_attr = 123;
  9. $memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server");
  10. echo "Store data in the cache (data will expire in 10 seconds)\n";
  11. $get_result = $memcache->get('key');
  12. echo "Data from the cache:\n";
  13. var_dump($get_result);
  14. ?>
复制代码

读库的例子
  1. <?php
  2. $sql = 'SELECT * FROM users';
  3. $key = md5($sql);   //memcached 对象标识符
  4. if ( !($datas = $mc->get($key)) ) {
  5.     //  在 memcached 中未获取到缓存数据,则使用数据库查询获取记录集。
  6.     echo "n".str_pad('Read datas from MySQL.', 60, '_')."n";
  7.     $conn = mysql_connect('localhost', 'test', 'test');
  8.     mysql_select_db('test');
  9.     $result = mysql_query($sql);
  10.     while ($row = mysql_fetch_object($result))
  11.         $datas[] = $row;
  12.     //  将数据库中获取到的结果集数据保存到 memcached 中,以供下次访问时使用。
  13.     $mc->add($key, $datas);
  14. } else {
  15.     echo "n".str_pad('Read datas from memcached.', 60, '_')."n";
  16. }
  17. var_dump($datas);
  18. ?>
复制代码


php的缓冲器:
有eaccelerator, apc, phpa,xcache,这个这个就不说了吧,搜索一堆一堆的,自己看啦,知道有这玩意就OK

MYSQL缓存:
这也算非代码级的,经典的数据库就是用的这种方式,看下面的运行时间,0.09xxx之类的
我贴段根据蓝色那家伙修改后部分my.ini吧,2G的MYISAM表可以在0.05S左右,据说他前后改了有快一年

 提示:您可以先修改部分代码再运行



基于反向代理的Web缓存:
如Nginx,SQUID,mod_proxy(apache2以上又分为mod_proxy和mod_cache)
NGINX的例子

 提示:您可以先修改部分代码再运行


mod_proxy的例子

  1. <VirtualHost *>
  2. ServerName www.zxsv.com
  3. ServerAdmin admin@zxsv.com
  4. # reverse proxy setting
  5. ProxyPass / http://www.zxsv.com:8080/
  6. ProxyPassReverse / http://www.zxsv.com:8080/
  7. # cache dir root
  8. CacheRoot "/var/www/proxy"
  9. # max cache storage
  10. CacheSize 50000000
  11. # hour: every 4 hour
  12. CacheGcInterval 4
  13. # max page expire time: hour
  14. CacheMaxExpire 240
  15. # Expire time = (now - last_modified) * CacheLastModifiedFactor
  16. CacheLastModifiedFactor 0.1
  17. # defalt expire tag: hour
  18. CacheDefaultExpire 1
  19. # force complete after precent of content retrived: 60-90%
  20. CacheForceCompletion 80
  21. CustomLog /usr/local/apache/logs/dev_access_log combined
  22. </VirtualHost>
复制代码

而SQUID的例子我就不说明了,这方面网上有写的太多,大家自己搜索一下

DNS轮询:
BIND是一款开放源码的DNS服务器软件,这个要说起来就大了,自己搜索去,大家知道有这个东西就行了。
我知道的有chinacache等大站就是这样做的,说简单点就是多服务器啦,把同一个页面或文件缓存到不同的服务器上,按南北自动解析到相关的服务器中

[[i] 本帖最后由 剑气凌人 于 2009-4-10 00:28 编辑 ]
发表于 2009-4-9 07:20:30 | 显示全部楼层
数据缓存和页面缓存不是同为文件缓存系统么?
如果按照你的这个说法,那我的地理位置,用户组,系统配置之类的东西,不也都是数据缓存?

另外在discuz模板引擎 从htm生成php应该算在哪个里面?论数据缓存,不是..论页面缓存,他还是要执行php..
感觉这样的分类不能涵盖全部的缓存机制...

我个人倾向于这篇文章的分类
http://www.ccvita.com/45.html

不厚道的说一句:这感觉上只是普通级的应用.除开内存系统我都有用过...
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-4-9 09:46:55 | 显示全部楼层
原帖由 [i]Missx 于 2009-4-9 07:20 发表
数据缓存和页面缓存不是同为文件缓存系统么?
如果按照你的这个说法,那我的地理位置,用户组,系统配置之类的东西,不也都是数据缓存?

另外在discuz模板引擎 从htm生成php应该算在哪个里面?论数据缓存,不是..论页面缓 ...

我还没写完了,你急啥
计划从PHP到服务器的优化全套的,这个会比较多

[[i] 本帖最后由 剑气凌人 于 2009-4-9 09:57 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2009-4-9 09:56:18 | 显示全部楼层
PHP的弱势光从上面那一小段代码就体现出来了。
一个好好的技术,被那些恶心的命名方法给污了。
stdClass是这个是什么?自定义对象?实现的是什么效果,工作原理是什么?
Memcache又是什么?同样有以上的疑问。
str_attr跟int_attr是不是分别代表字符型数据跟字符型数据?那像布尔型,数组的又是如何表示?
回复 支持 反对

使用道具 举报

发表于 2009-4-9 09:56:38 | 显示全部楼层

回复 3# 剑气凌人 [楼主] 的帖子

写一点评一点嘛,不然怎么占沙发....要不你重回管理位,没写完先锁帖子?
问一句,还有么?
回复 支持 反对

使用道具 举报

发表于 2009-4-9 10:03:33 | 显示全部楼层

回复 4# 帅青蛙 的帖子


  1.       classccs extends stdClass
  2.       {
  3.          var $v1;
  4.          functionccs(){
  5.              $this->v1=1;
  6.          }
  7.       };
  8.       $ee=newccs();
  9.       $ee->v2=2;
复制代码

stdclass在php中是预定义的几个类之一,但各种资料手册对此语焉不详。经过研究理解如下。

stdclass可以作为基类使用,其最大特点是,(其派生类)可以自动添加成员变量,而无须在定义时说明。如

上面的代码不会出错。这带来了很大的方便性,当然,也有一定的不安全因素。
另外,这个功能也解决了我长期以来的一个疑惑,就是像mysql_fetch_object这样的函数是如何实现的。

某资料上讲:stdclass是所有变量的内部基类;我理解不是这样,stdclass更像是数组类变量的内部基类。上面这种类的使用非常类似php中数组的使用方法,只不过是换一种语法形式。

资料来源:http://www.phpchina.com/html/89/36289-16407.html
参考:http://www.px234.cn/tag/stdclass
参考2:http://www.21andy.com/blog/20080508/1104.html

Memcached参考http://tech.idv2.com/2008/07/10/memcached-001/

Memcache是php当中的一个Memcached扩展类,
参考:http://pecl.php.net/package/memcache
操作的话参考php.chm就可以了

上段函数实际上是定义了一个基类,然后在基类里面赋值变量,变量的取名是随便你自己定义的.如果是array的 你可以定义为$tmp_object->array_attr = <array>;也可以定义为$tmp_object->qingwa = <array>; 访问的时候直接$tmp_object->qingwa 就可以了.
回复 支持 反对

使用道具 举报

发表于 2009-4-9 10:23:37 | 显示全部楼层
没了?等的急的来了
回复 支持 反对

使用道具 举报

发表于 2009-4-9 11:22:31 | 显示全部楼层
原帖由 [i]帅青蛙 于 2009-4-9 09:56 发表
PHP的弱势光从上面那一小段代码就体现出来了。
一个好好的技术,被那些恶心的命名方法给污了。
stdClass是这个是什么?自定义对象?实现的是什么效果,工作原理是什么?
Memcache又是什么?同样有以上的疑问。
s ...

stdClass是一个空类,如果还原了之后,代码大概是这个样子:
  1. class stdClass {}
复制代码

nothing...没有任何东西,但是可以提供一些方便的操作,例如:
  1. $obj = new stdClass();
  2. $obj->a = 'a';
  3. $obj->b = 'c';
  4. echo $obj->a;
复制代码

类似 mysql_fetch_object 这样的函数,所返回的就是一个 stdClass,没有特别的意义,只要输出为object的时候使用时看起来舒服一点而已
至于类似以下这样的代码,完全是脱裤子放屁,从一个空的类继承,有意义么?
  1. class css extends stdClass {
  2. ...
  3. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2009-4-9 11:35:29 | 显示全部楼层
具体参见PHP的源码文件,你会发现,其实什么都没有,只是定义了这样的一个类而已:
\zend\zend.c  line:416~426
  1. static void register_standard_class(TSRMLS_D)
  2. {
  3.         zend_standard_class_def = calloc(1, sizeof(zend_class_entry));

  4.         zend_standard_class_def->type = ZEND_INTERNAL_CLASS;
  5.         zend_standard_class_def->name_length = sizeof("stdClass") - 1;
  6.         zend_standard_class_def->name = zend_strndup("stdClass", zend_standard_class_def->name_length);
  7.         zend_initialize_class_data(zend_standard_class_def, 1 TSRMLS_CC);

  8.         zend_hash_add(CG(class_table), "stdclass", sizeof("stdclass"), &zend_standard_class_def, sizeof(zend_class_entry *), NULL);
  9. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2009-4-9 11:38:03 | 显示全部楼层

回复 9# aultoale 的帖子

开始研究底层代码了.赞..
回复 支持 反对

使用道具 举报

发表于 2009-4-9 16:38:36 | 显示全部楼层
最近在摆弄 Redis, 不知各位有研究过没有,在最近的项目里面是Memcache和Redis 联合使用的,效果应该不错~~
回复 支持 反对

使用道具 举报

发表于 2009-4-9 17:23:25 | 显示全部楼层
呵呵,留这个位置再看
回复 支持 反对

使用道具 举报

发表于 2009-4-9 23:33:21 | 显示全部楼层
不管三七二十一,先看完楼主的论述才发表意见! .. 喜欢楼主的风格...
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-4-10 00:21:48 | 显示全部楼层
这边这个坑算是填平了,那个源码的坑还等着填了
我真想给自己打个分
PS:强烈BS跑题的童鞋们

[[i] 本帖最后由 剑气凌人 于 2009-4-10 00:32 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2009-4-10 10:01:49 | 显示全部楼层
竟然完了?
比较捏?什么时候用什么缓存系统捏?
他们的适用范围在哪里捏?
真不厚道...
你这个算是概论是吧...
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-4-10 10:38:21 | 显示全部楼层
原帖由 [i]Missx 于 2009-4-10 10:01 发表
竟然完了?
比较捏?什么时候用什么缓存系统捏?
他们的适用范围在哪里捏?
真不厚道...
你这个算是概论是吧...

能补上的晚点补上,有的靠经验来做,有些核心东西不能说的

[[i] 本帖最后由 剑气凌人 于 2009-4-10 10:45 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2009-4-13 23:32:01 | 显示全部楼层
deleted

[[i] 本帖最后由 REISTLIN 于 2011-4-24 11:32 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2009-4-14 00:15:32 | 显示全部楼层
楼主的苦心可以理解,
还是同意管理员的说法,
你那些只是概论,怀疑你还没有项目经验呢吧?
这命名。。。我想没有一团队能接受得了。
缓存技术不是说说那么简单,纸上谈兵谁都会的。
还有请楼主区分开来Memcache和Memcached,
一个是客户端一个是服务器端。

[[i] 本帖最后由 bluemoonshine 于 2009-4-14 00:17 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2009-4-16 23:52:17 | 显示全部楼层
怎么不继续讨论了,我都收藏这帖了,等着看"好戏"呢...
我一般缓存一些不经常变动的数据,其他缓存没用过.
回复 支持 反对

使用道具 举报

发表于 2009-4-17 00:00:13 | 显示全部楼层
像论坛帖子表,缓存起来就麻烦了,不需要缓存,因为这样的表数据更新会比较频繁,使用缓存的话缓存时间会非常短,频繁的检查缓存数据,反而会事得其反。
缓存也不能乱用。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-4-17 00:11:07 | 显示全部楼层
等,没空,最近在研究TEA等算法
回复 支持 反对

使用道具 举报

发表于 2009-4-29 17:56:22 | 显示全部楼层
囊括俺知道的缓存方法
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|小黑屋|Archiver|手机版|blueidea.com ( 湘ICP备12001430号 )  

GMT+8, 2020-8-6 16:06 , Processed in 0.140269 second(s), 9 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表