| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | 31 |
- node
- Python
- 도커
- kubeflow
- bootstrap
- codepipeline
- IntelliJ
- PostgreSQL
- codedeploy
- Jenkins
- COALESCE
- chartjs
- chart.js
- SQL
- Spring Error
- docker
- Spring
- aws
- Airflow
- redis
- aws cicd
- codebuild
- codedeploy error
- Flux
- java bigdecimal
- Kafka
- AWS CI/CD 구축하기
- VPN
- openlens
- JavaScript
- Today
- Total
Small Asteroid Blog
kafka 창시자 Jay Kreps 의 로그는 무엇인가 본문
🎯 이 글의 진짜 핵심 메시지
표면적으로는 "로그가 뭔지" 설명하는 글처럼 보이지만, 실제로는 훨씬 더 큰 주장을 하고 있어요.
1️⃣ "로그는 추상화다" — 구현체가 아니라 개념
대부분의 엔지니어는 로그를 application log (log4j, syslog 같은 텍스트 파일)로 이해해요.
Jay Kreps가 말하는 건 완전히 다른 개념이에요.
"Append-only, totally-ordered sequence of records ordered by time"
이게 왜 중요하냐면:
- DB의 WAL(Write-Ahead Log)도 이 추상화
- Kafka topic도 이 추상화
- Git commit history도 이 추상화
- Zookeeper의 ZAB 알고리즘도 이 추상화
- RAFT, Paxos도 결국 "누가 다음 로그 엔트리를 결정하는가" 문제
즉, 분산 시스템에서 일어나는 대부분의 복잡한 문제들이 사실 로그 하나로 환원된다는 주장이에요.
2️⃣ State Machine Replication — 분산 시스템의 본질
이 부분이 글에서 가장 철학적으로 깊은 파트예요.
"두 개의 동일한 결정론적 프로세스가
같은 상태에서 시작해서
같은 순서로 같은 입력을 받으면
반드시 같은 결과를 낸다"
얼핏 보면 당연한 말 같지만, 이게 함의하는 바가 엄청나요.
분산 시스템에서 "일관성"이라는 문제 전체가 결국:
"어떻게 여러 노드가 동일한 순서로 동일한 입력을 받게 만드는가?"
= 어떻게 분산된 로그를 구현하는가?
로 환원된다는 거예요.
- Paxos가 해결하려는 것 → 로그
- RAFT가 해결하려는 것 → 로그
- ZAB(Zookeeper)이 해결하려는 것 → 로그
- MySQL replication → 로그(binlog)
- Kafka → 로그
"모든 분산 합의 알고리즘의 실용적 목적은 결국 분산 로그를 만드는 것" 이라는 통찰이에요.
3️⃣ Table과 Log의 이중성 — 가장 실용적인 핵심
Log → replay → Table (변경 이력 → 현재 상태)
Table → changelog → Log (현재 상태의 변경 → 이벤트)
이게 왜 심오하냐면, 세상의 모든 데이터 시스템을 두 가지로만 분류할 수 있어요:
| 종류 | 예시 | 특성 |
| Table (상태) | RDB, Redis, Elasticsearch | 현재 값을 저장 |
| Log (이벤트) | Kafka, WAL, Git | 변경 이력을 저장 |
그리고 둘은 서로 변환 가능해요.
- Kafka의 Log Compaction = Log → Table 방향의 최적화
- DB의 CDC(Change Data Capture) = Table → Log 방향
- Event Sourcing 패턴 = 애플리케이션 레벨에서의 Log 우선 설계
- Materialized View = Log에서 파생된 Table
현재 Sohyun이 작업 중인 추천 이벤트 로그 스키마 설계가 정확히 이 맥락이에요. rec_request_id로 요청과 클릭 이벤트를 연결하는 것 = Log에서 ML 학습용 Table을 materialize하는 파이프라인.
4️⃣ 데이터 통합 문제 — 왜 Kafka가 탄생했는가
LinkedIn에서 실제로 겪은 문제
시스템이 N개면 파이프라인이 N² 개 필요 → 유지보수 불가능 → 중앙 로그 하나로 모든 시스템을 연결하자 → Kafka 탄생
근데 이게 단순히 "메시지 큐를 만들자"가 아니에요.
기존 메시지 큐(RabbitMQ 등)와 Kafka의 근본적 차이:
| 기존 메시지 큐 | Kafka (로그) | |
| 메시지 소비 후 | 삭제 | 보존 |
| 소비자 위치 | 서버가 관리 | 소비자가 관리 (offset) |
| 재처리 | 불가 | 가능 (replay) |
| 순서 보장 | 약함 | 파티션 내 강력 보장 |
"메시지 큐가 아니라 분산 로그" — 이 철학의 차이가 Kafka를 다르게 만들었어요.
5️⃣ 가장 깊은 통찰 — "Unbundling the Database"
글의 후반부에서 Jay Kreps는 이런 주장을 해요:
조직 전체의 모든 시스템과 데이터 흐름을 하나의 거대한 분산 데이터베이스로 볼 수 있다.
- Redis, Elasticsearch, Hive = 서로 다른 인덱스 타입
- Storm, Flink = 트리거와 Materialized View 메커니즘
- Kafka = 이 모든 것을 연결하는 WAL
즉, 현대의 데이터 아키텍처는 하나의 거대한 DB가 unbundle된 형태라는 거예요.
전통적 DB = WAL + 인덱스 + 쿼리엔진 이 하나로 묶인 것
현대 아키텍처 = 각각이 분리된 것
- WAL → Kafka
- 인덱스 → Elasticsearch,Redis, ...
- 쿼리엔진 → Flink, Spark, Presto, ...
이걸 이해하면 "왜 마이크로서비스 아키텍처에서 Kafka가 중심이 되는가"가 자연스럽게 이해돼요.
💡 이 글을 읽고 나서 달라져야 하는 시각
이 글을 제대로 소화하면 다음이 보여야 해요:
- Kafka topic을 설계할 때 — "이건 Log인가 Table인가? Compaction이 필요한가?"
- CDC 파이프라인을 볼 때 — "이건 Table → Log 변환이다"
- 추천 이벤트 스키마를 설계할 때 — "이 Log에서 어떤 Table을 materialize할 건가?"
- Flink job을 볼 때 — "이건 Log 위에서 실시간 Materialized View를 만드는 것이다"
- Redis 캐시를 볼 때 — "이건 Kafka Log에서 파생된 Table이다"