テック技報最新号へ →
コード

Go: singleflight で同じキーの同時呼び出しを1本にまとめる

golang.org/x/sync/singleflight は、同じキーへの並行呼び出しを1回の実行にまとめ、結果を全員に返す。キャッシュ失効直後の DB スタンピード対策に向く。

@amitsinha__07 · 投稿 2026-11-05
#go#concurrency#cache#x-sync

使う場面

ホットなキャッシュキーが切れ、数百リクエストが一斉に同じ loadFromDB(key) を叩くとき。セマフォで同時数を絞るだけでは「同じ仕事の重複」は減らない。

やり方

go
import "golang.org/x/sync/singleflight"

var g singleflight.Group

func getUser(ctx context.Context, id string) (User, error) {
    v, err, _ := g.Do(id, func() (any, error) {
        return loadFromDB(ctx, id)
    })
    if err != nil {
        return User{}, err
    }
    return v.(User), nil
}

注意点

  • Do の中でパニックすると、待っていた全員に伝播する。
  • キーの粒度が粗すぎると無関係な呼び出しまで待たされる。細すぎると効果が薄い。
  • 失敗も共有されるので、一時的なエラーをキャッシュに載せたくないなら、呼び出し側でリトライ方針を決める。
  • 標準ライブラリではなく x/sync モジュール。go get golang.org/x/sync が必要。

出典

X の元の投稿を開く