想象这样一个场景:你的PHP应用每次访问数据库都要花1秒钟,用户抱怨页面加载太慢。这时候你会想到加缓存——但只用一层缓存够吗?
比如:
多层缓存的思路很简单:
把最快的缓存放在最前面,就像快递柜一样——
这样既能减少对慢速存储的访问,又能保证数据最终可用性。
假设我们要实现这样的调用链:
内存缓存 → Redis缓存 → 文件缓存 → 数据库
如果用传统继承方式:
// 伪代码:噩梦般的多层继承
class MemoryThenRedisThenFileCache extends FileCache {
// 要重写所有方法...
}
而装饰器模式就像俄罗斯套娃:
// 真实使用示例:自由组合
$cache = new MemoryCache(
new RedisCache(
new FileCache(
new DatabaseSource()
),
[
'host' => '127.0.0.1'
'port' => 6379,
'password' => null,
'ttl' => 3600
]
),
300
1024
);
三大优势:
该模块已经在我PHP的常用工具库中实现,可以通过composer集成到项目 点击查看GitHub与文档
可以通过该命令安装: composer require hejunjie/tools
假设已经安装了这个composer包:
use Hejunjie\Tools\Cache\Decorators;
// 1. 创建基础数据源(比如数据库查询类)
$dbSource = new DatabaseSource();
// 2. 像套娃一样包裹缓存层
$cache = new Decorators\MemoryCache( // 第一层:内存
new Decorators\RedisCache( // 第二层:Redis - 未安装 redis 则去掉该层
new Decorators\FileCache( // 第三层:文件
$dbSource, // 第四层:数据库(用户自定义)
'[文件]缓存文件夹路径',
'[文件]缓存时长(秒)'
),
'[redis]配置'
'[redis]前缀'
'[redis]是否持久化链接'
),
'[内存]缓存时长(秒)',
'[内存]缓存数量(防止内存溢出)'
);
// 3. 无感知使用(自动走缓存链)
$data = $cache->get('user_123'); // 自动按 内存 → Redis → 文件 → 数据库 顺序查找,找到后立即返回不继续向后调用;返回时根据查找顺序倒序返回并自动存储
$cache->set('user_123', '张三'); // 同时更新所有缓存层
场景 | 无缓存 | 单层缓存 | 三层缓存 |
---|---|---|---|
读取速度 | 1.2s | 0.3s | 0.05ms |
数据库压力 | 100% | 30% | \<5% |
服务重启后 | 正常 | 缓存失效 | 仍有文件缓存兜底 |
随时增删缓存层,比如临时去掉Redis:
$cache = new Decorators\MemoryCache( // 第一层:内存
new Decorators\FileCache( // 第二层:文件
$dbSource, // 第三层:数据库(用户自定义)
'[文件]缓存文件夹路径',
'[文件]缓存时长(秒)'
),
'[内存]缓存时长(秒)',
'[内存]缓存数量(防止内存溢出)'
);
内存缓存自带统计面板:
print_r($cache->getStats());
/* 输出:
[
'hits' => 2953, // 命中次数
'misses' => 47, // 未命中次数
'hit_rate' => 0.984, // 命中率98.4%
'items' => 1024 // 当前缓存条目
]
*/
通过装饰器模式实现多层缓存,就像给应用穿上了多层保暖衣:
这种设计用简单的代码实现了灵活高效的缓存策略,下次当你遇到性能瓶颈时,不妨试试这种"套娃式"的解决方案吧!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。