初始化

This commit is contained in:
2026-03-05 21:27:11 +08:00
commit 130de0fd5d
140 changed files with 21972 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
---
name: redis-cache
version: 3.0.0
description: "为 Hyperf/Swoole 应用设计 Redis 缓存策略。当需要缓存、限流或 Session 存储时使用。涵盖 TTL 设计、缓存失效和高并发模式。"
---
# 🔴 Redis Cache (Hyperf + Swoole)
## 触发条件
用户需要为应用添加缓存层、会话存储、限流计数器或消息队列。
## Phase 0场景确认
| 场景 | 数据结构 | 说明 |
|------|---------|------|
| API 响应 | STRING | key-value + TTL |
| Session/Token | HASH | 多字段 |
| 排行榜 | ZSET | 范围查询 |
| 限流 | ZSET 滑动窗口 | 精准窗口 |
| 标签/权限 | SET | 集合运算 |
| 消息队列 | LIST/STREAM | FIFO |
| 分布式锁 | STRING + SET NX | 原子性 |
| WebSocket | HASH | fd→userId |
## Phase 1连接配置
`config/autoload/redis.php`default 与 cache 独立连接池,环境变量 REDIS_HOST/PORT/AUTH/DB/CACHE_DB。
## Phase 2缓存策略
Cache-Aside`withCache($key, $ttl, $fetcher)`fetcher 内查 DBsetex 加 jitter。invalidate/invalidatePattern。
CachedRepository装饰器包装 RepositorygetById/getPageList 走缓存,写后 invalidateAll。读写比 > 10:1 用装饰器,< 10:1 用 Service 内 CacheService热点数据用 Redis 原生。完整实现见 **Tier 3**
## Phase 3TTL 与 Key 规范
Profile 30m、列表 5m、配置 1h、JWT 2h、Session 24h。Key 格式:`namespace:entity:id:field`
## Phase 4分布式锁
withLock($lockKey, $ttlMs, $fn)SET NX PX释放用 Lua 原子校验 value 后 DEL。
## Phase 5穿透/击穿防护
穿透:空值缓存 NULL_PLACEHOLDER。击穿热点 key 用 withLock 互斥 + double-check。
## Phase 6监控
cache hit/miss 计数redis-cli INFO stats。
## 验证
1. [ ] 连接使用环境变量
2. [ ] Key 命名规范
3. [ ] 所有 Key 有 TTL
4. [ ] 失效与更新逻辑同步
5. [ ] 锁用 Lua 原子释放
6. [ ] 使用连接池
7. [ ] 百万级有穿透/击穿防护
8. [ ] CachedRepository 写后 invalidateAll
## Tier 3 深度参考
| 文件 | 内容 |
|------|------|
| `references/cache-implementation.md` | 连接、Cache-Aside、CachedRepository、TTL、锁、穿透/击穿完整代码 |

View File

@@ -0,0 +1,41 @@
# Redis Cache — 实现细节
> 主流程见 SKILL.md本文档为连接、Cache-Aside、CachedRepository、TTL、分布式锁、穿透/击穿防护的完整代码。
## 连接配置
```php
// config/autoload/redis.php
return [
'default' => ['host' => env('REDIS_HOST'), 'auth' => env('REDIS_AUTH'), 'port' => (int) env('REDIS_PORT', 6379), 'db' => (int) env('REDIS_DB', 0), 'pool' => ['min_connections' => 5, 'max_connections' => 30, ...]],
'cache' => ['db' => (int) env('REDIS_CACHE_DB', 1), 'pool' => [...]] // 独立连接池
];
```
## Cache-Aside 模式
CacheService`withCache($key, $ttl, $fetcher)` — get 命中则返回,否则 fetcher() 后 setexTTL 加 jitter 防 stampede。`invalidate($keys)``invalidatePattern($pattern)` 用 scan 分批 del。
## CachedRepository 装饰器
实现 RepositoryInterface包装 baseRepo。getById/getPageList 用 withCachekey 格式 `{entity}:{id}``{entity}:list:{params_hash}`。invalidateDetail/invalidateList/invalidateAll。DI 注册时用 closure 返回 new CachedRepository(baseRepo, cacheService, 'order', detailTtl, listTtl)。Service 写操作后判断 `$repository instanceof CachedRepository` 则 invalidateAll。
## TTL 规范
Profile 30m、列表 5m、配置 1h、JWT 2h、Session 24h、限流与窗口对齐、验证码 5m、锁 任务时长+30s。
## Key 命名
`<namespace>:<entity>:<id>:<field>`,如 user:profile:123、orders:list:page:1、rate:limit:ip:api、session:user:456、lock:order:789、ws:connection:fd:100。
## 分布式锁
RedisLockServicewithLock($lockKey, $ttlMs, $fn)。SET NX PX。释放用 Lua 脚本原子校验 value 后 DEL。
## 缓存穿透/击穿
穿透:不存在 key 缓存 NULL_PLACEHOLDERTTL 30s。击穿热点 key 用 withLock 互斥double-check 后 fetcher 再 setex。
## 装饰器 vs 直接缓存 决策
读写比 > 10:1 → CachedRepository。读写比 < 10:1 → Service 内 CacheService。热点数据排行榜→ Redis 原生 ZSET/INCR。