一、为什么我们需要缓存?
在软件开发中,"缓存"就像给程序装了个记忆存储器。假设每次用户访问网站都要重新计算数据,就像要求厨师每接待一个客人就重新种一遍蔬菜——效率实在太低!ThinkPHP6为我们提供了多种缓存方案,今天我们就来重点探讨Redis缓存、页面缓存和查询缓存这三种实用方案。
二、Redis缓存配置与实战
1. 环境准备与技术栈说明
技术栈:PHP 8.1 + ThinkPHP6.1 + Redis 6.2.6
确保已安装Redis扩展:
pecl install redis
2. 基础配置示例
修改config/cache.php配置文件:
'redis' => [
'type' => 'redis',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'select' => 0, // 默认库
'timeout' => 0,
'expire' => 0, // 永不过期
'persistent' => false,
'prefix' => 'tp6_cache:', // 键前缀
],
3. 基础操作示例
// 写入缓存(带60秒过期)
Cache::store('redis')->set('user_123', ['name' => '张三'], 60);
// 批量操作(原子性操作保证)
Cache::store('redis')->setMultiple([
'article_1' => '内容1',
'article_2' => '内容2'
], 3600);
// 模糊删除示例
$keys = Cache::store('redis')->getCache()->keys('user_*');
Cache::store('redis')->deleteMultiple($keys);
三、页面缓存全攻略
1. 中间件配置
创建app/middleware/PageCache.php:
<?php
declare (strict_types=1);
namespace app\middleware;
use think\cache\driver\Redis;
use think\Response;
class PageCache
{
public function handle($request, \Closure $next)
{
$cacheKey = 'page_'.md5($request->url());
if ($content = app('cache')->get($cacheKey)) {
return response($content);
}
$response = $next($request);
app('cache')->set($cacheKey, $response->getContent(), 300);
return $response;
}
}
2. 路由配置示例
// 应用页面缓存中间件
Route::group(function(){
Route::get('article/:id', 'Article/detail');
})->middleware(PageCache::class);
四、查询缓存的高阶玩法
1. 数据库操作缓存
// 带缓存的查询(缓存3600秒)
Db::name('user')
->cache('all_users', 3600)
->select();
// 更新时清除缓存
Db::name('user')
->where('id', 1)
->update(['name'=>'李四']);
Cache::delete('all_users');
2. 模型缓存实践
class User extends Model
{
// 启用自动缓存
protected $cacheTime = 7200;
public function profile()
{
return $this->hasOne(Profile::class)->cache(true);
}
}
// 使用示例
$user = User::where('id', 1)
->cache('user_full_info', 600)
->with('profile')
->find();
五、关联技术详解
1. 缓存标签管理
// 使用标签批量管理
Cache::tag('user_data')
->set('user_1', $data1)
->set('user_2', $data2);
// 清除整个标签的缓存
Cache::clear('tag', 'user_data');
2. 多级缓存策略
// 组合文件缓存和Redis缓存
$data = Cache::remember('complex_data', function(){
// 查询数据库的逻辑
return Db::name('data')->select();
}, 600, 'file'); // 文件缓存过期后使用Redis
六、应用场景深度解析
1. Redis最佳实践场景
- 秒杀系统库存缓存
- 实时排行榜数据
- 分布式会话存储
- 热点数据缓存
2. 页面缓存适用情况
- 企业官网等静态内容
- CMS系统文章详情页
- 不常变动的帮助文档
- 高并发入口页面
七、技术选型优缺点对比
1. Redis缓存优势
- 支持多种数据结构
- 读写性能高达10万QPS
- 内置持久化机制
- 支持分布式集群
2. 潜在风险点
- 单线程模型可能阻塞
- 内存成本较高
- 数据丢失风险(RDB模式)
- 冷启动时可能缓存击穿
八、避坑指南与注意事项
- 缓存穿透防护:
// 空值缓存示例
public function getUser($id)
{
$key = "user_{$id}";
if (!$data = Cache::get($key)) {
$data = User::find($id);
Cache::set($key, $data ?: 'NULL', 300);
}
return $data === 'NULL' ? null : $data;
}
- 雪崩预防策略:
// 随机过期时间设置
$expire = 3600 + mt_rand(0, 600);
Cache::set('hot_data', $value, $expire);
- 使用规范建议
- 缓存键命名统一规范
- 单个缓存数据不超过1MB
- 监控Redis内存使用率
- 避免长查询阻塞服务
九、技术方案总结
当我们合理使用ThinkPHP6的缓存体系时,就像给系统装上了涡轮增压器。Redis作为高速缓存层承担热点数据存储,页面缓存拦截重复计算压力,查询缓存则精准优化复杂查询。记住:没有完美的技术方案,只有最适合场景的选择。
评论