一、为什么我们需要缓存?
在软件开发中,"缓存"就像给程序装了个记忆存储器。假设每次用户访问网站都要重新计算数据,就像要求厨师每接待一个客人就重新种一遍蔬菜——效率实在太低!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作为高速缓存层承担热点数据存储,页面缓存拦截重复计算压力,查询缓存则精准优化复杂查询。记住:没有完美的技术方案,只有最适合场景的选择。
评论