package cache import ( "errors" . "code.hoteas.com/golang/hotime/common" ) // HoTimeCache 可配置memory,db,redis,默认启用memory,默认优先级为memory>redis>db,memory与数据库缓存设置项一致, // 缓存数据填充会自动反方向反哺,加入memory缓存过期将自动从redis更新,但memory永远不会更新redis,如果是集群建议不要开启memory,配置即启用 type HoTimeCache struct { *Error dbCache *CacheDb redisCache *CacheRedis memoryCache *CacheMemory Config Map } func (that *HoTimeCache) Session(key string, data ...interface{}) *Obj { var reData *Obj if len(data) == 0 { //内存缓存有 if that.memoryCache != nil && that.memoryCache.SessionSet { reData = that.memoryCache.Cache(key, data...) if reData.Data != nil { return reData } } //redis缓存有 if that.redisCache != nil && that.redisCache.SessionSet { reData = that.redisCache.Cache(key, data...) if reData.Data != nil { if that.memoryCache != nil && that.memoryCache.SessionSet { that.memoryCache.Cache(key, reData.Data) } return reData } } //db缓存有 if that.dbCache != nil && that.dbCache.SessionSet { reData = that.dbCache.Cache(key, data...) if reData.Data != nil { if that.memoryCache != nil && that.memoryCache.SessionSet { that.memoryCache.Cache(key, reData.Data) } if that.redisCache != nil && that.redisCache.SessionSet { that.redisCache.Cache(key, reData.Data) } return reData } } return reData } //设置缓存 //设置内存缓存 if that.memoryCache != nil && that.memoryCache.SessionSet { reData = that.memoryCache.Cache(key, data...) } //redis缓存有 if that.redisCache != nil && that.redisCache.SessionSet { reData = that.redisCache.Cache(key, data...) } //redis缓存有 if that.dbCache != nil && that.dbCache.SessionSet { reData = that.dbCache.Cache(key, data...) } return reData } func (that *HoTimeCache) Db(key string, data ...interface{}) *Obj { var reData *Obj if len(data) == 0 { //内存缓存有 if that.memoryCache != nil && that.memoryCache.DbSet { reData = that.memoryCache.Cache(key, data...) if reData.Data != nil { return reData } } //redis缓存有 if that.redisCache != nil && that.redisCache.DbSet { reData = that.redisCache.Cache(key, data...) if reData.Data != nil { if that.memoryCache != nil && that.memoryCache.DbSet { that.memoryCache.Cache(key, reData.Data) } return reData } } //db缓存有 if that.dbCache != nil && that.dbCache.DbSet { reData = that.dbCache.Cache(key, data...) if reData.Data != nil { if that.memoryCache != nil && that.memoryCache.DbSet { that.memoryCache.Cache(key, reData.Data) } if that.redisCache != nil && that.redisCache.DbSet { that.redisCache.Cache(key, reData.Data) } return reData } } return reData } //设置缓存 //设置内存缓存 if that.memoryCache != nil && that.memoryCache.DbSet { reData = that.memoryCache.Cache(key, data...) } //redis缓存有 if that.redisCache != nil && that.redisCache.DbSet { reData = that.redisCache.Cache(key, data...) } //db缓存有 if that.dbCache != nil && that.dbCache.DbSet { reData = that.dbCache.Cache(key, data...) } return reData } func (that *HoTimeCache) Cache(key string, data ...interface{}) *Obj { var reData *Obj if len(data) == 0 { //内存缓存有 if that.memoryCache != nil { reData = that.memoryCache.Cache(key, data...) if reData != nil && reData.Data != nil { return reData } } //redis缓存有 if that.redisCache != nil { reData = that.redisCache.Cache(key, data...) if reData != nil && reData.Data != nil { if that.memoryCache != nil { that.memoryCache.Cache(key, reData.Data) } return reData } } //db缓存有 if that.dbCache != nil { reData = that.dbCache.Cache(key, data...) if reData != nil && reData.Data != nil { if that.memoryCache != nil { that.memoryCache.Cache(key, reData.Data) } if that.redisCache != nil { that.redisCache.Cache(key, reData.Data) } return reData } } return reData } //设置缓存 //设置内存缓存 if that.memoryCache != nil { reData = that.memoryCache.Cache(key, data...) } //redis缓存有 if that.redisCache != nil { reData = that.redisCache.Cache(key, data...) } //db缓存有 if that.dbCache != nil { reData = that.dbCache.Cache(key, data...) } return reData } // SessionsGet 批量获取 Session 缓存 // 返回 Map,key 为缓存键,value 为缓存值 // 优先级:memory > redis > db,低优先级数据会反哺到高优先级缓存 func (that *HoTimeCache) SessionsGet(keys []string) Map { if len(keys) == 0 { return Map{} } result := make(Map, len(keys)) missingKeys := keys // 从 memory 获取 if that.memoryCache != nil && that.memoryCache.SessionSet { memResult := that.memoryCache.CachesGet(keys) for k, v := range memResult { result[k] = v } // 计算未命中的 keys missingKeys = make([]string, 0) for _, k := range keys { if _, exists := result[k]; !exists { missingKeys = append(missingKeys, k) } } } // 从 redis 获取未命中的 if len(missingKeys) > 0 && that.redisCache != nil && that.redisCache.SessionSet { redisResult := that.redisCache.CachesGet(missingKeys) // 反哺到 memory if that.memoryCache != nil && that.memoryCache.SessionSet && len(redisResult) > 0 { that.memoryCache.CachesSet(redisResult) } for k, v := range redisResult { result[k] = v } // 更新未命中的 keys newMissing := make([]string, 0) for _, k := range missingKeys { if _, exists := result[k]; !exists { newMissing = append(newMissing, k) } } missingKeys = newMissing } // 从 db 获取未命中的 if len(missingKeys) > 0 && that.dbCache != nil && that.dbCache.SessionSet { dbResult := that.dbCache.CachesGet(missingKeys) // 反哺到 memory 和 redis if len(dbResult) > 0 { if that.memoryCache != nil && that.memoryCache.SessionSet { that.memoryCache.CachesSet(dbResult) } if that.redisCache != nil && that.redisCache.SessionSet { that.redisCache.CachesSet(dbResult) } } for k, v := range dbResult { result[k] = v } } return result } // SessionsSet 批量设置 Session 缓存 // data: Map,key 为缓存键,value 为缓存值 func (that *HoTimeCache) SessionsSet(data Map) { if len(data) == 0 { return } if that.memoryCache != nil && that.memoryCache.SessionSet { that.memoryCache.CachesSet(data) } if that.redisCache != nil && that.redisCache.SessionSet { that.redisCache.CachesSet(data) } if that.dbCache != nil && that.dbCache.SessionSet { that.dbCache.CachesSet(data) } } // SessionsDelete 批量删除 Session 缓存 func (that *HoTimeCache) SessionsDelete(keys []string) { if len(keys) == 0 { return } if that.memoryCache != nil && that.memoryCache.SessionSet { that.memoryCache.CachesDelete(keys) } if that.redisCache != nil && that.redisCache.SessionSet { that.redisCache.CachesDelete(keys) } if that.dbCache != nil && that.dbCache.SessionSet { that.dbCache.CachesDelete(keys) } } // CachesGet 批量获取普通缓存 // 返回 Map,key 为缓存键,value 为缓存值 // 优先级:memory > redis > db,低优先级数据会反哺到高优先级缓存 func (that *HoTimeCache) CachesGet(keys []string) Map { if len(keys) == 0 { return Map{} } result := make(Map, len(keys)) missingKeys := keys // 从 memory 获取 if that.memoryCache != nil { memResult := that.memoryCache.CachesGet(keys) for k, v := range memResult { result[k] = v } // 计算未命中的 keys missingKeys = make([]string, 0) for _, k := range keys { if _, exists := result[k]; !exists { missingKeys = append(missingKeys, k) } } } // 从 redis 获取未命中的 if len(missingKeys) > 0 && that.redisCache != nil { redisResult := that.redisCache.CachesGet(missingKeys) // 反哺到 memory if that.memoryCache != nil && len(redisResult) > 0 { that.memoryCache.CachesSet(redisResult) } for k, v := range redisResult { result[k] = v } // 更新未命中的 keys newMissing := make([]string, 0) for _, k := range missingKeys { if _, exists := result[k]; !exists { newMissing = append(newMissing, k) } } missingKeys = newMissing } // 从 db 获取未命中的 if len(missingKeys) > 0 && that.dbCache != nil { dbResult := that.dbCache.CachesGet(missingKeys) // 反哺到 memory 和 redis if len(dbResult) > 0 { if that.memoryCache != nil { that.memoryCache.CachesSet(dbResult) } if that.redisCache != nil { that.redisCache.CachesSet(dbResult) } } for k, v := range dbResult { result[k] = v } } return result } // CachesSet 批量设置普通缓存 // data: Map,key 为缓存键,value 为缓存值 func (that *HoTimeCache) CachesSet(data Map) { if len(data) == 0 { return } if that.memoryCache != nil { that.memoryCache.CachesSet(data) } if that.redisCache != nil { that.redisCache.CachesSet(data) } if that.dbCache != nil { that.dbCache.CachesSet(data) } } // CachesDelete 批量删除普通缓存 func (that *HoTimeCache) CachesDelete(keys []string) { if len(keys) == 0 { return } if that.memoryCache != nil { that.memoryCache.CachesDelete(keys) } if that.redisCache != nil { that.redisCache.CachesDelete(keys) } if that.dbCache != nil { that.dbCache.CachesDelete(keys) } } func (that *HoTimeCache) Init(config Map, hotimeDb HoTimeDBInterface, err ...*Error) { //防止空数据问题 if config == nil { config = Map{} } if err[0] != nil { that.Error = err[0] } that.Config = config //memory配置初始化 memory := that.Config.GetMap("memory") if memory == nil { memory = Map{ "db": true, "session": true, "sort": 0, "timeout": 60 * 60 * 2, } } if memory.Get("db") == nil { memory["db"] = true } if memory.Get("session") == nil { memory["session"] = true } if memory.Get("timeout") == nil { memory["timeout"] = 60 * 60 * 2 } that.Config["memory"] = memory that.memoryCache = &CacheMemory{TimeOut: memory.GetCeilInt64("timeout"), DbSet: memory.GetBool("db"), SessionSet: memory.GetBool("session")} if err[0] != nil { that.memoryCache.SetError(err[0]) } //db配置初始化 redis := that.Config.GetMap("redis") if redis != nil { if redis.GetString("host") == "" || redis.GetString("port") == "" { if err[0] != nil { err[0].SetError(errors.New("请检查redis配置host和port配置")) } return } if redis.Get("db") == nil { redis["db"] = true } if redis.Get("session") == nil { redis["session"] = true } if redis.Get("timeout") == nil { redis["timeout"] = 60 * 60 * 24 * 15 } that.Config["redis"] = redis that.redisCache = &CacheRedis{TimeOut: redis.GetCeilInt64("timeout"), DbSet: redis.GetBool("db"), SessionSet: redis.GetBool("session"), Host: redis.GetString("host"), Pwd: redis.GetString("password"), Port: redis.GetCeilInt64("port")} if err[0] != nil { that.redisCache.SetError(err[0]) } } //db配置初始化 db := that.Config.GetMap("db") if db != nil { if db.Get("db") == nil { db["db"] = false } if db.Get("session") == nil { db["session"] = true } if db.Get("timeout") == nil { db["timeout"] = 60 * 60 * 24 * 30 } // mode 默认为 "compatible"(兼容模式,便于老系统平滑升级) if db.Get("mode") == nil { db["mode"] = CacheModeCompatible } that.Config["db"] = db that.dbCache = &CacheDb{ TimeOut: db.GetCeilInt64("timeout"), DbSet: db.GetBool("db"), SessionSet: db.GetBool("session"), HistorySet: db.GetBool("history"), Mode: db.GetString("mode"), Db: hotimeDb, } if err[0] != nil { that.dbCache.SetError(err[0]) } } } func (that *HoTimeCache) DisableDbCache() { that.dbCache = nil that.redisCache = nil }