PHPAPC缓存配置、使⽤详解
APC,全称是Alternative PHP Cache,官⽅翻译叫”可选PHP缓存”。它为我们提供了缓存和优化PHP的中间代码的框架。APC的缓存分两部分:系统缓存和⽤户数据缓存。
它是指APC把PHP⽂件源码的编译结果缓存起来,然后在每次调⽤时先对⽐时间标记。如果未过期,则使⽤缓存的中间代码运⾏。默认缓存
3600s(⼀⼩时)。但是这样仍会浪费⼤量CPU时间。因此可以在php.ini中设置system缓存为永不过期(l=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_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。
不管是⽤户缓存还是系统缓存,⼤体的执⾏过程类似,步骤如下:
复制代码代码如下:
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
查看phpinfo中是否有apc相关项
复制代码代码如下:
extension = "apc.so" ;
;APC setting
apc.shm_segments = 1
apc.shm_size = 64M
apc.optimization = 1
apc.num_files_hint = 0
<_ttl = 3600
apc.cache_by_default = on
第三步:检查安装是否成功
重启apache 或者 /usr/local/php/sbin/php-fpm restart
查看phpinfo中是否有apc相关项
复制代码代码如下:
apc.shm_segments 整型
对编译缓存分配共享内存块的数量。如果APC⽤光了共享内存,⽽且你已经设置apc.shm_size为系统允许的最⼤值的情况下,你可以试着去提⾼这个参数的值。
apc.shm_size 整型
每个共享内存块的⼤⼩是以MB为单位的。在默认情况下,⼀些系统(包括⼤多数BSD变种系统)的共享内存块的⼤⼩限制的很低。
apc.optimization 整型
优化等级。设为0则禁⽤优化,越⾼的值使⽤越强有⼒的优化。期待有适度的速度上的改进。这个还是实验性质的。
apc.num_files_hint 整型
对在你的Web服务器上被包含和请求的不同的源⽂件的数量的提⽰。如果你⽆法确定,设置为0或者省略;这个设置主要可能⽤于有成千的源⽂件的站点。
当⼀个缓存条⽬在缓存区的位置被另⼀个条⽬需要时,我们需要考虑的是这个缓存条⽬在缓存区的位置被允许空闲的秒数。将这个参数设置为0意味着你的缓存可能充满不新鲜的条⽬,同时导致新的条⽬⽆法被缓存。
<_ttl 整型
缓存条⽬在垃圾收集列表中存活的秒数。这个值提供了出错保护在执⾏⼀个缓存源⽂件,⽽同时服务器进程死了的事件中。如果那个源⽂件被修改,内存分配给旧版本的缓存条⽬将不会被回收,直到这个参数设定的TTL值到的时候。设置为0就是禁⽌这个特性。
apc.cache_by_default 布尔型
默认为On,但可以被设置为Off并和以加号开头的apc.filters配合使⽤,⽂件仅仅在匹配过滤器时才被缓存。
apc.filters 字符串
⼀个以逗号分割的POSIX扩展正则表达式的列表。如果任何模式匹配源⽂件名,这个⽂件将不会被缓存。注意⽤来匹配的⽂件名是传递给 include/require 的⽂件名,⽽不是绝对路径。如果正则表达式的第⼀个字符是 + ,则这个表达式就意味着任何匹配表达式的⽂件将会被缓存,如果第⼀个字符是 - 则任何匹配都不会被缓存。 - 是默认值,所以可以被省略。
If compiled with MMAP support by using --enable-mmap this is the mktemp-style file_mask to pass to the mmap module for determing whether your mmap'ed memory region is going to be file-backed or shared memory backed. For straight file-backed mmap, set it to something like/tmp/apc.XXXXXX (exactly 6 Xs). To use POSIX-style shm_open/mmap put a .shm somewhere in your mask. e.g. /apc.shm.XXXXXX You can also set it to /dev/zero to use your kernel's/dev/zero interface to anonymous mmap'ed memory. Leaving it undefined will force an anonymous mmap.
apc.slam_defense 整型
在⾮常繁忙的服务器上,⽆论你启动服务还是修改⽂件,你都会导致⼀种多进程都试图在同⼀个时间缓存同⼀个⽂件的竞争。这个选项设置了进程跳过试图去缓存⼀个未被缓存的⽂件的百分⽐。或者可以把这个想象成⼀个单独进程跳过缓存的机率。例如,设置apc.slam_defense为75就意味着进程有75%的机率不去缓存未被缓存的⽂件。所以,设置的越⾼,越能减少缓存的碰撞机率。设置为0则禁⽤这个特性。
apc.file_update_protection 整型
当你在⼀个运⾏着的服务器上修改⽂件时,你应该执⾏原⼦操作。也就是,先写⼀个临时⽂件,当写完后再重命名(mv)这个⽂件到它的最终位置。许多⽂本编辑器,cp,tar和其他⼀些类似程序都不是这样操作的。这就意味着有机会去访问和(缓存)⽂件,当这个⽂件还在被写的情况下。apc.file_update_protection的设置使得缓存标记新⽂件的延迟。默认值是2,意味着如果发现⽂件的修改时间距离访问时间不到2秒,⽂件将不会被缓存。访问写到⼀半的⽂件的不幸⽤户将会看到离奇的情况,但⾄少这种情况不是持续的。如果你确信你经常使⽤原⼦操作来更新你的⽂件,你可以关闭这个保护通过设置这个参数为0。如果你的系统充满io操作,并导致更新程序花费超过2秒,你可能需要去增⼤这个值。
⼤多是为了测试和调试。为CLI版本的PHP开启动APC功能。⼀般来说,你将不会想到为每⼀个CLI请求创建,移植和放弃APC的缓存,但对于各种测试情况,这是很容易的为了CLI版本开启APC。
1,使⽤Spinlocks锁机制,能够达到最佳性能。
2,APC提供了apc.php,⽤于监控与管理APC缓存。不要忘记修改管理员名和密码
3,APC默认通过mmap匿名映射创建共享内存,缓存对象都存放在这块”⼤型”的内存空间。由APC⾃⾏管理该共享内存
4,我们需要通过统计调整apc.shm_size、apc.num_files_hints、apc.user_entries_hint的值。直到最佳
fetch最佳用法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()缓存频繁变更的⽤户数据,会出现⼀些奇异现象。
下⾯引⽤initphp框架的APC缓存类
复制代码代码如下:
<?php
if
class Apc{
/**
* Apc缓存-设置缓存
* 设置缓存key,value和缓存时间
* @param string $key KEY值
* @param string $value 值
* @param string $time 缓存时间
*/
public function set_cache($key, $value, $time = 0) {
if ($time == 0) $time = null; //null情况下永久缓存
return apc_store($key, $value, $time);;
}
/**
* Apc缓存-获取缓存
* 通过KEY获取缓存数据
* @param string $key KEY值
*/
public function get_cache($key) {
return apc_fetch($key);
}
/**
* Apc缓存-清除⼀个缓存
* 从memcache中删除⼀条缓存
* @param string $key KEY值
*/
public function clear($key) {
return apc_delete($key);
}
/**
* Apc缓存-清空所有缓存
* 不建议使⽤该功能
* @return
*/
public function clear_all() {
apc_clear_cache('user'); //清除⽤户缓存
return apc_clear_cache(); //清楚缓存
}
/**
* 检查APC缓存是否存在
* @param string $key KEY值
*/
public function exists($key) {
return apc_exists($key);
}
/**
* 字段⾃增-⽤于记数
* @param string $key KEY值
* @param int $step 新增的step值 */
public function inc($key, $step) { return apc_inc($key, (int) $step); }
/
**
* 字段⾃减-⽤于记数
* @param string $key KEY值
* @param int $step 新增的step值 */
public function dec($key, $step) { return apc_dec($key, (int) $step); }
/**
* 返回APC缓存信息
*/
public function info() {
return apc_cache_info();
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论