인프라와 도구 — 4 컴포넌트의 첫 3

Definition · Deployment · Instrumentation + 3 가지 배포 아키텍처

Kohavi (2020) Ch.4.5 의 인프라 4 컴포넌트 중 첫 3 개를 깊게 다룬다. 실험 사양·iteration 관리, variant assignment service, 3 가지 production 코드 아키텍처 (code fork / parameterized / config push), atomicity, 그리고 counterfactual 을 포함한 instrumentation 까지. 각 설계 결정의 트레이드오프와 직관을 함께 정리한다.

Experimentation
A/B Test
Platform
저자

Kwangmin Kim

공개

2026년 05월 08일

1 정의

정의: 실험 인프라 4 컴포넌트 (Experimentation Infrastructure)

Bing (Kohavi et al. 2009), LinkedIn (Xu et al. 2015), Google (Tang et al. 2010) 의 실험 플랫폼은 모두 다음 4 컴포넌트로 구성된다 (Kohavi, Tang, Xu, 2020, Ch.4.5).

  1. Experiment Definition / Set-up / Management — 사양 작성·iteration 관리·검증
  2. Experiment Deployment — variant assignment service + production 코드 변경
  3. Experiment Instrumentation — 사용자 행동 + variant·iteration 로깅
  4. Experimentation Analytics — data processing → computation → visualization

이 글은 첫 3 개 컴포넌트를 다루고, 4 번째 (Analytics) 와 변종 배정 확장 (Single-Layer / Concurrent) 은 후속 글 F4-4 에서 다룬다.

플랫폼의 목표는 실험을 셀프서비스로 만드는 것이다. 즉, 실험자가 데이터 사이언티스트나 플랫폼 엔지니어의 hands-on 도움 없이도 안전하고 신뢰할 수 있는 실험을 시작·중단·분석할 수 있어야 한다.

2 개념 및 원리

2.1 4 컴포넌트의 데이터 흐름

┌──────────────────────────────────────────────────────────────┐
│  1. Definition                                               │
│     실험 사양 (owner·name·dates·variants·iteration·targeting) │
│     ↓ stored in experiment system configuration              │
└────────────────┬─────────────────────────────────────────────┘
                 │ pushed to runtime
                 ▼
┌──────────────────────────────────────────────────────────────┐
│  2. Deployment                                               │
│     - Variant Assignment Service: f(user_id, exp_id, layer)  │
│     - Production code: 3 가지 architecture                   │
│     - Atomicity 보장 (분산 서버 일관성)                       │
└────────────────┬─────────────────────────────────────────────┘
                 │ user actions occur
                 ▼
┌──────────────────────────────────────────────────────────────┐
│  3. Instrumentation                                          │
│     - 기본 로깅 (user actions, system performance)            │
│     - 실험 로깅 (variant_id, iteration_id, exp_id)           │
│     - Counterfactual logging (선택, Run/Fly 단계)             │
└────────────────┬─────────────────────────────────────────────┘
                 │ logs flow to data warehouse
                 ▼
                [Analytics — F4-4 에서 다룸]

각 컴포넌트는 이전 컴포넌트의 정확성을 가정 한다. Definition 이 모호하면 Deployment 가 잘못 된 variant 를 노출하고, Deployment 가 결함이면 Instrumentation 데이터가 오염되고, Instrumentation 이 누락되면 Analytics 가 의미 없는 숫자를 만든다. 이 chain-of-trust 가 실험 시스템 설계의 핵심이다.

직관 — 왜 4 개로 쪼개는가, 한 컴포넌트로 만들면 안 되는가

이 4-way 분할은 임의가 아니라 의무 (responsibility) 의 자연스러운 경계 다.

  • Definition 은 인간이 다루는 영역 (UI, 협업) — 변경이 빠르고 실험자 친화 도구가 필요
  • Deployment 는 실시간 시스템 영역 — 분산·atomicity·성능이 핵심
  • Instrumentation 은 데이터 파이프라인 영역 — 일관성·완전성·schema evolution
  • Analytics 는 통계·시각화 영역 — 정확성·해석 가능성

각 영역의 비기능 요구 (latency·consistency·correctness·usability) 가 다르므로 한 시스템으로 묶으면 모든 영역에서 trade-off 가 발생한다. 4-way 분할은 각 영역이 독립적으로 진화 하도록 허용한다 — Analytics 의 새 통계 기법 도입이 Deployment 의 안정성을 깨뜨리지 않는다.

소프트웨어 아키텍처 일반 원칙 (separation of concerns) 의 실험 도메인 적용이라고 볼 수 있다.

3 Component 1 — Experiment Definition / Set-up / Management

3.1 실험 사양의 최소 필드

플랫폼이 실험 사양을 저장하기 위해 필요한 최소 필드 (Kohavi, Tang, Xu, 2020, Ch.4.5).

필드 의미 누락 시 결과
owner 실험 소유자 책임자 모호 → 출시 결정 정체
name 인간 친화 이름 검색·메타분석 불가
description 가설·목적 6 개월 후 왜 이 실험이 있었는지 모름
start / end dates 시작·종료 시점 iteration 비교 불가
variants 처치 정의 (Control + Treatment N 개) variant 식별 불가
iteration 현재 반복 (피드백·ramping 단계) 시점별 결과 분리 불가
targeting 대상 사용자 조건 (country·device·…) 트래픽 제어 불가
randomization unit user·session·device SUTVA 분석 잘못됨

이 사양은 데이터베이스에 저장되어 runtime 에 push 된다. 변경 시 실험 ID·iteration ID 자동 발급 으로 추적 가능성 확보.

3.2 Iteration — 실험의 시간적 진화

저자들은 한 실험이 여러 iteration 을 가질 수 있다고 강조한다. iteration 의 발생 이유.

  1. 버그 수정 — 실험 중 발견된 결함 수정 후 재실행
  2. 점진 노출 (ramping) — 1% → 5% → 20% → 50% (Ch.15)
  3. 링 (rings) — 개발자 → 사내 → 외부 일부 → 전체
직관 — 왜 iteration 을 별도 entity 로 추적하는가

같은 실험의 1% 노출과 50% 노출은 사실상 다른 실험 이다. 표본 크기·power·세그먼트 다양성이 모두 다르기 때문에 결과 해석이 달라진다.

만약 iteration 을 별도 추적하지 않으면 다음 일이 일어난다.

  • 1% 단계에서 측정된 효과 +2% 와 50% 단계의 효과 +0.5% 가 같은 데이터에 섞여 평균 +1% 로 보고
  • 실제로는 1% 단계 사용자가 early adopter 라 효과가 컸고, 50% 는 일반 사용자라 효과가 작은 것
  • 잘못된 평균이 출시 결정에 사용됨

iteration 별로 분리해 보면 Treatment effect heterogeneity over time 을 발견하고, 일반 사용자 에 대한 진정한 효과를 추정할 수 있다. 이는 단순 데이터 정리가 아니라 인과 식별의 도구 다.

3.3 권한·검증 메커니즘

플랫폼이 제공해야 할 핵심 기능.

  • Draft 작성·편집·저장 — 실험을 즉시 시작하지 않고 검토 가능
  • Draft vs Running 비교 — 새 iteration 의 변경 사항 시각화
  • History / Timeline — 종료된 실험도 archive 에서 재조회 가능
  • 자동 ID 할당 — 실험 ID·variant ID·iteration ID 가 instrumentation 코드에 들어감
  • 검증 (validation) — configuration 충돌, 잘못된 targeting (예: 빈 audience), 누락 필드 자동 감지
  • 권한 비대칭 — 실험 시작은 owner 또는 권한자만, 중지는 누구나
권한 비대칭의 직관 — Asymmetry of Harm

왜 시작은 권한 제한, 중지는 자유인가? harm 의 비대칭성 때문이다.

  • 잘못 시작된 실험 — 실제 사용자가 나쁜 처치에 노출되어 활성 피해 발생
  • 잘못 중지된 실험 — 단지 학습 기회 1 회 손실, 사용자 피해 0

잘못된 시작의 비용 (사용자 이탈·매출 손실) 이 잘못된 중지의 비용 (실험 재시작 1 주 지연) 보다 훨씬 크다. 이 비대칭은 자유주의적 권한 모델 을 정당화한다 — 누구나 stop 할 수 있되, start 는 책임자만.

이 패턴은 의료 분야 (임상시험 DSMB 의 stopping rule), 항공 (조종사 누구나 중단 가능), 원자력 (oS̄ 스크램 버튼) 에도 동일하게 적용된다. 안전 critical 시스템의 일관된 설계 원칙이다.

단, 자동 alert 가 owner 에게 가서 무엇이 왜 중지되었는지 즉시 알도록 한다. 그렇지 않으면 악의적 stop 이 가능해진다.

3.4 Fly 단계의 추가 기능

Run·Fly 단계로 진입하면 다음이 추가된다.

  • 자동 ramping — 가드레일 통과 시 1% → 5% → 50% 자동 진행 (Ch.15 SQR)
  • NRT alerting — 분 단위 모니터링, 가드레일 위반 시 자동 차단
  • Bad experiment 자동 감지 — 통계적 이상치 자동 종료

이 기능들은 인지 부담을 시스템으로 흡수 한다. Fly 단계 조직은 매일 수십 건이 ramping 중이라 사람이 일일이 점검할 수 없다.

4 Component 2 — Experiment Deployment

4.1 Variant Assignment Service

실험 사양이 결정된 후, 사용자 요청이 들어왔을 때 어느 variant 를 노출할지 결정하는 서비스다.

핵심 속성:

\[\text{variant} = f(\text{user\_id}, \text{exp\_id}, \text{layer\_id})\]

여기서 \(f\) 는 cryptographic hash 함수 (보통 MD5·SHA-1).

속성 의미 위반 시 결과
결정성 (deterministic) 같은 user·exp 는 항상 같은 variant 사용자 경험 일관성 깨짐
균등성 (uniform) bucket 분포가 평균적으로 같음 SRM 발생
독립성 (independent) layer 간 배정이 무관 직교성 위반

Atomicity 도 같이 보장해야 한다 — 분산 서버 환경에서 한 사용자 요청이 여러 child service 에 fan-out 되었을 때, 모든 child 가 같은 variant 를 봐야 한다.

직관 — Atomicity 가 깨지면 무슨 일이 벌어지는가

검색 엔진을 예로 들자. 사용자 검색 요청 1 건이 다음 분산 처리를 거친다.

검색 요청
   ├→ 인덱스 서버 1 (a~h 단어)
   ├→ 인덱스 서버 2 (i~p 단어)
   ├→ 인덱스 서버 3 (q~z 단어)
   ├→ 광고 서버
   └→ 답변 통합 서버

ranking 알고리즘 A/B 실험 중인데, 인덱스 서버 1·2 는 새 알고리즘 (Treatment) 을 사용하고 서버 3 은 아직 old 알고리즘 (Control) 을 사용한다고 가정. 같은 검색 결과 페이지에 두 알고리즘의 출력이 섞이면:

  1. 사용자 시점에서 일관성이 깨진 결과 — 어떤 단어로 검색하느냐에 따라 결과 품질이 다름
  2. 데이터 시점에서 인과 효과 측정 불가 — 어떤 부분이 Treatment 효과인지 분리 불가
  3. 인스턴스 시점에서 디버깅 악몽 — 같은 사용자가 다른 결과를 받는 경우 reproduce 불가

해결책: parent service (답변 통합) 가 한 번 variant 를 결정하고 child 에 전파. 이는 분산 시스템의 idempotency 와 tracing 패턴과 동일하다.

4.2 3 가지 Production 코드 아키텍처

Variant 가 결정된 후 코드가 어떻게 분기하느냐에 따라 3 가지 패턴.

4.2.1 Architecture 1: Code Fork

variant = getVariant(userId)
if variant == "Treatment":
    button_color = "red"
else:
    button_color = "blue"
  • 장점: variant 결정이 코드 변경 지점에 가까움 → triggering 자연스러움 (Treatment·Control 모두 affected user 만 포함, Ch.20)
  • 단점: 분기 코드 부채. 한 코드베이스에 수십 개의 if-else 가 누적되면 유지 비용 폭증

4.2.2 Architecture 2: Parameterized

variant = getVariant(userId)
button_color = variant.getParam("buttonColor")
# Control: button_color = "blue" (default)
# Treatment: button_color = "red" (variant param)
  • 장점: 코드 분기 제거, 추가는 파라미터만 새로 정의
  • 단점: 모든 변경 가능 항목을 미리 파라미터로 추상화해야 함 (선견지명 필요)

4.2.3 Architecture 3: Early Assignment + Config Push

# variant 결정은 요청 진입점에서 한 번
config = pushedConfig  # 모든 파라미터 + variant 정보
button_color = config.getParam("buttonColor")
  • 장점: 성능 (파라미터 lookup 캐시 가능). 수천 파라미터 규모에서 필수.
  • 단점: variant 결정 시점이 코드 변경 지점에서 멀어짐 → triggering 분석 어려움

4.3 3 아키텍처 비교

측면 Code Fork Parameterized Early + Config
Triggering 용이성 높음 높음 낮음 (counterfactual logging 필요)
코드 부채 누적 적음 적음
성능 보통 보통 가장 좋음 (캐시)
도입 난이도 낮음 중간 높음 (전체 시스템 재설계)
확장성 (파라미터 천 개+) 어려움 보통 좋음

저자들이 보고한 실제 선택.

  • Google — Architecture 1 → 3 으로 전환 (성능 + 코드 부채)
  • Bing — Architecture 3
  • Microsoft Office — Architecture 2 의 변형 (bug ID 를 파라미터로 전달, 3 개월 후 제거 alert)
직관 — 왜 정답이 없고 회사마다 다른가

이 트레이드오프는 현재의 부채 (technical debt)미래의 부채 사이의 선택이다.

  • Architecture 1 (Code Fork) — 빠른 도입, 점진 누적되는 부채
  • Architecture 3 (Early + Config) — 큰 초기 투자, 누적 부채 없음

조직의 단계가 결정 인자다.

  • Crawl·Walk — Architecture 1 이 합리적. 실험 빈도가 낮아 부채가 누적되기 전에 cleanup 가능
  • Run·Fly — Architecture 3 이 필수. 천 개 파라미터·수만 실험에서 코드 분기는 유지 불가능

Microsoft Office 의 변형 (Architecture 2 + 자동 cleanup alert) 은 흥미롭다 — 부채 누적의 자연 적인 해법은 부채를 제거할 의무를 시스템에 내장 하는 것이다. 3 개월 후 자동 알림은 인간의 forgetfulness 를 시스템이 보완하는 패턴이다. 비슷한 패턴이 deprecation warning, expiration date, TTL 등에 나타난다.

4.4 Triggering 의 영향 (간단히)

Architecture 1 에서는 variant 결정이 코드 변경 지점에 있어 affected user 만 데이터에 포함 된다. Architecture 3 에서는 variant 결정이 요청 진입점이라 모든 사용자가 데이터에 포함 — 실제로는 변경 영향이 없는 사용자까지. 이는 statistical power 를 떨어뜨린다.

해결책은 counterfactual logging (Ch.20 에서 상세). Treatment 사용자에게 “Control 이었다면 무엇을 봤을지” 함께 로깅한다. 이 로그를 통해 affected user 만 사후 필터링 가능. 그러나 counterfactual logging 자체가 비용이 크다 — 두 가지 결과를 모두 계산해야 하므로.

5 Component 3 — Experiment Instrumentation

5.1 무엇을 로깅하는가

Instrumentation 은 두 layer 로 분리된다.

  1. 기본 instrumentation — 사용자 행동 (page views·clicks·conversions) + 시스템 성능 (latency·errors)
  2. 실험 instrumentation — 모든 사용자 요청·인터랙션에 대해 다음 추가 정보:
    • variant_id (어떤 처치였는가)
    • iteration_id (몇 번째 반복인가)
    • exp_id (어떤 실험이었는가)
    • timestamp (시점)

기본 instrumentation 은 새 기능 배포 시 반드시 업데이트 되어야 한다. 새 버튼·새 페이지가 기존 instrumentation schema 에 없으면 클릭이 추적되지 않아 효과 측정 불가.

5.2 Iteration 로깅이 왜 critical 한가

실험이 시작되거나 ramping 될 때 모든 서버가 동시에 새 iteration 으로 전환되지 않는다. 일부 서버는 아직 old iteration, 일부는 new. 이 시점에 사용자 요청의 iteration 을 함께 로깅 하지 않으면 다음 문제가 발생한다.

  • iteration 1 (1% ramp) 의 데이터와 iteration 2 (5% ramp) 의 데이터가 섞임
  • 평균 효과만 보면 “1% 효과” 와 “5% 효과” 의 가중 평균
  • iteration 별 효과 차이가 있을 때 평균이 잘못된 결정을 유도
직관 — 왜 iteration 정보가 단순 timestamp 로 대체될 수 없는가

“timestamp 로 iteration 을 추론하면 되지 않나?” 는 자연스러운 질문이다. 답: 분산 시스템의 시간 동기화는 milliseconds 단위로 어긋난다. ramping 의 cutover 가 정확히 12:00:00 이라도 일부 서버는 12:00:00.150 에 전환되고 일부는 11:59:59.870 에 이미 새 코드 로드.

게다가 ramping 은 한 번에 끝나지 않는다 — 새 코드가 배포되기까지 수 분 ~ 수 시간이 걸린다. 이 transition window 동안 같은 timestamp 에 두 iteration 데이터가 섞인다.

Iteration ID 를 명시적으로 로깅하면 transition window 의 데이터를 정확히 분리할 수 있다. 이는 단순 편의가 아니라 데이터 정확성의 근본이다. 분산 시스템의 시간 부정확성을 응용 layer 의 ID 로 보완하는 일반 패턴이다.

5.3 Counterfactual Logging — Run/Fly 단계 필수

Treatment 사용자가 “만약 Control 이었다면 무엇을 봤을까” 를 함께 로깅하는 패턴이다. Architecture 3 의 triggering 분석 (Ch.20) 에 핵심.

Treatment 사용자 요청
  ↓
Treatment 응답 생성 (red button)
  ↓ (counterfactual logging on)
Control 응답도 동시 계산 (blue button) — 사용자에게는 안 보임
  ↓
두 응답의 차이를 로깅

비용: Treatment 응답 생성에 추가로 Control 계산 = 두 배 연산.

가정 — 무엇이 깨지면 counterfactual 이 의미를 잃는가

Counterfactual logging 의 가정은 Treatment 와 Control 의 응답이 서로 부작용 (side effect) 없이 계산 가능 하다는 것이다. 깨지는 사례:

  • DB write 가 포함된 Treatment — Control 도 DB write 를 하면 부작용이 누적, 안 하면 Control 추정에 missing data
  • 외부 API 호출이 포함된 Treatment — 두 번 호출하면 비용이 두 배, 한 번만 하면 어느 variant 의 효과인지 불명
  • 사용자에게 직접 노출되는 부작용 (이메일·푸시) — Control 도 보내면 사용자 피해, 안 보내면 효과 측정 불가

해결: read-only 변경에 한정해 counterfactual 적용. write·side-effect 변경은 별도 분석 (예: Architecture 1 + 분기 변경) 으로 처리.

이 한계 때문에 counterfactual logging 은 ranking·recommendation 같은 read-only domain 에서 가장 효과적이다.

6 왜 필요한가

6.1 4 컴포넌트 부재의 결과

플랫폼 인프라가 분산되거나 ad-hoc 으로 구현되면 다음 함정에 빠진다.

  • Definition 부재 — 실험 description 이 없어 6 개월 후 왜 했는지 모름. Institutional memory (Ch.8) 부재. 같은 가설 반복 검증.
  • Deployment 결함 — atomicity 위반으로 분산 서버 일관성 깨짐. 실험 결과가 측정 불가능한 noise 로 오염.
  • Instrumentation 누락 — variant·iteration 로깅 누락으로 ramping 데이터 섞임. 잘못된 평균이 결정 근거가 됨.
  • Trust chain 단절 — 한 컴포넌트만 잘 작동해도 전체 신뢰성은 가장 약한 컴포넌트 수준.

6.2 표준 4 컴포넌트의 가치

표준화된 4 컴포넌트 인프라가 갖춰지면.

  • 실험자는 셀프서비스로 실험 시작·중단 가능 (데이터 사이언스 팀 병목 제거)
  • 새 실험 1 건의 한계 비용이 거의 0 — Run·Fly 단계 진입 조건
  • 메타분석 가능 (Ch.8) — 같은 schema 데이터가 누적되어 횡단 분석 가능

이 가치는 단계 전환의 핵심 enabler 다. Walk → Run 진입은 인프라 표준화 없이 불가능하다.

7 응용

7.1 Bing 의 Architecture 3 도입 사례

Bing 은 초기에 Architecture 1 (Code Fork) 로 시작했다가, 검색 ranking 파라미터가 수백 개로 늘어난 시점에 Architecture 3 (Early + Config) 으로 전환했다. 도입 비용은 1 년 엔지니어링 프로젝트 (사전지식 보강), 효과는.

  • 동시 실험 수 5 배 증가 (코드 분기 제약 제거)
  • 실험 시작 시간 분 단위로 단축 (코드 deploy 불필요, config push 만)
  • Triggering 분석은 counterfactual logging 으로 보완

7.2 Microsoft Office 의 부채 자동 알림

Office 는 Architecture 2 의 변형으로, 각 실험 파라미터에 bug ID 부착 후 3 개월 뒤 자동 알림으로 cleanup 강제. 결과: 코드 부채 누적이 다른 회사 대비 현저히 낮음.

이 패턴은 부채의 자연 감쇠 (decay) 를 시스템으로 강제한다. 사람의 의지에 의존하지 않고도 정리 작업이 자동 schedule 된다.

8 예시 — 실험 사양 + Variant Assignment + Instrumentation 최소 구현

다음 코드는 4 컴포넌트의 첫 3 개를 단일 파일에 압축한 minimum viable example 이다. 실제 플랫폼은 각 컴포넌트가 분산 서비스로 구현되지만, 핵심 데이터 흐름은 동일하다.

import hashlib
import json
import time
from dataclasses import dataclass, field, asdict
from typing import Dict, List

# ============================================================
# Component 1: Definition / Set-up / Management
# ============================================================
@dataclass
class ExperimentSpec:
    exp_id: str
    name: str
    description: str
    owner: str
    start: float                # epoch seconds
    end: float
    variants: List[str]         # ["control", "treatment"]
    iteration: int = 1
    targeting: Dict = field(default_factory=dict)
    randomization_unit: str = "user_id"

spec = ExperimentSpec(
    exp_id="exp_button_color_001",
    name="Button Color Test",
    description="Red CTA vs Blue CTA on checkout page",
    owner="alice",
    start=time.time(),
    end=time.time() + 14 * 86400,
    variants=["control", "treatment"],
    iteration=1,
    targeting={"country": "US", "device": "web"},
)

# ============================================================
# Component 2: Deployment — Variant Assignment Service
# ============================================================
def assign_variant(user_id: str, spec: ExperimentSpec, layer_id: str = "default") -> str:
    """Architecture 2 (Parameterized) 의 variant 결정"""
    key = f"{spec.exp_id}:{spec.iteration}:{layer_id}:{user_id}".encode()
    h = int.from_bytes(hashlib.md5(key).digest()[:8], "big")
    bucket = h % 1000
    # 간단한 50/50 split
    return spec.variants[1] if bucket < 500 else spec.variants[0]

# ============================================================
# Component 3: Instrumentation
# ============================================================
event_log = []

def log_event(user_id: str, action: str, spec: ExperimentSpec, variant: str, **extra):
    """variant·iteration 정보를 모든 이벤트에 attach"""
    event_log.append({
        "timestamp": time.time(),
        "user_id": user_id,
        "action": action,
        "exp_id": spec.exp_id,
        "iteration_id": spec.iteration,
        "variant_id": variant,
        **extra,
    })

# ============================================================
# 시뮬레이션 — 사용자 1000 명 요청 처리
# ============================================================
import numpy as np
rng = np.random.default_rng(42)

for i in range(1000):
    uid = f"user_{rng.integers(0, 10**8)}"
    variant = assign_variant(uid, spec)
    # 변종별 page view → click 시뮬
    log_event(uid, "page_view", spec, variant)
    click_prob = 0.05 if variant == "control" else 0.07
    if rng.random() < click_prob:
        log_event(uid, "click_cta", spec, variant)

# 결과 요약 (Component 4 — Analytics 의 입력 형태)
import pandas as pd
df = pd.DataFrame(event_log)
summary = df.pivot_table(
    index="variant_id",
    columns="action",
    values="user_id",
    aggfunc="count",
    fill_value=0,
)
summary["ctr"] = summary["click_cta"] / summary["page_view"]
print(summary)

예상 출력 (시드 42 기준).

action       click_cta  page_view       ctr
variant_id
control             24        494  0.048583
treatment           34        506  0.067193
직관 — 이 코드가 보여주는 4 가지 데이터 흐름 핵심
  1. 사양 (Definition) 이 데이터에 흐름 — exp_id·iteration_id 가 모든 event 에 첨부되어 분석 시 어느 실험·어느 단계의 데이터인지 자동 식별
  2. 결정성 보장 (Deployment)assign_variant() 가 같은 user·iteration 에서 같은 결과 → 사용자 경험 일관성
  3. Iteration 분리 (Instrumentation)iteration_id 를 명시 → ramping 시 데이터 섞임 방지
  4. Trust chain — 어느 한 컴포넌트만 결함이어도 최종 분석은 의미 없음

위 코드는 30 줄 미만이지만 실험 인프라의 본질 을 모두 담고 있다. 실제 플랫폼은 이 30 줄을 분산 시스템·고가용성·실시간 모니터링으로 확장한 것이다.

9 관련 주제

선행 — Ch.4 시리즈

후속 — Ch.4 시리즈

관련 챕터

다른 카테고리 연결

Subscribe

Enjoy this blog? Get notified of new posts by email: