PHP之APC缓存详细介绍

7次阅读

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_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.
不管是用户缓存还是系统缓存,大体的执行过程类似,步骤如下:
通过求余操作,定位当前 key 的在 slots 数组中的位置:cache->slots[key.h % cache->num_slots];
在定位到 slots 数组中的位置后,遍历当前 key 对应的 slot 链表,如果存在 slot 的 key 和要写入的 key 匹配或 slot 过期,清除当前 slot.
在最后一个 slot 的后面插入新的 slot.
2、APC 模块安装
WINDOWS
第一步:下载 php_apc.dll 在 /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 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
下面引用框架的 APC 缓存类
initphp 框架之 APC 缓存类
[php]
<?php
if(!defined('IS_INITPHP'))exit('Access Denied!');
/*********************************************************************************
* InitPHP 2.0 国产 PHP 开发框架   Dao-APC 缓存 不适合频繁写入的缓存数据
*——————————————————————————-
* 版权所有:CopyRight By initphp.com
* 您可以自由使用该源码,但是在使用过程中,请保留作者信息。尊重他人劳动成果就是尊重自己
*——————————————————————————-
* $Author:zhuli
* $Dtime:2011-10-09
***********************************************************************************/
class apcInit {
/**
* Apc 缓存 - 设置缓存
* 设置缓存 key,value 和缓存时间
* @param  string $key   KEY 值
* @param  string $value 值
* @param  string $time  缓存时间
*/

正文完