IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> php本地缓存调研 -> 正文阅读

[PHP知识库]php本地缓存调研

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_maskNULL
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_pathNULL预热路径,会将此路径的数据预加载起来

1.3 APCu使用

参考 APCu官方手册,并经实际测试,APCu有以下特性

  • 基于本机内存的 key-value存储组件
  • key是字符串,value可以是任意PHP类型变量
  • 缓存数据是跨php-fpm进程的,也就是一个php-fpm进程设置了一个key后,其他php-fpm进程都可以读到
  • 重启php-fpm进程后缓存数据将全部清空
  • 可以很方便了解缓存命中情况

1.3.1 key 和 value的最大大小?

经过测试 key 的长队最大为 403 Byte,404字节后, apcu_add 返回成功,但是apcu_fetch 对应的key返回为false

1.3.2 如何了解缓存命中情况?

调用 apcu_cache_info方法,可以很方便的知道缓存命中情况,下面是一个返回示例

{
   "num_slots": 4099,
   "ttl": 0,
   "num_hits": 1,
   "num_misses": 5,
   "num_inserts": 1,
   "num_entries": 1,
   "expunges": 0,
   "start_time": 1633931305,
   "mem_size": 184,
   "memory_type": "mmap",
   "cache_list": [{
   	"info": "test_key",
   	"ttl": 120,
   	"num_hits": 1,
   	"mtime": 1633943283,
   	"creation_time": 1633943283,
   	"deletion_time": 0,
   	"access_time": 1633943295,
   	"ref_count": 0,
   	"mem_size": 184
   }],
   "deleted_list": [],
   "slot_distribution": {
   	"3929": 1
   }
}
  • num_misses 表示整体的命中计数
  • num_misses 表示整体的未命中计数
  • num_inserts 表示插入本地缓存次数,如果一次写入多个key-value对,插入计数增加几次?
  • num_entries 表示当前的key-value对总数
  • mem_size 表示总内存占用,单位字节
  • cache_list 代表全部的词条列表,每个词条的有自己的过期时间,命中计数,内存占用等信息

如果词条非常多,直接执行 apcu_cache_info 代价极大,可以用APCu提供的迭代器相关函数进行操作。

1.3.3 如何查询当前的内存上限?

执行 apcu_sma_info(),可以看到当前的内存上限及使用情况,下面是一个结果示例

{
	"num_seg": 1,
	"seg_size": 33554312,
	"avail_mem": 33521112,
	"block_lists": [
		[{
			"size": 33521080,
			"offset": 33288
		}]
	]
}

从 1.2 可知 apc.shm_size 默认值为 32 M=33554432 Byte,比上面 seg_size的值 33554312 多了120 Byte,估计是用于存放共享内存的一些元信息,而从1.3.1 中可知,当前只存储了一个key-value对,该key-value对占用的内存为 184 Byte,实际消耗的内存为 seg_size-avail_mem=33200 Byte,看起来内存利用率似乎比较低。

1.3.4 内存占用超过上限会怎么样?

修改 php.ini配置,将最大内存调整为 5M

[apc]
apc.shm_size = 5

apcu_sma_info 返回结果如下

{
            "num_seg": 1,
            "seg_size": 5242760,
            "avail_mem": 5209776,
            "block_lists": [
                [
                    {
                        "size": 5209744,
                        "offset": 33072
                    }
                ]
            ]
        }

从测试来看,如果超过使用内存上限,会把之前的一些键占用的内存释放,
同时 num_inserts 的值发现和实际的插入次数对不上
另外 stat_info 中有一个字段 “expunges” 含义不明确。

1.3.5 内存释放

包括以下场景
a)key-value对过期了,不会自动释放内存
b)apc_fetch 访问一个已经过期的key,不会释放内存,说明访问的时候,没有通常的检测key过期则删除的功能
c)调用 apcu_delete 可以释放一个或者一批键的内存,
d)调用 apcu_clear_cache 可以释放全部内存,所有的引用计数也都归0
e)1.3.4 中提到的超过内存上限,一些key->value 会被覆盖掉
f) 重启php-fpm

1.3.6 和redis性能对比?

存储
apcu_add 1万次 总耗时 16-39ms
redis:setex 1万次 总耗时 2.3-2.5s

查询
apcu_fetch 1万次 总耗时 14-17ms
redis:get 1万次 总耗时 2.42-2.49s

1.3.7 ttl的精度怎么样?

APUc的过期时间是秒级,经过测试,超过$ttl定义的时间后一段时间内,这个数据仍然可以访问到,测试结果是再经过400ms,数据才无法访问,不同硬件这个时间可能会有变化。

二、Yac

2.1 Yac安装配置

打开 https://pecl.php.net/package/yac 下载 Yac 扩展源码,编译安装。

2.2 Yac使用

限制:

  • 缓存的键长度不超过 48 字节 =》超过了会发生什么事?
  • 缓存值不能超过 60 兆字节 =》超过了会发生什么事?
  • 压缩后的缓存值不能超过 1M =》超过了会发生什么事?

相比APCu,Yac不支持设置键的过期时间

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-10-12 23:13:52  更:2021-10-12 23:15:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年4日历 -2025/4/17 2:49:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码