Files
hotime/cache/cache.go
T
hoteas 9a9b9c83ff refactor(logging): 迁移日志记录到 Zerolog 并优化错误处理
- 将日志记录库从 Logrus 替换为 Zerolog,提升性能和灵活性
- 更新各个模块的日志记录方式,确保一致性
- 优化错误处理逻辑,确保在发生错误时能够正确记录并传递错误信息
- 移除不再使用的错误处理字段,简化代码结构
- 更新相关文档以反映新的日志记录和错误处理机制
2026-04-13 00:38:50 +08:00

471 lines
12 KiB
Go
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.
package cache
import (
. "code.hoteas.com/golang/hotime/common"
"code.hoteas.com/golang/hotime/log"
)
// HoTimeCache 可配置memorydbredis,默认启用memory,默认优先级为memory>redis>db,memory与数据库缓存设置项一致,
// 缓存数据填充会自动反方向反哺,加入memory缓存过期将自动从redis更新,但memory永远不会更新redis,如果是集群建议不要开启memory,配置即启用
type HoTimeCache struct {
Log *log.Logger
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 缓存
// 返回 Mapkey 为缓存键,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: Mapkey 为缓存键,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 批量获取普通缓存
// 返回 Mapkey 为缓存键,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: Mapkey 为缓存键,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, logger *log.Logger) {
if config == nil {
config = Map{}
}
that.Log = logger
that.Config = config
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"),
Log: logger}
redis := that.Config.GetMap("redis")
if redis != nil {
if redis.GetString("host") == "" || redis.GetString("port") == "" {
if logger != nil {
logger.Error().Msg("请检查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"),
Log: logger}
}
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
}
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,
Log: logger,
}
}
}
func (that *HoTimeCache) DisableDbCache() {
that.dbCache = nil
that.redisCache = nil
}