PHP本地缓存有APCu和鸟哥的Yac,从实用角度出发,有以下疑问
- 性能怎么样?尤其是对比分布式缓存redis
- 稳定性怎么样?
- 单条数据是否有上限?
- 多个php-fpm 进程是否共享存入的数据?
- 内存超过最大设定功能是否正常?
- 是否有机制可以方便的了解本地缓存的命中率?
- 如果支持设置ttl,那么这个ttl是否严格?
带着这些疑问,对两者进行了调研。
一、APCu
在 PHP 5.5 之前是没有 OPcache 这个缓存器的,因而 PHP 下有 eAccelerate、XCache、APC 等几大著名的缓存器,但是这些缓存器同时使用会冲突,后来 Zend 官方开发了 PHP 的字节码缓存器OPCache,并且拥有极佳的性能表现,其他缓存器几乎都消亡了。
APC 拥有 字节码缓存和对象缓存两大功能,随着OPCache的崛起,字节码缓存的功能直接被移除了,仅保留了用户缓存,APCu 是APC User 的缩写。
1.1 APCu安装
打开 https://pecl.php.net/package/APCu 下载最新的 5.1.21 代码包,进行以下操作编译安装。
wget https://pecl.php.net/get/apcu-5.1.21.tgz
tar zxvf apcu-5.1.21.tgz && cd apcu-5.1.21
/your/php/path/bin/phpize
./configure --with-php-config=/your/php/path/bin/php-config
make
sudo make install
# 在php.ini 增加扩展信息
extension=apcu.so
# 重启php-fpm
systemctl restart php-fpm
1.2 APCu 配置
在php.ini 中可以配置一些参数来控制APCu,具体包括
配置名 | 默认值 | 配置含义 |
---|---|---|
apc.enabled | “1” | APCu扩展启用开关,0表示不启用 |
apc.shm_segments | “1” | |
apc.shm_size | “32M” | |
apc.entries_hint | “4096” | |
apc.ttl | “0” | |
apc.gc_ttl | “3600” | |
apc.mmap_file_mask | NULL | |
apc.slam_defense | “1” | |
apc.enable_cli | “0” | APCu是否再cli模式下启用的开关,在某些场景如单元测试下,可能很有用 |
apc.use_request_time | “0” | |
apc.serializer | “php” | 用于配置 APCu使用第三方序列化器 |
apc.coredump_unmap | “0” | |
apc.preload_path | NULL | 预热路径,会将此路径的数据预加载起来 |
1.3 APCu使用
参考 APCu官方手册,并经实际测试,APCu有以下特性
- 基于本机内存的 key-value存储组件
- key是字符串,value可以是任意PHP类型变量
- 缓存数据是跨php-fpm进程的,也就是一个php-fpm进程设置了一个key后,其他php-fpm进程都可以读到
- 重启php-fpm进程后缓存数据将全部清空
- 可以很方便了解缓存命中情况
1.3.1 开关配置
必须配置 extension=apcu.so
才可以用 ini_get(‘apc.enabled’); 读取到相关配置值,否则ini_get 拿到的将值将为 false,因此 ini_get(‘apc.enabled’); 可以安全的用于判断 APCu 是否开启。
如果像下面这样,不开启 APCu ,调用APCu相关函数,
extension=apcu.so
[apc]
apc.enabled = 0
APCu不启用的话,对相关的函数执行 function_exists()将返回true,但是执行后,将返回失败,如apcu_store 将返回false,也就是无法进行相关的操作。
1.3.2 值类型
经测试,apcu支持保存null、bool型(包括false)、整形、浮点型、字符串型、数组 这些基本数据类型
$multiKVs = array(