Sobes.tech
Senior

Barcha 5 goroutine bir vaqtning o'zida bo'sh cache'ni ko'rib, ma'lumotlar bazasiga (cache stampede) borayotgan holatni qanday boshqarasiz?

sobes.tech AI

AIdan javob

Проблема 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.