프로덕션 운영 사례 — 검증된 것과 귀속(歸屬) 오류
ClickHouse를 PB~경 스케일 관측성 백엔드로 운영하는 사례는 넘치지만 ‘K8s + operator + 로컬 NVMe’ 조합의 순수 1차 실증은 얇습니다.
- K8s + operator는 eBay·Anthropic·Trip.com·LogHouse가 검증한 안전한 패턴입니다.
- 로컬 NVMe primary는 최고 성능을 사는 대신 노드 소실 시 재복제·drain 운영을 대가로 치릅니다 — 대규모 K8s 사례는 대부분 오브젝트 스토리지 백킹으로 수렴합니다.
- 소규모 팀에는 로컬 NVMe(hot 캐시) + S3(primary) 하이브리드가 재수화·drain 리스크를 줄여 더 안전합니다.
- 대규모 사례의 수치 상당수가 ClickHouse Inc. 벤더 출처이므로 편향을 감안해 읽습니다.
ClickHouse를 관측성 백엔드로 PB~경(quadrillion) 스케일에서 운영하는 사례는 차고 넘칩니다 — 이 방향성 자체는 의심할 필요가 없습니다. 그런데 사용자가 검토 중인 특정 조합 ‘K8s + operator + 로컬 NVMe’의 순수 실증은 생각보다 얇습니다. 대규모 named 사례의 스토리지는 대부분 (a) 베어메탈 로컬 디스크(Cloudflare·Didi)이거나 (b) 오브젝트 스토리지 백킹(Anthropic·Character.AI·ClickHouse LogHouse)이고, “K8s 위 로컬 NVMe만으로 대규모"를 공개 1차 출처로 확인해주는 곳은 드뭅니다. 결론부터 적자면, K8s+operator는 검증된 프로덕션 패턴이지만 로컬 NVMe는 성능 상한을 사는 대신 node lifecycle 운영을 대가로 치르며 소규모 팀에는 로컬 NVMe(hot 캐시) + S3(primary) 하이브리드가 더 안전합니다.
출처 열에 그 구분을 표기했습니다.대규모 운영 사례 매트릭스
출처 등급 범례: 자사=해당 회사 자체 엔지니어링 블로그(상대적 독립) · CH=ClickHouse 자사 블로그/케이스스터디(자기 홍보 맥락, Ⓥ) · 규모 수치의 등급은 셀 내 표기.
| 회사 | 용도 | 배포 형태 | 스토리지 | 출처 |
|---|---|---|---|---|
| Cloudflare | HTTP/DNS/방화벽 분석·빌링 | 베어메탈(자체 DC 300+) | 로컬 디스크 중심 | 자사+CH |
| Netflix | 로그(관측성) | 자체 파이프라인 | 계층형 | CH |
| MS Clarity | 웹 세션/행동 분석 | “layer” 서브클러스터 | DC 간 복제 | 자사 |
| Character.AI | 관측성(로그) | ClickHouse Cloud(multi-cloud K8s) | S3(Cloud) | CH |
| Tesla(Comet) | 메트릭(관측성) | K8s 추정, OTel→Kafka→ETL | CH 네이티브 | CH |
| Didi | 로그 | 물리 노드(베어메탈) | 계층형(hot/cold) | CH |
| Trip.com | 로그 | K8s StatefulSet | 로컬+ (SMT/S3 테스트) | CH |
| Uber | 로그 | 자체 인프라 | 계층형 | 자사 |
| eBay | OLAP/모니터링 | K8s + operator | 미확인(출처에 언급 없음) | 자사 |
| Anthropic | 관측성 | air-gapped Cloud arch on K8s + operator | 오브젝트 스토리지 | CH |
| Sentry(Snuba) | 에러/이벤트 검색 | 자체 인프라 | ClickHouse | 자사 |
| PostHog | 제품 분석 | 자체/Cloud | Sharded | 자사 |
| GitLab | 분석 + 관측성 | Cloud/자체 | — | 자사+CH |
| LogHouse(CH 도그푸딩) | 내부 관측성 | K8s + operator | 오브젝트 스토리지/S3 | CH |
규모(핵심 수치)는 회사별로 따로 뜯습니다:
| 회사 | 규모(핵심 수치) |
|---|---|
| Cloudflare | 20+클러스터, >100 노드, 1000+ replica, ~90M rows/s, 100+ PB, 96조 events를 <2s(1일 창 1.61경도 <2s) ✓ |
| Netflix | 5 PB/day, 평균 10.6M events/s(peak 12.5M), 500~1000 QPS Ⓥ |
| MS Clarity | 수백 대 머신, 수백 PB, 수백조 events, 수십억 pv/day ✓ |
| Character.AI | 450 PB raw/월 → 샘플 후 50B/월, 10x 데이터·비용 -50% Ⓥ |
| Tesla(Comet) | 1B rows/s를 11일 지속 = 1 quadrillion rows 무장애 Ⓥ |
| Didi | 400+ 물리 노드, peak write 40 GB/s+, ~15M queries/day, PB/day, machine cost -30% vs ES Ⓥ⁽자가보고⁾ |
| Trip.com | 50 PB(4PB ES에서 시작), 저장 -50%+, query 4~30x Ⓥ |
| Uber | millions logs/s, 수천 서비스, 수 PB, ingest <1min ✓ |
| eBay | Federated 다중 리전, 인프라 풋프린트 -90%+ ✓ |
| Anthropic | 3인 팀 운영(데이터량·비용 비공개) ✓ |
| Sentry(Snuba) | Kafka 인서트, Tagstore TB→GB, Alert이 전체 QPS의 ~40% ✓ |
| PostHog | Sharded CH, Kafka engine table + MV 인제스천 ✓ |
| GitLab | 100M rows 쿼리 30~40s→<1s, 일 57M+ traces, 3000+ 서비스 ✓ |
| LogHouse(CH 도그푸딩) | 100+ PB 비압축, ~500조 rows, SysEx 37M + OTel 2M logs/s Ⓥ |
Didi 수치는 2024-04 스냅샷이며 물리 노드 400+는 Log 300+/Trace 40+로 나뉩니다. machine cost -30%는 TCO보다 좁은 지표로 엔지니어링·마이그레이션 비용은 제외합니다. Uber 수치는 2021-02 스냅샷으로 단일 노드 300K logs/s 실측치이며 후속으로 비정형 Spark 로그는 CLP로 보완했습니다.
그 밖의 확인 사례 — Zomato · Shopee · OpenAI · Ahrefs
Zomato(EC2 10×m6g.16xlarge, gp3 hot→cold TTL, ES 대비 연 $1M+ 절감 Ⓥ), Shopee(분산 트레이싱 ~3M rows/s, 30B+ trace rows ✓⁽요약⁾). OpenAI는 일 PB급 로그를 자체 관리 ClickHouse 클러스터(90 샤드×2 리플리카, Fluent Bit→로드밸런서 인제스트, 최근 데이터는 디스크·구 데이터는 blob 스토리지로 티어링)로 인제스트하며 월 20%+ 성장합니다 Ⓥ⁽자가보고⁾(출처: clickhouse.com 블로그 + OpenAI 엔지니어 컨퍼런스 발표). 단 이 글은 Datadog 등 상용 벤더 이탈이나 K8s/EKS·인스턴스·로컬 NVMe를 전혀 언급하지 않습니다 — OpenAI는 순수 하이퍼스케일 증거일 뿐이므로 아래 §‘K8s + 로컬 NVMe’ 실증 목록에는 넣지 않습니다(C8). Ahrefs(초대형 베어메탈)는 이번 조사에서도 노드 수·용량을 명시한 1차 출처를 확보하지 못해 **?**으로 둡니다.
순수 자체운영의 최대 규모는 베어메탈(Cloudflare 100+PB, Didi 400+노드)이고 두 곳 다 K8s가 아닙니다. K8s로 대규모를 돌리는 곳(eBay·Trip.com·Anthropic·LogHouse)은 operator를 쓰며 스토리지는 오브젝트 스토리지 백킹으로 수렴합니다. “K8s + 로컬 NVMe만으로 대규모"는 매트릭스에서 직접 확인되는 조합이 아닙니다. (2026-07-14 재확인: 별도 딥리서치 라운드에서도 NVMe-on-K8s를 명시한 프로덕션 사례는 확보되지 않아 이 결론이 그대로 유지됐습니다 — OpenAI를 포함해도 마찬가지입니다.)
매트릭스의 “가능하다"를 액면 그대로 읽으면 안 됩니다 — 각 규모를 내기까지 상당한 엔지니어링이 붙었습니다. 대규모 레퍼런스는 “CH면 공짜로 된다"가 아니라 “이만큼 튜닝하면 이 규모가 난다"로 읽어야 합니다.
근거 — Netflix·Cloudflare가 규모를 낸 튜닝 상세
Netflix는 5PB/day를 내려고 세 곳을 갈아엎었습니다 Ⓥ: 유사 로그 수백만 개를 하나로 collapse하는 fingerprinting, JDBC 배치 인서트를 커스텀 native 프로토콜 인코딩으로 교체, 태그 쿼리에 LowCardinality 적용(창시자 Alexey Milovidov 제안). Cloudflare는 오케스트레이션을 얇게 가져가 “북미 DC 연결을 끊어 용량 1/3을 제거해도 유럽 클러스터가 부하를 자동 인수"하는 회복력을 보였고 ✓, 그럼에도 2026년 빌링 파이프라인이 쿼리 플래닝 단계의 락 경합으로 느려진 장애를 겪었습니다(안티패턴 §9).
‘K8s + operator + 로컬 NVMe’ — 실증은 어디까지인가
사용자 관심 조합을 세 축으로 쪼개 각각의 근거를 따집니다. 여기서 흔한 귀속 오류를 정정합니다 — 여러 2차 자료가 “eBay는 hot 데이터에 로컬 SSD를 쓴다"고 서술하지만 eBay 공식 블로그에는 스토리지 하드웨어·티어링 언급이 전혀 없습니다(원문·미러·검색 3중 확인). 일반적인 K8s+ClickHouse 권장 패턴을 eBay 사례에 잘못 붙인 것이므로 eBay를 로컬 NVMe의 실증 레퍼런스로 내세울 근거는 없습니다 ?.
| 사례 | K8s | operator | 로컬 NVMe(hot) | 근거 등급 |
|---|---|---|---|---|
| eBay | O(federated, FCHI/FCHC) | O(자체 확장+OSS operator) | 미확인(출처에 없음) | K8s+operator=✓, 스토리지=? |
| Anthropic | O | O(ClickHouse Operator) | 오브젝트 스토리지 백킹(로컬은 캐시 추정) | ✓(로컬 캐시는 ≈) |
| Trip.com | O(StatefulSet) | 자체 관리 | 로컬 → SharedMergeTree/S3 테스트로 이행 | ✓ |
| ClickHouse LogHouse | O | O(ClickHouse Operator) | 오브젝트 스토리지 | Ⓥ |
| mrkrbrts(참조 아키텍처) | O(EKS) | O(Altinity) | r7gd NVMe = S3 write-through 캐시 | ✓(개인 참조 아키텍처) |
K8s + operator 자체는 eBay·Anthropic·Trip.com·LogHouse·ClickHouse 자신이 검증한 패턴입니다. 그러나 “로컬 NVMe를 hot으로” 쓰는 실증은 대부분 오브젝트 스토리지 백킹 위의 캐시(Anthropic·Character.AI·mrkrbrts) 형태입니다. 로컬 NVMe를 primary durable로 두는 순수형은 여기 없습니다. 순수 로컬 NVMe primary는 성능이 최선이나 그 대가로 node lifecycle 운영을 집니다. 재복제·drain 절차와 reclaimPolicy 함정, Altinity issue #1859의 미결 스레드는 로컬 NVMe 데이터스토어 벤치마킹 §대가가 9개 시스템 횡단 증거와 함께 소유합니다. 이 페이지는 실증 범위와 출처 편향만 다룹니다.
관측성 아키텍처 패턴
인제스천 파이프라인 — Kafka / Vector / OTel
대규모 사례가 수렴하는 인제스천 패턴은 다섯 갈래입니다.
| 패턴 | 대표 사례 | 특징 | 트레이드오프 |
|---|---|---|---|
| Kafka버퍼+커스텀워커 | Zomato, Trip.com, PostHog | 배치·백프레셔 제어, native포맷 인서트 | 워커 유지보수 부담 |
| Kafka table engine + MV | PostHog | CH 내장 컨슈머, 인프라 단순 | 튜닝 여지 제한, 장애 격리 약함 |
| OTel Collector | Tesla, Character.AI(DaemonSet), Netflix(일부) | 표준·벤더중립 | 대규모에서 CPU 병목(아래) |
| Vector | Anthropic | 경량·고성능 파이프라인 | — |
| CH → CH 직접(SysEx) | ClickHouse LogHouse | native 포맷 byte-copy, 재직렬화 0 | ClickHouse 소스 한정 |
Kafka 버퍼 + 커스텀 워커 구현 언어는 Zomato가 Go, Trip.com이 GoHangout입니다. OTel Collector는 표준·벤더중립에 에코시스템 확장성까지 갖췄지만 대규모에서는 CPU 병목이 따라옵니다(아래 §OTel Collector의 CPU 병목).
공통 원칙은 어디서나 같습니다 ✓ — (1) 대형 배치 인서트(수천~수만 rows) 또는 async insert, (2) native 포맷(HTTP 대비 ~1.8x, Zomato Ⓥ), (3) 초당 인서트 빈도 제한(Sentry: ~1/s), (4) Kafka로 스파이크 흡수. 원칙을 어기면 곧바로 아래 안티패턴의 “too many parts"로 직행합니다.
wide events가 대세
관측성 스키마의 업계 방향은 wide events로 굳어지고 있습니다 ✓(ClickHouse LogHouse의 100PB 설계, Charity Majors/Honeycomb 담론과 맞닿음). row마다 완전한 컨텍스트를 사전 집계 없이 저장하고(histogram 대신 개별 insertDuration 값), pod명·버전·네트워크 정보 같은 고카디널리티 차원을 그대로 보존해 쿼리 시점에 집계합니다. 전통 메트릭 스토어의 per-series cardinality explosion을 피하려는 게 핵심 동기입니다. ClickStack/HyperDX가 이 패턴을 UI로 지원합니다(HyperDX 심층). 대비되는 시그널별 테이블(logs/metrics/traces 분리, OTel 스키마 기본)도 여전히 유효하며 Tesla처럼 메트릭만 PromQL 전용 파이프라인으로 특화하는 하이브리드도 실전에서 쓸 만합니다.
실전 스키마 규칙(여러 사례 공통 ✓): 필터 빈도 높은 23개 컬럼을 카디널리티 오름차순 ORDER BY(Trip.com 50x (log_level, timestamp, host_ip, host_name)), LowCardinality(Netflix 태그 최적화의 핵심), 동적 태그는 Map 또는 JSON 타입(25.3 GA), 압축은 ZSTD(Trip.com 40%+·Character.AI 15Ⓥ), skip index(tokenbf_v1/Bloom)는 남용 금지.
OTel Collector의 CPU 병목 (대규모 교훈)
아키텍처를 두고 얻은 교훈 중 가장 큰 건 OTel Collector의 CPU 비용입니다. ClickHouse가 자체 관측성(LogHouse)을 키우면서 OTel Collector가 초대형 스케일에서 CPU 병목이 됨을 공개했습니다 — OTel은 반복 변환(JSON 직렬화 → 파싱/마샬링 → OTel 포맷 변환 → 재인제스트)이 비쌉니다. 구체 수치 Ⓥ(ClickHouse 자체 도그푸딩):
- 20M rows/s를 OTel로 안정 처리하려면 ~8,000 CPU 코어가 필요하다고 추산.
- 그래서 CH→CH native byte-copy인 커스텀 SysEx로 전환: 800 OTel 코어 → 70 SysEx 코어로, 20배 볼륨을 이전 CPU의 <10%로 처리. OTel이 부하 시 로그를 drop하던 문제도 해소.
- 단 OTel을 완전히 폐기하지는 않았습니다 — crash-loop 등 system table 접근 불가 시나리오·stderr 캡처에는 여전히 유효 → 하이브리드 유지.
Datadog 대비 비용 주장 — 출처 편향 경고
Ⓥ.| 항목 | 수치 | 비고 |
|---|---|---|
| Datadog vs 자체관리 ClickStack 비용비 | 1 | ClickHouse 자료 Ⓥ |
| Character.AI (관측성 마이그레이션) | 10x 데이터, 비용 -50% | ClickHouse Cloud+ClickStack Ⓥ |
| Zomato (ES→CH) | 연 $1M+ 절감 | ES 대비 Ⓥ |
| Didi (ES→CH) | 머신 비용 -30% | Ⓥ |
| Trip.com (ES→CH) | 저장 -50%+, 쿼리 4~30x | Ⓥ |
Datadog 고비용의 원인(고카디널리티 과금 전가, custom metrics·인제스트+쿼리 이중 과금, 오토스케일에 붙는 per-host 페널티) 자체는 실재합니다 ✓. 그러나 “10~50배"는 자체관리 인건비/운영비를 제외한 인프라 비용 기준일 가능성이 높습니다. TCO를 재평가할 때는 운영 인력·on-call·업그레이드 비용을 반드시 가산해야 합니다. 라이선스 절감분을 운영/개발 인건비 증가가 상쇄하는 영역(Security·Synthetics 등 제품형 기능)도 있습니다. 인프라 vs people TCO의 실제 크로스오버는 Managed vs Self-hosted에서 숫자로 다룹니다. 이관은 rip-and-replace 대신 dual-write → 고카디널리티 쿼리 속도 비교 → 단계적 전환 순서로 밟아 리스크를 줄이길 권합니다 ✓.
공통 교훈 & 안티패턴
반복 등장하는 성공 패턴
- 배치·async 인서트가 절대 원칙 — 모든 대규모 사례가 Kafka 버퍼 + 대형 native 배치.
- 수직 확장 우선, 샤딩은 나중 — CH는 대형 단일 노드(수백 코어/TB RAM)에서 강합니다. 조기 수평 확장은 비용·복잡도만 늡니다(대개 replica 2개면 충분).
- hot(로컬 NVMe) + cold(S3) tiering — 성능·비용 균형의 표준. SharedMergeTree(Cloud 전용)로 storage-compute 분리가 신흥 표준이나 self-host에선 불가.
- LowCardinality + 필터순 ORDER BY + ZSTD — 압축·쿼리 성능의 3종 세트.
- 쿼리 게이트웨이/거버넌스 — Trip.com(SQL 파싱·QPS 제한·대형 스캔 차단), Uber(QueryBridge). 대규모에선 쿼리 남용 통제가 필수.
- 복제로 내구성, 오케스트레이션은 최소 — Cloudflare는 “용량 1/3을 빼도 그리 많은 게 잘못되지 않는다"고 표현.
- 소규모 팀도 운영 가능 — Anthropic 3명, Character.AI 첫 SRE 1명. 단 그게 되려면 operator + 오브젝트 스토리지 백킹이 전제였습니다.
안티패턴 (피해야 할 것)
✓ (ClickHouse “13 mistakes”, BigDataBoutique):
- Too Many Parts(가장 흔한 프로덕션 이슈) — 작은 인서트/고카디널리티 파티션 키가 원인. 파티션당 300 parts 초과면 조치. → 배치/async insert, 파티션 키 카디널리티 <1,000.
- 고카디널리티 파티션 키 — 일 단위가 보통 적정, 그 이상 세분화 금지.
- 소량(row 단위) 인서트 — 각 인서트가 파트 + Keeper 레코드 생성(Sentry 교훈: ~1/s 권장).
- Mutation 남용 — classic mutation은 파트 전체 재작성 → lightweight delete/patch part 사용.
- Keeper 과소 리소스 / 단일 앙상블 의존 — 조정 손실 시 테이블이 read-only로 전락. 전용 Keeper 다중 AZ로(Clarity의 단일 3노드 ZK 전면 의존은 리스크 포인트).
- materialized view 남발(>50개)·skip index 남용 — 인서트 속도만 갉아먹고 성능 개선은 미미.
- experimental/beta 기능을 코어에 사용 — GA 전 핵심 의존 금지.
- (K8s 특화) 로컬 NVMe + 부주의한 node drain/upgrade — drain이 데이터 소실→재복제를 유발.
reclaimPolicy: Retain+ PVC affinity + rolling 절차 설계 필수. - (대규모) 쿼리 플래닝/컴파일 병목 — 데이터 경로 말고 플래닝 락 경합에서도 병목이 납니다(Cloudflare 2026 빌링 파이프라인 사례
✓).
우리 케이스에서는
전제부터 다릅니다. 로깅 챕터는 ClickHouse를 로그 저장소로만 저울질했고 그 관점의 결론은 로그는 VictoriaLogs로 가고 CH 통합(D4)은 “명분 + 오너가 섰을 때 earn it last"였습니다(로깅 권장안). 이 페이지의 사례들은 그 판단을 뒤집지 않습니다 — 오히려 대규모 named 사례 대부분이 전담 팀 또는 벤더 협업을 전제로 하니 “오너 없는 소규모 팀은 CH 자체운영을 1차로 밀지 말라"는 로깅 챕터의 경고를 뒷받침합니다.
이 챕터의 사례 근거는 로깅 챕터가 유보한 게이트(RUM 대체 + 범용 분석 + 인력 보유)를 통과했다고 가정한 뒤에만 발동합니다. 그 전제 위에서 프로덕션 사례가 주는 실무 함의는 다음과 같습니다.
- “K8s + operator"는 안심하고 채택할 수 있습니다 — eBay·Anthropic·Trip.com·ClickHouse 자신이 검증한 패턴입니다. operator는 Altinity로 통일합니다(Altinity operator).
- “로컬 NVMe만으로 대규모"의 순수 실증은 없습니다. eBay는 스토리지 형태를 공개하지 않았고(귀속 오류 주의), 대규모 K8s 사례는 오브젝트 스토리지 백킹으로 수렴합니다. 스토리지 성능을 하드 요구로 두더라도 로컬 NVMe hot + S3 cold(또는 write-through 캐시) 하이브리드가 소규모 인력의 노드 소실·재수화 대응에 유리합니다(스토리지 설계).
- 로깅 챕터의 경계는 그대로 유지합니다 — 로그 hot 경로는 여전히 VictoriaLogs, 메트릭은 VictoriaMetrics입니다. CH self-host는 통합 저장소를 노리는 결정이 아닙니다. RUM·트레이스 등 신호가 실제로 한 팀에 모일 때 추가하는 것이고, 이때도 로그 전면 이전은 별도 명분이 필요합니다.
- 비용 주장은 액면가로 믿지 않습니다. “10~50배"는 벤더 인프라 기준 수치이므로 운영 TCO를 가산해 재평가합니다(Managed vs Self-hosted).
두 챕터는 모순 없이 양립합니다 — 로깅 챕터는 “채택 여부(로그 관점)“에서 보류, 이 챕터는 “채택했다면 어떻게(RUM+분석 관점)“에서 사례를 큐레이션합니다. 게이트를 못 넘으면 로깅 챕터 판단이 우선입니다. 근거 URL은 출처. 시점 기준 2026-07.