When dealing with cache invalidation in Golang, you can follow the following strategy: mark cache items with timestamps, and get new data when they expire. Using locks, the cache is locked when the coroutine obtains the cache item, and the cache is unlocked and new data is obtained when the cache item does not exist or expires.
#How to deal with Golang cache failure?
When using cache in Golang programs, it is crucial to deal with cache invalidations to ensure data consistency and reliability. The following are two processing strategies:
1. Use timestamps
type CacheItem struct { Value interface{} Timestamp time.Time } var cache = make(map[string]CacheItem) func SetCache(key string, value interface{}) { cache[key] = CacheItem{Value: value, Timestamp: time.Now()} } func GetCache(key string) (interface{}, bool) { item, ok := cache[key] if ok && time.Since(item.Timestamp) < time.Second*30 { return item.Value, true } return nil, false }
2. Use lock
var cache = sync.Map{} func SetCache(key string, value interface{}) { cache.Store(key, value) } func GetCache(key string) (interface{}, bool) { if value, ok := cache.Load(key); ok { return value, true } lock := sync.Mutex{} lock.Lock() defer lock.Unlock() if value, ok := cache.Load(key); ok { return value, true } newValue, err := fetchNewValue(key) if err == nil { cache.Store(key, newValue) } return newValue, err == nil }
Practical Case
Suppose we are using cache in a RESTful API to store user details.
package main import ( "encoding/json" "fmt" "net/http" "time" "github.com/go-redis/redis/v8" ) var redisClient = redis.NewClient(&redis.Options{}) type User struct { ID int Name string } func main() { // 添加缓存处理 http.HandleFunc("/users/:id", func(w http.ResponseWriter, r *http.Request) { var user User id := r.URL.Path[len("/users/"):] // 尝试从缓存中获取用户数据 cachedUser, ok := GetCache(id) if ok { // 缓存命中 fmt.Fprintf(w, "User from cache: %+v", cachedUser) return } // 缓存未命中 // 从数据库中获取用户数据 err := db.Get(id, &user) if err != nil { // 数据库中不存在此用户 fmt.Fprintf(w, "User not found") return } // 设置缓存,有效期为 30 秒 SetCache(id, user, time.Second*30) fmt.Fprintf(w, "User from database: %+v", user) }) http.ListenAndServe(":8080", nil) } func GetCache(key string) (User, bool) { result, err := redisClient.Get(key).Bytes() if err != nil { return User{}, false } var user User err = json.Unmarshal(result, &user) if err != nil { return User{}, false } return user, true } func SetCache(key string, user User, expiration time.Duration) { jsonBytes, err := json.Marshal(user) if err != nil { return } err = redisClient.Set(key, jsonBytes, expiration).Err() if err != nil { return } }
The above is the detailed content of How to deal with Golang cache invalidation?. For more information, please follow other related articles on the PHP Chinese website!