Go singleflight로 캐시 분해 방지 방법
AI Store에서 AI코딩으로 만들어진 앱을 만나보세요!
지금 바로 방문하기

캐시 분해 방지와 Go의 singleflight 사용

카테고리

프로그래밍/소프트웨어 개발

서브카테고리

웹 개발

대상자

고성능 서비스 개발자, Go 언어 사용자, 고并发 환경에서 캐시 최적화를 고려하는 개발자

핵심 요약

  • 캐시 분해(cache breakdown)는 고并发 시 핫키의 만료로 인해 데이터베이스 과부하를 유발하는 문제로, singleflight 패키지가 이를 방지함
  • singleflight.Group.Do 메서드는 동일한 키에 대한 요청을 한 번만 실행하여 다중 요청을 하나로 통합
  • Group 구조체는 요청을 관리하고, DoChan은 비동기 결과 처리를 지원하며, Forget은 캐시 결과를 강제로 삭제

섹션별 세부 요약

1. 캐시 분해 문제와 일반적인 해결 방법

  • 캐시 분해는 핫키 만료 시 다수의 요청이 데이터베이스에 동시에 접근하여 발생
  • 일반적인 해결 방법:
  • 핫 데이터의 만료 시간을 무한으로 설정
  • 뮤텍스 잠금을 통해 한 번에 하나의 요청만 처리
  • 백그라운드에서 캐시 업데이트

2. `singleflight` 패키지 구성 요소

  • Group: 동일한 키의 요청을 통합 관리하는 핵심 구조체
  • Do 메서드: 동일한 키의 요청이 있을 경우 하나의 요청만 실행하고 나머지 요청은 결과를 공유
  • 리턴 값: (result, error, shared)
  • DoChan: 비동기 결과 처리를 위한 채널 리턴
  • Forget: 특정 키의 요청 기록을 삭제하여 새 요청을 강제로 생성

3. `singleflight` 예제 사용

  • Do 메서드를 사용하여 캐시 미스 시 데이터베이스 조회 수행
  • 5개의 goroutine이 동일한 키를 요청해도 한 번만 실행되고 결과가 공유됨
  • 예제 코드:

```go

v, err, shared := sg.Do("key", fetchData)

```

  • 결과: shared: true로 모든 요청이 동일한 결과를 공유

4. 키 설계와 타임아웃 처리

  • 키의 유니크성과 일관성 보장: {type}:{identifier} 형식 사용 (예: user:1234)
  • 타임아웃 관리: DoChanselect 문을 통해 시간 초과 시 대체 전략 실행

```go

select {

case <-doChan:

fmt.Println("done")

case <-time.After(2 * time.Second):

fmt.Println("timeout")

}

```

결론

singleflight는 고并发 환경에서 캐시 분해를 효과적으로 방지하여 데이터베이스 부하를 줄이고 성능을 개선합니다. 키의 일관성 유지타임아웃 처리 전략을 적용하여 시스템의 반응성을 높이는 것이 중요합니다.