Sobes.tech
Назад к вопросам
Senior
4

Как обработать ситуацию, когда все 5 горутин одновременно видят пустой кэш и идут в БД (cache stampede)?

Компании, где спрашивали
РамблерРамблер

Ответ от нейросети

sobes.tech 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.