본문으로 건너뛰기

[Loki] LogQL 벤치마크에 오브젝트 스토리지 지연 시뮬레이션 추가

PR 링크: grafana/loki#20733 상태: Merged | 변경: +109 / -3

들어가며

로컬 파일시스템에서 벤치마크를 실행하면 I/O 지연이 거의 0에 가깝기 때문에 프로덕션(S3, GCS 등)에서의 성능을 정확히 반영하지 못합니다. 이 PR은 -storage-latency 플래그를 추가하여 요청당 지연을 주입하고, 각 엔진이 스토리지 지연에 얼마나 민감한지 측정할 수 있게 합니다.

핵심 코드 분석

Decorator 패턴으로 지연 주입

objstore.Bucket 래퍼 (dataobj 엔진용):

type latencyBucket struct {
    objstore.Bucket
    latency time.Duration
}

func (b *latencyBucket) Get(ctx context.Context, name string) (io.ReadCloser, error) {
    b.delay()
    return b.Bucket.Get(ctx, name)
}

func (b *latencyBucket) GetRange(ctx context.Context, name string, off, length int64) (io.ReadCloser, error) {
    b.delay()
    return b.Bucket.GetRange(ctx, name, off, length)
}

ObjectClient 래퍼 (chunk store용):

type latencyObjectClient struct {
    objectclient.ObjectClient
    latency time.Duration
}

func (c *latencyObjectClient) GetObject(ctx context.Context, objectKey string) (io.ReadCloser, int64, error) {
    c.delay()
    return c.ObjectClient.GetObject(ctx, objectKey)
}

프로덕션 코드에 영향 없는 hook 설계

type Config struct {
    // yaml:"-" 태그로 설정 파일에서 무시
    ObjectClientDecorator func(client.ObjectClient) client.ObjectClient `yaml:"-"`
}

func NewObjectClient(...) (client.ObjectClient, error) {
    // ...
    if cfg.ObjectClientDecorator != nil {
        actual = cfg.ObjectClientDecorator(actual)
    }
    return actual, nil
}

사용법

# 동일 리전 S3 시뮬레이션 (10ms)
go test -bench=BenchmarkLogQL -storage-latency=10ms ./pkg/logql/bench/

# 크로스 리전 시뮬레이션 (50ms)
go test -bench=BenchmarkLogQL -storage-latency=50ms ./pkg/logql/bench/

왜 이게 좋은가

  • Decorator 패턴으로 기존 인터페이스를 변경하지 않고 동작을 주입합니다
  • yaml:"-"와 nil 체크로 프로덕션 코드 경로에는 영향이 전혀 없습니다
  • 두 스토리지 백엔드(dataobj 엔진, chunk store) 모두에 일관되게 적용됩니다
  • 새로운 쿼리 엔진과 기존 엔진의 I/O 효율성을 공정하게 비교할 수 있습니다
  • 실제 클라우드 환경 없이도 프로덕션에 가까운 벤치마크가 가능해집니다

참고 자료

댓글

관련 포스트

PR Analysis 의 다른글