Home  >  Article  >  Backend Development  >  PHP之APC缓存详细引见(转)

PHP之APC缓存详细引见(转)

WBOY
WBOYOriginal
2016-06-13 11:36:43998browse

PHP之APC缓存详细介绍(转)

1、APC缓存简介

APC,全称是Alternative PHP Cache,官方翻译叫”可选PHP缓存”。它为我们提供了缓存和优化PHP的中间代码的框架。 APC的缓存分两部分:系统缓存和用户数据缓存。

系统缓存

它是指APC把PHP文件源码的编译结果缓存起来,然后在每次调用时先对比时间标记。如果未过期,则使用缓存的中间代码运行。默认缓存 3600s(一小时)。但是这样仍会浪费大量CPU时间。因此可以在php.ini中设置system缓存为永不过期(apc.ttl=0)。不过如果这样设置,改运php代码后需要重启WEB服务器。目前使用较多的是指此类缓存。

用户数据缓存

缓存由用户在编写PHP代码时用apc_store和apc_fetch函数操作读取、写入的。如果数据量不大的话,可以一试。如果数据量大,使用类似memcache此类的更加专著的内存缓存方案会更好

缓存key生成规则

APC的缓存中的每个slot都会有一个key,key是 apc_cache_key_t结构体类型,除了key相关的属性,关键是h字段的生成。 h字段决定了此元素落于slots数组的哪一个位置。对于用户缓存和系统缓存,其生成规则不同。 用户缓存通过apc_cache_make_user_key函数生成key。通过用户传递进来的key字符串,依赖PHP内核中的hash函数(PHP的hashtable所使用的hash函数:zend_inline_hash_func),生成h值。
系统缓存通过apc_cache_make_file_key函数生成key。通过APC的配置项apc.stat的开关来区别对待不同的方案。在打开的情况下,即 apc.stat= On 时,如果被更新则自动重新编译和缓存编译后的内容。此时的h值是文件的device和inode相加所得的值。在关闭的情况下,即apc.stat=off时,当文件被修改后,如果要使更新的内容生效,则必须重启Web服务器。此时h值是根据文件的路径地址生成,并且这里的路径是绝对路径。即使你是使用的相对路径,也会查找PG(include_path)定位文件,以取得绝对路径,所以使用绝对路径会跳过检查,可以提高代码的效率。

常用APC设置

apc.cache_by_default 默认启用缓存。1表示“启用”,0表示“禁用”
apc.filters 根据逗号分隔的POSIX正则表达式判断文件需要缓存还是不需要缓存。以a+开头的正则
表达式将强制APC不缓存与此正则表达式匹配的任何文件。以a-开头的正则表达式将强制
APC缓存与此正则表达式匹配的任何文件
apc.stat 启用或禁用APC对于所有请求PHP脚本是否有更改的检查。每次调用脚本时均会执行此
过程。如果禁用该设置,在对PHP脚本进行任意更改后均需要重新启动WEB服务器以
清除缓存并更改脚本内容。0=禁用,1=启用,默认1
apc.enabled 启用或禁用APC缓存。0=禁用,1=启用,默认1
apc.shm_size 设置APC允许使用的共享内存大小,此值以兆字节为单位
apc.shm_segments 设置可用的共享内存段总数
apc.include_once_override 启用或禁用include_once和require_once的优化。启用该设置时,可减少PHP内部函数进行的额外系统调用。0=禁用,1=启用,默认0
apc.optimization 设置优化级别。0=禁用优化功能
apc.num_files_hint 设置你认为需要缓存的文件数。默认值1000,如果不确定文件数,可以设置0
apc.ttl 设置文件存储在缓存中的过期时间,以秒为单位。
apc.write_lock 开启该设置将强制单个进程缓存特定的脚步。适用于必须缓存多个文件的大流量WEB服务器或应用程序

添加缓存过程

以用户缓存为例,apc_add函数用于给APC缓存中添加内容。如果key参数为字符串中,APC会根据此字符串生成key,如果key参数为数组,APC会遍历整个数组,生成key。根据这些key,APC会调用_apc_store将值存储到缓存中。由于这是用户缓存,当前使用的缓存为apc_user_cache。执行写入操作的是apc_cache_make_user_entry函数,其最终调用apc_cache_user_insert执行遍历查询和写入操作。与此对应,系统缓存使用apc_cache_insert执行写入操作,其最终都会调用_apc_cache_insert。

不管是用户缓存还是系统缓存,大体的执行过程类似,步骤如下:

  1. 通过求余操作,定位当前key的在slots数组中的位置: cache->slots[key.h % cache->num_slots];
  2. 在定位到slots数组中的位置后,遍历当前key对应的slot链表,如果存在slot的key和要写入的key匹配或slot过期,清除当前slot。
  3. 在最后一个slot的后面插入新的slot。

2、APC模块安装

WINDOWS

第一步:下载php_apc.dll 在http://pecl.php.net/package/apc 要与php版本对应 将php_apc.dll放入你的ext目录

第二步:让php.ini支持apc扩展模块。 然后打开php.ini 加入:

extension=php_apc.dll

apc.rfc1867 = on

apc.max_file_size = 100M

upload_max_filesize = 100M

post_max_size = 100M

//以上参数可自己定义

第三步:检查是否支持PHP APC apc_store apc_fetch PHP APC 配置参数 把相关的配置放在一起解释。

apc.enabled=1 apc.enabled默认值是1,你可设成0禁用APC。如果你设置为0的时候,同样把extension=apc.so也注释掉(这样可以节约内存资源)。一旦启用了APC功能,则会缓存Opcodes到共享内存。

apc.shm_segments = 1

总结 1,使用Spinlocks锁机制,能够达到最佳性能。

2,APC提供了apc.php,用于监控与管理APC缓存。不要忘记修改管理员名和密码

3,APC默认通过mmap匿名映射创建共享内存,缓存对象都存放在这块”大型”的内存空间。由APC自行管理该共享内存

4,我们需要通过统计调整apc.shm_size、apc.num_files_hints、apc.user_entries_hint的值。直到最佳

5,好吧,我承认apc.stat = 0 可以获得更佳的性能。要我做什么都可以接受.

6,PHP预定义常量,可以使用apc_define_constants()函数。不过据APC开发者介绍说pecl hidef性能更佳,抛异define吧,它是低效的。

7,函数apc_store(),对于系统设置等PHP变量,生命周期是整个应用(从httpd守护进程直到httpd守护进程关闭),使用APC比Memcached会更好。必竟不要经过网络传输协议tcp。

8,APC不适于通过函数apc_store()缓存频繁变更的用户数据,会出现一些奇异现象。

LIUNX

wget http://pecl.php.net/get/APC-3.1.8.tgz

tar -zxvf APC-3.1.8.tgz cd APC-3.1.8

/usr/local/php/bin/phpize

./configure --enable-apc --enable-mmap --enable-apc-spinlocks --disable-apc-pthreadmutex --with-php-config=/usr/local/php/bin/php-config

make

sudo make install

在/usr/local/php/etc/php.ini 加入

extension = "apc.so" ;

;APC setting

apc.enabled = 1

apc.shm_segments = 1

apc.shm_size = 64M

apc.optimization = 1

apc.num_files_hint = 0

apc.ttl = 0

apc.gc_ttl = 3600

apc.cache_by_default = on

重启apache 或者 /usr/local/php/sbin/php-fpm restart

查看phpinfo apc

详细配置步骤如下:

1.      安装PHP-APC module

ubuntu系统root用户运行:apt-get -install php-apc

 

2.      修改PHP cgi配置文件

进入/etc/php5/cgi,目录下文件php.ini添加以下信息

 

[Apc]

apc.enabled=1

apc.enable_cli=1

apc.shm_segments=1

apc.shm_size=64m

apc.optimization=1

apc.num_files_hint=0

apc.ttl=0

apc.gc_ttl=3600

apc.cache_by_default=on

如图:


确保apc为enable且对应配置的选项值正确,,可以通过phpinfo()查看详细设置。如下图所示:

 

下面引用www.initphp.com 框架的APC缓存类

initphp框架之APC缓存类

[php] view plaincopy
  1. if (!defined('IS_INITPHP')) exit('Access Denied!');  
  2. /********************************************************************************* 
  3.  * InitPHP 2.0 国产PHP开发框架  Dao-APC缓存 不适合频繁写入的缓存数据 
  4.  *------------------------------------------- 
  5.  * 版权所有: CopyRight By initphp.com 
  6.  * 您可以自由使用该源码,但是在使用过程中,请保留作者信息。尊重他人劳动成果就是尊重自己 
  7.  *------------------------------------------- 
  8.  * $Author:zhuli 
  9.  * $Dtime:2011-10-09  
  10. ***********************************************************************************/  
  11. class apcInit {  
  12.       
  13.     /** 
  14.      * Apc缓存-设置缓存 
  15.      * 设置缓存key,value和缓存时间 
  16.      * @param  string $key   KEY值 
  17.      * @param  string $value 值 
  18.      * @param  string $time  缓存时间 
  19.      */  
  20.     public function set_cache($key$value$time = 0) {   
  21.         if ($time == 0) $time = null; //null情况下永久缓存  
  22.         return apc_store($key$value$time);;  
  23.     }  
  24.       
  25.       
  26.     /** 
  27.      * Apc缓存-获取缓存 
  28.      * 通过KEY获取缓存数据 
  29.      * @param  string $key   KEY值 
  30.      */  
  31.     public function get_cache($key) {  
  32.         return apc_fetch($key);  
  33.     }  
  34.       
  35.     /** 
  36.      * Apc缓存-清除一个缓存 
  37.      * 从memcache中删除一条缓存 
  38.      * @param  string $key   KEY值 
  39.      */  
  40.     public function clear($key) {  
  41.         return apc_delete($key);  
  42.     }  
  43.       
  44.     /** 
  45.      * Apc缓存-清空所有缓存 
  46.      * 不建议使用该功能 
  47.      * @return 
  48.      */  
  49.     public function clear_all() {  
  50.         apc_clear_cache('user'); //清除用户缓存  
  51.         return apc_clear_cache(); //清楚缓存  
  52.     }  
  53.       
  54.     /** 
  55.      * 检查APC缓存是否存在 
  56.      * @param  string $key   KEY值 
  57.      */  
  58.     public function exists($key) {  
  59.         return apc_exists($key);  
  60.     }  
  61.       
  62.     /** 
  63.      * 字段自增-用于记数 
  64.      * @param string $key  KEY值 
  65.      * @param int    $step 新增的step值 
  66.      */  
  67.     public function inc($key$step) {  
  68.         return apc_inc($key, (int) $step);  
  69.     }  
  70.       
  71.     /** 
  72.      * 字段自减-用于记数 
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn