H
하베스트
AI로 요약된 콘텐츠

Go 1.24의 스위스 테이블(Swiss Tables)이 Datadog에서 수백 기가바이트의 메모리를 절감한 방법

Datadog은 Go 1.24 업그레이드 과정에서 메모리 사용량 이슈를 추적하며, 새로운 스위스 테이블(Swiss Tables) 도입이 대규모 서비스에서 막대한 메모리 절감으로 이어졌음을 확인했습니다. 대용량 맵의 동작 원리, 메모리 프로파일링, 구조체 수준의 최적화 과정을 시간 순서대로 상세히 분석하고, 실질적인 운영 비용 절감까지의 여정을 담았습니다. 핵심은 Go 1.24의 변화된 맵 구현이 대규모 환경에서의 메모리 효율과 구조 자체의 혁신적인 최적화를 가능하게 했다는 점입니다.


1. Go 1.24 도입과 예상 밖의 메모리 절감

Datadog은 Go 1.24로 업그레이드하면서 런타임 레벨의 메모리 증가(regression) 문제를 파악하여 Go 커뮤니티와 함께 원인 분석 및 패치 적용까지 완료했습니다. 하지만 기대와 달리 가장 트래픽이 많은 환경에서 메모리 사용량이 이전보다 훨씬 더 감소하는 현상이 나타났습니다. 그 이유를 찾기 위해 런타임 라이브 힙 프로파일을 상세히 들여다보기 시작했습니다.

"우리는 ShardRouter 패키지의 shardRoutingCache 맵에서 약 500MiB의 라이브 힙 사용량을 절감했습니다."

이 수치는 Go GC 정책(GOGC)까지 고려하면 실제 메모리 사용량이 1GiB(500MiB x 2) 감소한 것을 의미합니다. 파트1에서 언급한 mallocgc 관련 메모리 증가(~400MiB)를 반영해도 전체적으로 약 600MiB 메모리 순감소가 있었습니다.


2. 대형 맵과 기존(Go 1.23) 버킷 기반 해시테이블 구조

Datadog의 데이터 처리 서비스 일부는 ShardRouter라는 패키지를 사용합니다. 서비스 시작 시 데이터베이스에서 데이터를 가져와 shardRoutingCache 맵에 채웁니다. 맵의 타입은 다음과 같습니다.

shardRoutingCache map[string]Response

여기서 값 타입(Response)은 여러 필드를 가지지만, 실제로 대부분의 필드가 사용되지 않는 경우도 많았습니다.

맵 동작 방식 및 메모리 산출

  • Go 1.23의 맵 구현은 2의 거듭제곱 개수(bucket)의 배열에 각 버킷당 8개의 슬롯을 갖는 구조였습니다.
  • 맵의 성장이 필요할 때, 실제 데이터를 두 배열(구버전/신버전 bucket array)에 두고 점진적으로 옮기기 때문에 메모리 사용량이 일시적으로 2배 가까이 증가합니다.
  • 실 예로, map에 3,500,000개의 요소가 있다면 약 1,048,576개의 버킷이 필요하며, 실제로는 버킷 교체 작업으로 인해 1,572,864개의 버킷이 할당됨을 확인했습니다.
  • 각 버킷(8슬롯)은 464바이트를 차지하여 총 약 726MiB에 달하는 메모리가 맵 본체에 의해 소모되었습니다.
  • 여기에 각 라우팅키 string의 실제 데이터 공간(약 200MiB)까지 합치면 약 930MiB의 라이브 힙 사용량이 프로파일에서 관찰됐습니다.

"이 수치는 실제 운영 환경에서 본 것과도 잘 일치합니다: Go 1.23의 shardRoutingCache 맵 힙 점유량은 약 930MiB에 달했죠."


3. Go 1.24의 스위스 테이블과 확장 해싱(Extendible Hashing)의 도입

Go 1.24에서는 스위스 테이블(Swiss Tables))과 확장 해싱(Extendible Hashing) 기반으로 맵 구조가 완전히 재설계됩니다.

  • 데이터를 그룹(8개 슬롯) 기반으로 묶고, 각 그룹에는 64비트 컨트롤 워드가 추가되어, 슬롯 상태(비었음, 삭제됨, 사용 중)와 해시 일부를 즉시 판별할 수 있도록 합니다.
  • SIMD처럼 CPU의 한 번의 명령(혹은 비트연산)으로 8개 슬롯을 한꺼번에 비교해 탐색 효율을 극대화합니다.

"스위스 테이블에서는 컨트롤 워드 덕분에 모든 슬롯을 일일이 선형 검색하지 않고, 한 번에 슬롯 후보를 좁힐 수 있습니다."

  • 그룹이 꽉 차면 인접 그룹에 시도하며, 오버플로우 버킷 개념이 완전히 없어집니다.
  • Go 1.24의 각 스위스 테이블은 최대 128개 그룹(1,024 슬롯)만을 담고, 이를 확장하는 방식으로 분할(split)과 디렉토리 기반 여러 테이블로 확장성을 갖춥니다.

"Go 1.24의 테이블 스플리팅 접근법은 Go 1.23처럼 오래된 버킷까지 계속 메모리에 남겨두지 않으므로, 더 메모리 효율적입니다."

메모리 사용량 비교

  • 동일한 3,500,000개 요소의 경우,
    • 스위스 테이블 구조에서는 약 217MiB로 맵 본체의 메모리 점유가 대폭 감소
    • Go 1.23 대비 약 500MiB의 힙 절감 효과 (실제 GC까지 고려하면 1GiB 수준)
    • 이는 실 운영 환경의 라이브 프로파일에서 확인된 데이터와 정확히 일치합니다.

4. 저트래픽 환경에서 절감 효과가 덜한 이유

트래픽이 적은 환경에서는 맵의 요소 수가 적어 절감 효과가 상대적으로 작았습니다.

  • 예시로, 550,000개의 요소라면,
    • Go 1.23: 약 62MiB
    • Go 1.24: 약 34MiB
    • 절감 폭은 28MiB로, 이전 mallocgc 이슈로 인한 200~300MiB 증가를 상쇄하지 못해 전체 메모리 사용량은 오히려 소폭 증가
  • 하지만 더 개선할 여지가 있는지 점검했습니다.

5. 구조체(Struct) 최적화로 추가 메모리 절약

코드를 재검토하다 보니, shardRoutingCache 맵에 저장할 때 Response 구조체의 RoutingKey 및 LastModified 필드가 전혀 사용되지 않고 있음을 발견했습니다. 또한 ShardType 필드도 실제로는 3가지 값만 사용되어, 굳이 int64가 아닌 uint8로 줄일 수 있었습니다.

다음 두 가지 최적화를 적용했습니다.

  1. ShardType의 타입을 int → uint8로 변경해 공간 절약 (255개 enum 지원)
  2. shardRoutingCache 용 별도 구조체(cachedResponse)를 도입해, 불필요한 string, nil 포인터 필드 제거

"이 변경 덕분에 각 key-value 쌍이 56바이트에서 24바이트로 감소했습니다."

실질적 영향

  • 맵 전체 크기: 217MiB → 93MiB로 대폭 감소
  • GOGC 효과 반영 시, 데이터 처리 서비스 전체에서 pod당 약 250MiB RAM 추가 감소
  • 실제 라이브 힙 프로파일에서 확인하여 운영 적용

6. 운영 비용 절감 및 인프라 영향

최적화 후, Datadog은 freed memory를다음 두 가지 방식으로 활용할 수 있었습니다.

  1. 쿠버네티스 컨테이너 메모리 할당량 낮추기
    → freed memory를 클러스터 내 다른 앱이 활용 가능

  2. GOMEMLIMIT 설정으로 CPU와 메모리 트레이드 오프
    → 일부 CPU 바운드 workload는 메모리 자원을 CPU 효율 향상에 활용해, pod 개수 downscaling 가능


7. Go 1.24와 메모리 최적화 여정, 교훈

마지막으로, 이번 경험에서 얻은 주요 교훈은 다음과 같습니다.

  • 런타임 변화 추적 및 커뮤니티 협업의 중요성

    "우리는 Go 1.24에서 도입된 미묘하지만 임팩트가 큰 메모리 회귀 이슈를 찾아내고 패치에 기여했습니다."

  • 언어 버전 업그레이드시 단순 성능 향상 기대보다는, 불가피하게 이슈가 발견될 수 있음을 항상 염두에 둘 것
    → 최신 버전에서만 누릴 수 있는 최적화(ex. Swiss Tables)는 적극 활용, 문제점은 빠르게 발견·대응해야 함

  • 정확한 런타임 메트릭과 라이브 힙 프로파일링이 문제 파악 및 커뮤니케이션에 결정적 역할

  • Go 1.24의 Swiss Table 도입이 대형 맵에서 메모리 사용량을 획기적으로 줄였음

    "대용량 환경에서 Map 메모리 사용량이 약 70% 감소했습니다."

  • 구조체 설계, 불필요한 필드 제거 및 타입 최적화 등 '사소해보이는' 코드 개선도 대규모 운영 환경에서는 막대한 효과를 발휘할 수 있음을 재확인


마치며

Go 1.24의 스위스 테이블 도입과 구조체 최적화는 Datadog의 대규모 서비스에 실질적인 메모리 절감과 운영비용 감소 효과를 가져왔습니다. 작은 디테일이 모여 대규모 시스템에서 놀라운 성능 향상으로 이어질 수 있음을 이번 사례가 잘 보여줍니다. Datadog은 앞으로도 커뮤니티와 함께 최신 기술 변화를 선도하며, 밑바닥부터 꼼꼼하게 최적화하는 엔지니어링 문화를 이어갈 계획입니다. 🚀

요약 완료: 2025. 11. 22. 오후 12:46:51

이런 요약이 필요하신가요?

하베스트가 원클릭으로 요약해드립니다

5초 요약
AI 자동 분석
📱
모든 기기
웹, iOS, Chrome
🔍
스마트 검색
언제든 재발견
요약 시작하기
나도 요약하기