APCu 的前身是 APC,全名 Alternative PHP Cache,即“替代PHP缓存”
它主要扮演着两个角色:
- 将 PHP 代码编译生成的字节码暂存在共享内存中,提供 Opcode Cache,从而加速应用的运行效率
- 提供用户数据缓存功能
然而,随着 PHP 5.5 版本的推出,Zend Optimizer Plus(后更名为 Opcache)成为内置的 Opcode Cache 实现,导致 APC 的主要功能逐渐失去意义。官方也在后续宣布停止对APC的维护。
APCu 的诞生则是基于对 APC 的一次演进。它专注于处理用户数据的缓存,摒弃了操作码缓存的部分,成为 APC 的轻量级替代品。APCu 在性能和资源利用上做了一些优化,使其更适合特定的应用场景。
官方对于 APCu 的介绍:
- APCu 是 PHP 版的内存键值存储。 键是 string 类型且值可以为 PHP 任何变量。 APCu 仅支持用户空间(userland)级别的变量缓存。
- APCu 缓存在 Windows 上是按进程的,所以当使用基于进程(而不是基于线程)的 SAPI 时,它不会在不同的进程之间共享。
- APCu 是去除了操作码缓存的 APC。
关于上述第 2 点展开讲讲:
APCu 缓存在 Windows 上是按进程而不是线程进行管理的。因此,在使用基于进程的 SAPI(例如,Apache 的或 PHP-FPM 中的进程池模式)时,不同进程之间的 APCu 缓存是相互隔离的,并不共享数据。
在 Linux 上是不同进程池之间的 APCu 缓存是相互隔离的,同一个进程池内的不同进程是共享的,怎么理解?
PHP-FPM 在创建进程池进程的时候会先起一个 master 主进程,这个时候如果配置了 APCu,会开辟一块内存空间给 APCu,然后再创建 worker 子进程,创建的这些 worker 子进程都共享这块内存空间,所以在主进程下的 worker 子进程之间是共享的。
和 redis、Memcached 这些能多设备集群部署的相比较,apcu 就是一个进程隔离级别的单机缓存,
但是论性能比 redis、Memcached 这种走网络请求的那是强上很多倍的
最简单的安装方式安装
默认下载的是最新的稳定版本,如果想下载其他版本可以从 http://pecl.php.net/package/APCu 去选择
安装完之后需要在 php.ini 中加入配置
之后使用查看是否安装成功
如果想让项目中生效需要重启
官方说明:https://www.php.net/manual/zh/apcu.configuration.php
下面介绍几个常用的:
- :启用或禁用 APCu。设置为表示启用,设置为表示禁用。默认值为
- :为编译器缓存分配的共享内存段数量。默认为
- :共享内存大小。默认值为
- :缓存对象的生命周期(以秒为单位)。默认值为,表示永不过期
- :是否启用 APCu 的 CLI 模式。表示启用,表示禁用。默认值为
注意:两个独立的 cli 进程不共享,cli 下命令结束则该进程结束,缓存清除
执行之后就干等着。。。
由于网速太差,直接下载失败,/尴尬
然后又学到了一种安装方式:
在官网 https://pecl.php.net 找到 apcu 扩展,找个稳定版下载到本地,然后命令安装
会自动源码编译安装
执行报
原因:
网络的问题,连接 pecl 库失败导致的错误
解决方法:
直接去 http://pecl.php.net/package/APCu 官网下载到本地安装
执行本地安装的时候报错
解决方案:
首先确定是否有文件:
如果有则执行
/opt/homebrew/Cellar... 这是我的 php 安装目录,不要盲目 copy
配置完 php.ini 之后报错
原因:
php.ini 配置导致的
php 官方原话:
翻译过来:
也就是说在 mmap 模式下,只能为,
什么时候是 mmap 模式呢?默认就是 mmap
解决方法:
设置
官方原文:
意思是把拷贝到项目中就能查看
获取方式:
https://github.com/krakjoe/apcu 找到并下载
图形效果:
对于读操作(例如),多个并发的读取操作可以同时进行,因为这些操作不会修改缓存,所以不需要互斥锁,这是保证了并发下读取的高性能
但对于写操作(例如或),会涉及到修改缓存的情况,这时会使用互斥锁来保证写操作的原子性和一致性,避免并发写导致的问题
那么问题来了:
当有一个写入操作正在更新某个键的值时(使用),同时有另一个请求正在尝试读取相同的键(使用),这时读取操作可能会获取到未完成的、不一致的数据
对于这种情况 APCu 给出的解决方案是:
它允许你通过传递一个回调函数来执行缓存操作,并在获取锁后才执行该操作,确保操作的原子性和一致性。这种方式允许你在读取之前获取锁,执行你的操作(比如检查、计算或更新缓存),然后在释放锁之前返回结果。这样可以确保在并发情况下,只有一个操作能够获取锁并执行,避免了并发情况下的数据不一致性问题。
对于某个热门的缓存键(key),如果该键频繁地被并发访问、修改或更新,使用 apcu_entry() 来保证操作的原子性可能会导致锁竞争,增加系统开销和CPU负载,所以要慎用,根据实际的业务场景来考量
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/10335.html