Sobes.tech
Senior

Cum gestionezi situația în care toate cele 5 goroutine văd simultan un cache gol și merg la baza de date (cache stampede)?

sobes.tech AI

Răspuns de la AI

Проблема cache stampede возникает, когда несколько горутин одновременно видят, что кэш пуст, и все начинают обращаться к базе данных, создавая избыточную нагрузку.

Чтобы это предотвратить, можно использовать следующие подходы:

  1. Singleflight (одиночный полёт) — в Go есть пакет golang.org/x/sync/singleflight, который позволяет сгруппировать несколько одновременных запросов с одинаковым ключом в один запрос к базе, а остальные горутины ждут результата.
import (
    "golang.org/x/sync/singleflight"
)

var group singleflight.Group

func GetData(key string) (Data, error) {
    v, err, _ := group.Do(key, func() (interface{}, error) {
        // Проверяем кэш
        data, found := cache.Get(key)
        if found {
            return data, nil
        }
        // Если нет, загружаем из БД
        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
}
  1. Мьютексы или каналы — можно использовать мьютекс на ключ кэша, чтобы только одна горутина загружала данные, а остальные ждали.

  2. Пре-загрузка кэша (cache warming) — обновлять кэш заранее, чтобы не было ситуаций, когда все одновременно видят пустой кэш.

  3. Использование TTL и случайных задержек — чтобы избежать одновременного истечения срока жизни кэша у всех.

Самый простой и эффективный способ в Go — использовать singleflight.