Senior
How to handle a situation when all 5 goroutines simultaneously see an empty cache and go to the database (cache stampede)?
sobes.tech AI
Answer from AI
The cache stampede problem occurs when multiple goroutines simultaneously see that the cache is empty and all start querying the database, creating excessive load.
To prevent this, the following approaches can be used:
- Singleflight — in Go, there is the
golang.org/x/sync/singleflightpackage, which allows grouping multiple concurrent requests with the same key into a single database request, while other goroutines wait for the result.
import (
"golang.org/x/sync/singleflight"
)
var group singleflight.Group
func GetData(key string) (Data, error) {
v, err, _ := group.Do(key, func() (interface{}, error) {
// Check cache
data, found := cache.Get(key)
if found {
return data, nil
}
// If not, load from DB
data, err := db.Load(key)
if err != nil {
return nil, err
}
cache.Set(key, data)
return data, nil
})
if err != nil {
return nil, err
}
return v.(Data), nil
}
-
Mutexes or channels — you can use a mutex on the cache key so that only one goroutine loads the data, and others wait.
-
Cache warming — preloading the cache in advance to avoid situations where everyone sees an empty cache at the same time.
-
Using TTL and random delays — to prevent all cache entries from expiring simultaneously.
The simplest and most effective method in Go is to use singleflight."}]}]}