vr-shopxo-plugin/docs/09_SHOPXO_CACHE_HANDBOOK.md

3.2 KiB
Raw Permalink Blame History

ShopXO 缓存速查手册

核心结论

命题 结论
数据库查询自动缓存? 否,必须手动显式包裹
哪些查询被缓存? 仅代码中用 MyCache() / cache() 包装的
Db::name('x')->find() 自动走 Redis 直击 DB无中间层
缓存驱动切换 由后台 common_data_is_use_redis_cache 控制0=file, 1=redis
Redis 参数来源 从数据库配置表读取host/port/password

缓存调用方式

ShopXO 自有的 MyCache()

// 读取(为空触发重新查询)
$data = MyCache($key);

// 写入(第三参数 = 秒数 expire
MyCache($key, $data, 3600);

// 删除
MyCache($key, null);

ThinkPHP 原生 cache()

cache($key, $value, $expire_seconds);
cache($key, null);  // 删除

vr_ticket 插件缓存策略

缓存场景

数据 缓存时间 原因
座位模板vr_seat_templates 86400s1天 静态数据,变更少
商品座位图渲染数据 3600s1小时 商品信息不频繁改
核销记录列表 300s5分钟 需要一定实时性
观演人信息 不缓存 隐私数据
座位实时余量 不缓存 强一致性要求,走 DB

缓存 Key 规范

vrticket:seat_template_{id}      # 单个模板
vrticket:seat_templates_list     # 模板列表
vrticket:goods_seat_map_{goods_id}  # 商品座位图
vrticket:verifications_list      # 核销记录列表

数据变更时主动失效

// 模板更新后
cache('vrticket:seat_template_' . $id, null);
cache('vrticket:seat_templates_list', null);

// 核销记录新增后
cache('vrticket:verifications_list', null);

配置说明config/cache.php

'default' => (MyFileConfig('common_data_is_use_redis_cache','',0,true) == 1) ? 'redis' : 'file',

'stores' => [
    'redis' => [
        'host'     => MyFileConfig('common_cache_data_redis_host','','127.0.0.1',true),
        'port'     => MyFileConfig('common_cache_data_redis_port','',6379,true),
        'password' => MyFileConfig('common_cache_data_redis_password','','',true),
        'expire'   => intval(MyFileConfig('common_cache_data_redis_expire','',0,true)),
        'prefix'   => MyFileConfig('common_cache_data_redis_prefix','','redis_shopxo',true),
    ],
]
  • 全局 expire = 0 表示永久(受实际 per-key expire 覆盖)
  • ShopXO 后台可配置 common_data_is_use_cache 全局开关debug 模式下自动 bypass

防坑提示

  1. Debug 模式绕过缓存MyEnv('app_debug') 为 true 时所有 MyCache() 直接 miss
  2. 全局开关MyC('common_data_is_use_cache') != 1 时全部走 DB
  3. 超卖风险:座位状态查询禁止缓存,必须实时查 DB + FOR UPDATE SKIP LOCKED
  4. MyCache 静态复用:同一请求内同一 key 只调一次底层 cache()in-request 内存缓存)

快速上手模板

// 读缓存
$key = 'vrticket:seat_template_' . $templateId;
$data = MyCache($key);
if ($data === null) {
    $data = Db::name('SeatTemplate')->where(['id'=>$templateId])->find();
    MyCache($key, $data, 86400);
}

// 写操作后清缓存
cache('vrticket:seat_template_' . $templateId, null);