v0.1
This commit is contained in:
210
docs/智能缓存机制说明.md
Normal file
210
docs/智能缓存机制说明.md
Normal file
@@ -0,0 +1,210 @@
|
||||
# 智能缓存机制说明
|
||||
|
||||
## 概述
|
||||
|
||||
为了解决 `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内存使用情况
|
||||
- 根据业务增长调整缓存容量
|
||||
Reference in New Issue
Block a user