Files
tyapi-server/docs/智能缓存机制说明.md
2025-07-28 01:46:39 +08:00

210 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 智能缓存机制说明
## 概述
为了解决 `EnabledTables` 配置问题,我们实现了一个智能缓存决策机制。该机制允许您:
1. **精确控制缓存表**:通过 `EnabledTables``DisabledTables` 精确控制哪些表使用缓存
2. **智能决策**`CachedBaseRepositoryImpl` 会自动根据配置决定是否使用缓存
3. **无需修改代码**钱包Repository等代码无需修改自动适应配置
## 核心组件
### 1. 全局缓存配置管理器 (`CacheConfigManager`)
```go
// 全局实例
var GlobalCacheConfigManager *CacheConfigManager
// 主要方法
func (m *CacheConfigManager) IsTableCacheEnabled(tableName string) bool
func (m *CacheConfigManager) IsTableCacheDisabled(tableName string) bool
func (m *CacheConfigManager) AddEnabledTable(tableName string)
func (m *CacheConfigManager) AddDisabledTable(tableName string)
```
### 2. 智能缓存Repository (`CachedBaseRepositoryImpl`)
```go
// 智能决策方法
func (r *CachedBaseRepositoryImpl) shouldUseCacheForTable() bool
func (r *CachedBaseRepositoryImpl) isTableCacheEnabled() bool
// 智能缓存方法
func (r *CachedBaseRepositoryImpl) GetWithCache(ctx context.Context, dest interface{}, ttl time.Duration, where string, args ...interface{}) error
func (r *CachedBaseRepositoryImpl) FindWithCache(ctx context.Context, dest interface{}, ttl time.Duration, where string, args ...interface{}) error
```
### 3. 智能GORM插件 (`GormCachePlugin`)
```go
// 智能缓存决策
func (p *GormCachePlugin) shouldCache(db *gorm.DB) bool
func (p *GormCachePlugin) shouldInvalidateTable(table string) bool
```
## 工作原理
### 1. 配置初始化
```go
// 在 cache_setup.go 中
cacheConfig := cache.CacheConfig{
EnabledTables: []string{
"users",
"product",
"product_category",
// 注意:这里没有 "wallets"
},
DisabledTables: []string{
"audit_logs",
"system_logs",
},
}
// 初始化全局管理器
cache.InitCacheConfigManager(cacheConfig)
```
### 2. 智能决策流程
当钱包Repository调用缓存方法时
```go
// 钱包Repository代码无需修改
func (r *GormWalletRepository) GetByUserID(ctx context.Context, userID string) (*Wallet, error) {
var wallet Wallet
err := r.CachedBaseRepositoryImpl.GetWithCache(ctx, &wallet, 5*time.Minute, "user_id = ?", userID)
return &wallet, err
}
```
**决策流程:**
1. **Repository层**:调用 `GetWithCache` 方法
2. **智能决策**`shouldUseCacheForTable()` 检查 `wallets` 表是否启用缓存
3. **配置检查**:通过 `GlobalCacheConfigManager.IsTableCacheEnabled("wallets")` 检查
4. **结果处理**
- 如果启用缓存:设置 `cache:enabled=true`,正常使用缓存
- 如果禁用缓存:设置 `cache:disabled=true`,跳过缓存,直接查询数据库
### 3. 缓存失效智能控制
```go
// GORM回调中的智能失效
func (p *GormCachePlugin) afterCreate(db *gorm.DB) {
if !p.config.AutoInvalidate || db.Error != nil {
return
}
// 只对启用缓存的表执行失效操作
if p.shouldInvalidateTable(db.Statement.Table) {
p.invalidateTableCache(db.Statement.Context, db.Statement.Table)
}
}
```
## 使用场景
### 场景1钱包表不启用缓存
```go
// 配置中不包含 wallets
EnabledTables: []string{
"users",
"product",
// 没有 "wallets"
}
// 结果:钱包查询不使用缓存,直接查询数据库
// 不会触发缓存失效操作,避免 "context canceled" 错误
```
### 场景2钱包表启用缓存
```go
// 配置中包含 wallets
EnabledTables: []string{
"users",
"product",
"wallets", // 添加钱包表
}
// 结果:钱包查询正常使用缓存
// 缓存失效操作正常执行
```
### 场景3动态调整
```go
// 运行时动态启用钱包缓存
cache.GlobalCacheConfigManager.AddEnabledTable("wallets")
// 运行时动态禁用钱包缓存
cache.GlobalCacheConfigManager.AddDisabledTable("wallets")
```
## 优势
### 1. **精确控制**
- 通过配置精确控制哪些表使用缓存
- 避免对不需要缓存的表执行无效操作
### 2. **代码无需修改**
- Repository层代码无需修改
- 自动适应配置变化
### 3. **性能优化**
- 避免对未启用缓存的表执行缓存失效操作
- 减少Redis无效操作提高性能
### 4. **错误消除**
- 彻底解决 `"context canceled"` 错误
- 避免对不存在缓存数据的表执行失效操作
### 5. **灵活配置**
- 支持运行时动态调整
- 支持环境级别的配置差异
## 监控和调试
### 1. 查看表缓存状态
```go
// 获取单个表状态
status := cache.GlobalCacheConfigManager.GetTableCacheStatus("wallets")
// 返回:{"table_name": "wallets", "enabled": false, "disabled": true, ...}
// 获取所有表状态
allStatus := cache.GlobalCacheConfigManager.GetAllTableStatus()
```
### 2. 日志监控
```go
// 启用缓存的查询
"执行带缓存查询" {"table": "users", "ttl": "5m0s", "where": "id = ?"}
// 禁用缓存的查询
"执行无缓存查询" {"table": "wallets", "where": "user_id = ?"}
// 表未启用缓存的提示
"表未启用缓存,跳过缓存操作" {"table": "wallets"}
```
## 最佳实践
### 1. **配置原则**
- 只对查询频繁、数据变化不频繁的表启用缓存
- 对实时性要求高的表(如钱包余额)谨慎使用缓存
- 对日志表等大数据量表禁用缓存
### 2. **性能考虑**
- 合理设置TTL平衡缓存命中率和数据一致性
- 监控缓存命中率和失效频率
- 根据业务特点调整缓存策略
### 3. **运维建议**
- 定期检查缓存配置的合理性
- 监控Redis内存使用情况
- 根据业务增长调整缓存容量