
Kafka 제대로 이해하기 | 멤버십 영상
요약
본 영상은 Kafka의 창시자 중 한 명인 J. Kreps의 원전 글을 리뷰하며, 분산 시스템 아키텍트가 반드시 알아야 할 '로그(Log)' 개념을 깊이 있게 다룹니다. 로그를 단순한 메시지 큐가 아닌, 시간 순서로 정렬된 레코드 배열이자 분산 시스템 일관성의 근간으로 이해하는 것이 핵심입니다.
핵심 포인트
- 분산 시스템의 핵심은 물리적 시간이 아닌 '논리적인 타임스탬프' 기반의 로그이다.
- 로그는 단순히 메시지를 전달하는 큐가 아니라, 순서와 일관성을 보장하는 분산 커밋 로그다.
- 이 원전 학습을 통해 데이터 흐름을 설계하는 아키텍트 시각을 갖출 수 있다.
Video: Kafka 제대로 이해하기 | 멤버십 영상
Channel: 코딩하는기술사
Duration: 33m 18s
Source: subtitle (auto, ko)
Transcript:
안녕하세요. 사랑하는 멤버 여러분. 어 오늘은이 백엔드 개발자와 아키텍터라면 반드시 읽어야 한다고 생각하는 글 하나 리뷰해 보겠습니다. 어 카프카를 만든 이크랩스라는 사람의 글인데요. 더 로그라는 글입니다. 자 이게 어 원문인데요. 어이 글은 2013년도 12월에이 링크드인 엔지니어링 블로그에 개제된 글입니다. 어 제목은 이렇게 더 로그 모든 소프트웨어 엔지니어가 실시간 데이터의 통합 추상화에 대해서 알아야 할 것입니다. 어 저자가이 링크대인에 합류하면서 겪었던 모놀리식 데이터베이스의 한계와 어 분산 시스템 간의 통합 문제, 데이터 통합 문제 그리고 그 문제를 해결하는 과정에서 깨달은 어 로그라는 개념이 왜 분산 시스템에서 핵심이 되는지를 어이 블로그 글을 통해서 깊이 있게 설명하고 있습니다. 그리고 이러한 통찰은 어 저자가 개발한 카프카의 탄생 배경과 어 핵심 철학이 되는데요. 이번 시간을 통해서 여러분들은이 분산 시스템에서의 로그의 역할과 중요성을 이해하고 카프카의 탄생 배경은 물론이고 카프카를 단순히 사용하는 개발자를 넘어서 어 데이터의 흐름을 이해하고 설계하는 아키텍트의 시각을 가지게 되실 겁니다.
요즘은이 결과만 빠르게 만들어 내는데 집중하기 쉬운 세상인데요. 하지만 진짜 실력은 이런 깊이 있는 그래서 나온다고 생각합니다. 어, 이런 원전을 직접 접하고 이해하는 경험이 어, 여러분들을 단순히 도구를 쓰는 개발자가 아니라 어, 설계 영향을 갖춘 아키텍터로 성장시켜 줄 것이라고 믿습니다. 자, 그럼 시작하겠습니다. 자, 본격적으로 들어가기 전에이 카북카는 왜 메시지 Q가 아니라이 분산 커밋 로그라고 불리는가? 어 저자는이 모든 분산 시스템의 핵심을 로그가 있다고 하는데요. 이렇게 갑화를 메시지 Q가 아니라 분산 로그라고 하는 이유가 무엇일까요? 어,이 질문에 답하기 위해서는이 로그라는 개념이 분산 시스템에서 왜 중요한지를 먼저 우리가 이해를 해야 됩니다.이 J 그랩스는 당시 링크드 인수석 엔지니어였고 현재는 컴플런트 CEO입니다. 어, J그랩스가 링크 인해 근무할 당시에 여러 개의 특화된 분수한 시스템을 운영하면서이 로그의 중요성을 깨달았다고 하는데요. 그래서 이글은 저자가 현업에서 직접 겪은 경험에서 나온 통찰이라고 할 수 있죠.
그렇기 때문에 10년이 지난 지금도 여전히 실무에서 유효한 지식이 되는 겁니다. 어, 오늘 우리가이 글을 통해서 분산 시스템을 보는 새로운 관점과 그리고 카프카의 탄생, 배경 그리고 카프카의 핵심적인 철학 그리고 데이터의 흐름 즉 분산 시스템 환경에서 데이터 흐름을 설계하는 사고 방식을 배우게 될 것입니다. 자, 본격적으로 시작하겠습니다. 먼저 로그의 정의를 보겠습니다. 저자는이 글을 통해서 로그를 업핸펜드 온리 그리고 시간 순서로 정렬된 레코드 배열이라고 정의하고 있습니다. 자, 여기 그림을 보시면 이렇게 순차적으로 로그가 끝에 계속 추가가 되고 시간 순서대로 정렬이 되고 있습니다.이 각 레코드에는 이렇게 순차적인 번호가 보여되는데요. 어,이 번호는이 물리적인 클락, 즉이 실제 물리적인 시간과는 분리된 논리적인 타임 스탬프 역할을 한다고 합니다. 다시 말해서 여기에이 레코드에 저장되는 순서이 순서가 곧 시간이며이 시간은이 분산 시스템의 일관성의 근간이 된다고 말하고 있습니다. 분산 시스템은 말 그대로이 여러 대의 서버가 존재하죠.
어, 각 서버를 노드라고도 하는데요.이 수많은 노드의 물리적인 시계는 정확하게 맞추기가 어렵습니다. 어, 여러들이 각각 자기만의 시계를 가지고 있고 어, 네트워크가 지연되거나 하드웨어의 작은 오차 또는이 NTP, 동기와, 오류 등으로 인해서이 각 노드의 시계가 정확하게 일치하지 않을 수도 있거든요. 그래서 작게는 수ml초에서 심하면 수백m까지 차이가 날 수 있는 거죠. 어, 예를 들어서 A에서 3시 24분 0.001초에 쓴 데이터와이 B 서버에서 3시 24분 0.002초에 쓴 데이터 중에서 어느 것이 먼저인지 물리적인 시간만으로는 확신할 순 없다는 거죠. 그런데이 로그의이 순서 즉 순번은 다릅니다.이 로그가 저장된 순서 즉 논리적인 타임스탬프는 실제 시기하고 무관하게 몇 번째로 발생했는가를 순번으로 표현한 것인데요.이 순번 0번이 1번보다 먼저라는 건 시계를 볼 필요도 없이 명확한 거죠. 어 그래서 결론적으로 분수한 환경에서는 어 물리적인 시계는 노드마다 다를 수 있기 때문에 신뢰할 순 없지만이 로그의 순서 즉 로그의 순번은 어떤 환경에서도 순서가 동일하기 때문에 신뢰할 수 있다는 것이죠.
어, 참고로 여기서 말하는이 로그는 우리 개발자들이 흔히 아는이 로그 4J와 같은 어플리케이션 로그가 아닙니다.이 어플리케이션 로그는 사람이 잃는 텍스트이고요.이 글에서 다루는 로그는 프로그램이 잃는 구조화된 기록입니다. 저자는이 두 가지를 명확하게 구분하기 원합니다. 자, 그리고이 전통적인 데이터베이스 영역에서도 어, 로그의 역할이 점점 진화하고 있었습니다. 어, 처음에는이 데이터베이스의 로그의 역할은이 충돌 복구였습니다. DB가 변경 사항을 최종 적용하기 전에 로그에 먼저 기록해 두는 거죠. 어, 이렇게 하면 시스템이 죽더라도 로그를 재생해서 다시 복구할 수 있는 거죠. 우리가 이것을 Wal 즉라이트 어헤드 로그라고 하죠. 그런데이 데이터베이스의 로그가 점점 지나가게 됩니다. 어, 여기 보시는 바와 같이 처음에 충돌 복구와이 트랜잭션의이 원자성과 내구성을 보장하기 위해서 사용되던이 데이터베이스 로그가이 로그 시핑을 통한 원격 데이터베이스의 복재 수단으로 사용되고 나아가서는 어 구독 가능한 데이터 스트림의 형태로 활용되기 시작했습니다.
즉 오라클의 X스트림 그리고 마QL의 바이너리 로그와 같은 형태로 원격 복재에 활용되고 어 전통적인 데이터베이스가 아니라 그 하두비나 검색 엔진 뭐 캐시와 같은 그런 외부의 시스템에도이 데이터 스트림을 제공하는이 법용 구독 메커니즘으로 발전을 해 나가고 있었던 거죠. 어, 결론적으로이 카프카가 탄생하기 전에도 이미이 로그는 데이터 흐름의 핵심 메커니즘으로 활용되고 있었던 거죠. 그러면이 로그가 왜 분산 시스템에서 핵심이 되는지 저자는 어 원칙을 하나 제시하면서 설명을 하고 있습니다. 어 이와여스테이트 머신리플li이션 프ci플 상태 기계 복제 원칙이라고 하는데요.이 원칙은 이렇습니다. 동일하고 결정론적인 두 개 프로세스가 같은 상태에서 시작하고 같은 순서로 동일한 입력을 받으면 동일한 출력을 생성하고 같은 상태로 끝난다. 어, 여기서 결정론적이라는 말은 뭐 타이밍이나 외부 환경에 영향을 받지 않고 같은 입력이면 항상 같은 결과를내는 프로세스를 말하는데요. 어, 다시 말해서 분산한 시스템에서 여러 머신을 모두 같은 상태로 유지하고 싶다면 모든 머신에 같은 순서로 동일한 입력을 주면 된다.
그러면 어떤 머신이든 반드시 같은 상태가 된다는 건데요. 어, 이때 그 같은이 순서를 기록하는 것이 바로 로그라는 것이고 결국이 분수한 시스템의 일관성 문제는이 순서 합의 즉 순서를 맞추는 문제고 도구는 그 순서를 물리적으로 구현하는 도구라는 것입니다. 그래서이 로그가 분산 시스템에서 핵심적인 역할을 한다는 것이고요. 분석 환경에서 여러 노드의 데이터와 처리 순서를 로그가 부장해 주면 그 결과로 모든 노드의 최종 상태가 동일해진다는 것입니다. 결론을 다시 압축하면 로그의 순서가 분수한 시스템의 일관성을 만들어 낸다는 것입니다. 자, 다음으로 저자는이 상태 기계 복제 원칙을 구현하는 두 가지이 복재 모델을 설명합니다. 어, 무엇을 로그에 기록하느냐에 따라서 복제 전략이 달라지는데요. 먼저이 상태 기계 복제 모델입니다.이 이 요청 자체를 로그에 기록하고 모든 복재분이 그 요청을 직접 처리하는 모델입니다. 어 예를 들어서 이렇게 + 1 곱하기 2 같은이 요청이 변환 명령 즉 요청 자체를 로그에 기록하는 방식이죠.
어, 다음으로이 주 백업 모델입니다. 리더 즉 마스터가 요청을 처리하고 그 결과값을 로그에 기록하는 방식인데요. 예를 들어서 이렇게 1, 3, 6이라는이 결과 자체를 로그에 기록을 하고이 마스터 리더를 따르는이 팔로 슬레이브들이이 결과값을 순서대로 적용하는 방식이죠. 자, 이렇게 그림으로 표현되어 있는데요.이 상태 머신 복재 모델은 로그에 어, 실제 요청 자체를 이렇게 기록합니다. 그리고 모든 복재본이 그 요청 자체를 자기가 가져가서 직접 처리합니다. 그리고 주 백업 모델은 어, 마스터 즉 리더가 요청의 결과를 로고에 기록하면이 슬레이브들이이 결과를 가져가서 순서대로 적용하는 모델인 것이죠.이 의 두 가지이 복재 모델은이 로그에 기록하는 내용은 다르지만이 핵심은 한 가지입니다. 바로 순서. 순서가 깨지면 일관성이 깨진다는 것은 동일합니다.이 덧셈과 곱셈의 순서를 바꾸면 결과가 달라지는 것처럼 로그의 순서가 바뀌면 각 복재분이 서로 다른 상태가 되어 버리는 것이죠. 어, 다음으로 저자는이 합의 알고리즘과 로그의 관계를 이야기합니다.
여기이 박소스 그리고이 레프트,이 GAB 같은이 모든 합의 알고리즘은 결국 분산 로그를 유지하기 위한 방법이다라고 말하는데요.이 토소스, 레프트, JB는 분산 시스템의 대표적인 합의 알고리즘들입니다. 어 실제로이 쿠버 네티스의 ETCD 그리고이 주기퍼의 어떤 분산 조율 같은 시스템에서 내부적으로 이러한 알고리즘들을 사용하는데요.이 합이라는 건 무엇일까요? 분산된 여러 노드가 서로 다른 값을 주장할 때 하나의 값으로 일치시키는 과정을 합이라고 하는데요. 예를 들어서 노드 a는 값이 5다라고 하고 노드 B는이 값이 7이다라고 주장할 때 합의 알고리즘은 우리 모두 5로 하자라고 결정하게 만드는 규칙입니다. 어 근데 실제 시스템에서는 갑 하나를 합의하고 끝나지 않죠. 주문하고 결제하고 취소하고 환불하고 이렇게 요청이 끝없이 이어지죠. 값 하나가 아니라이 수많은 값의 순서대로 합의를 해야 된다는 것입니다. 그 수많은 합의 결과를 순서대로 기록한 것이 바로 또 로그라는 것이죠. 이렇게 합의를 설계하다 보면 자연스럽게 로그가 필요해지는 겁니다.
그래서이 박소스 레프트 GB이 합의 알고리즘들이 결국 분산 로그를 유지하기 위한 방법이 된다는 것이죠. 다시 말해서 합의의 결과가 쌓이면 로그가 되고 그 로그를 모든 노드가 동일하게 유지하는 것이이 알고리즘들의 본질이라는 것입니다. 결론적으로 저자가 말하고 싶었던 건 이것입니다. 로그는 단순한 기록 도구가 아니라이 분사한 시스템에 건강이 된다는 말을이 합의 알고리즘을 통해서도 보여주고 있는 것이죠. 자, 다음으로이 테이블과 로그의 이중성에 대한 내용이 나옵니다. 어, 저자가 여기에 음양 기호를 넣었습니다. 로그와 테이블이 마치 음과 양처럼이 반대처럼 보이지만 사실 하나의 데이터를 다른 형태로 표현한 것이라는 의미인데요. 어, 꽤 멋진 비유라고 생각합니다. 어, 저자가 말한 이중성이라는 것은이 로그와 테이블이 서로 다른 것처럼 보일 수 있지만 사실은 같은 데이터를 다른 형태로 표현한 것이라는 뜻입니다. 로그가 원본이고 테이블이 그 로그로부터 파생된 것이라고 말합니다. 로그 테이블 테이블 로그 언어 방향이든 전환이 가능한 대칭이라는 것인데요.
로그를 순서대로 재생하면 테이블을 만들 수 있고 반대로 테이블의 변경 사항을 로그로 발행을 하면 어 실시간 복제 피드가 됩니다. 어 예를 들어 보면이 기로가 소수의 변경 로고이고 현재이 체크아웃 상태가 테이블이 되는 거죠. 어 또이 은행 계좌에서 거래 내역이 로그이고 현재 잔액이 테이블인 것이죠. 사실 우리가 이미 익숙하게 쓰고 있는 개념입니다. 어, 이런 이중성이라는 관점이 중요한 이유가 있습니다. 즉 로그가 원본이고 테이블이 파생물이라는 사실을 인식하면 데이터 아키텍처를 다른 시각에서 설계할 수 있기 때문입니다. 최종 상태만 저장하는 대신에 그 상태를 만들어 낸 이벤트를 저장하는 것. 그러면 현재 상태든 언제든 이벤트를 재생해서 만들어 낼 수 있다는 것이고 과거에 어느 시점의 상태도 제연할 수 있으며 무슨 일이 일어났는지에 대한 모든 이력도 남는다는 것입니다. 즉 체종 상태와 함께 더 많은 것을 얻을 수 있다는 거죠. 어 저는이 개념이 어 흔히 이벤트 소싱 그리고 CQRS의 근간이 된다고 생각합니다.
어 잠시이 이중선과 실무를 한번 연관시켜 보겠습니다. 어이 내용은이 실제 원문에 나오는 내용은 아니지만이 저자가 얘기한이 테이블과 로고의 이중성이 우리가 잘 알고 있는이 현대 아키텍처에서 어떻게 구현되고 있는지를 보여주는 대표적인 사례들이라서 한번 설명하고 넘어가겠습니다. 어 먼저이 이벤트 소싱입니다.이 이 상태 자체를 저장하는 대신에이 상태 변화 이벤트를 로그로 저장하는 거죠. 어 덕분에 언제든지 과거 시점으로 돌아가서 그 시점의 상태를 제연할 수 있고 감사 추적 즉 오디 추적이 자동으로 되는 것이죠. 금융이나 의료처럼 모든 변경 이력이 중요한 도메인에서는 특히이 강력한 패턴이 이벤트 소싱입니다. 다음으로 CQRS 쓰기와 읽기를 분리하는데 쓰기는 이벤트 로그에 읽기는 로그를 재생한 파생 뷰에서 하는 거죠. 쓰기 성능과 일기 성능을 독립적으로 최적화시키는 패턴이죠.이 이 이벤트 소신과 CQRS 두 패턴 모두이 로그와 테이블의 이중성을 실제 아키텍처로 구현한 것입니다. 그리고 카프카의 K 테이블 역시 마찬가지죠.이 카프카 스트림에서 K스트림은 이벤트의 흐름 즉 로그이고 K 테이블은 그 이벤트를 짓게한 현재 상태 즉 테이블인 것이죠.이 이 카프카의 토픽 즉 로그를 테이블 뷰로 자동 투용한 것입니다.
어 이렇게이 세 가지는 이름은 다르지만 본질은 같습니다. 바로 저자가 얘기한 로그와 테이블의 이중성을 다양한 형태로 구현한 것이죠. 자, 다음으로 저자가이 링크들 인해서 경험한 실제 사례를 설명합니다. 검색, 소셜 그래프, 키값 저장소, 문서 저장소, 추천 엔진, 뭐 올랩, 하, 테라 데이터, 또 모니터링 시스템이 수십개의 특화된 시스템이 있었다고 합니다. 즉 분산 시스템 환경이죠. 그런데이 시스템들은 그 필요한 데이터를 그 다른 시스템으로부터 직접 가지고 오는 구조였다고 하는데요. 그래서 시스템 사이에 데이터를 보내야 할 때마다이 시스템 간의 커스텀 파이프라인을 별도로 만들어야 했다고 합니다. 자, 이렇게 시스템간에 별도의 커스텀 파이프라인을 별도로 다 이렇게 만들어서 연결을 하면 n개의 시스템이 있으면 최대 n * n -의 파이프라인이 필요하게 됩니다. 즉 파이프라인의 복잡도가 n제곱이 되는 거죠. 이렇게 연결해야 될 시스템이 늘어날수록이 연결선은 거미줄처럼 폭발적으로 늘어나게 됩니다. 그리고 더 심각한 문제는이 새로운 시스템이 추가가 될 때마다 기존 파이프라인과 세로 모두 연결을 해야 된다는 것입니다.
즉 단순히 파이프 하나가 아니라 기존 시점 전체와 다시 연결을 이렇게 복잡하게 해야 된다는 거죠. 어, 그리고이 파이프라인 내수가 이렇게 수십가 되면서 문제가 생겼을 때 어디서 문제가 생겼는지 찾는게 큰 일이 됩니다. 수정보다 원인 파악에 더 많은 에너지를 쓰게 되는 것이죠. 그리고 더 나쁜 것은 파이프라인이 잘못 깨진 채로 데이터가 흘러 들어가면 시스템은 돌아가고 있으니까 문제가 있는지조차 모르지만 실제로는 잘못된 어떤 결과가 나올 수 있는 거죠. 아무리 정교한 알고리즘을 돌려도 입력되는 데이터가 오염됐으면 결과도 잘못될 수 있는 거죠. 즉 가비지인, 가비지 아웃이라는 말이 있듯이요. 결국 데이터 이동 자체가 가장 큰 엔지니어링 부채가 되어 버린 것이죠. 어, 해결책은 심플했습니다.이 중앙에 로그 허버를 하나 두는 것입니다.이 모든 데이터의 소스는 중앙 로그에 발행을 하고 모든 소비자 즉 데이터의 컨슈머는 중앙 로그를 구독하는 형태인 거죠. 여기서 세 시스템이 하나 추가되면이 중앙 로그하고 한 번만 연결하면 됩니다.
기존 구조에서는 시스템이 열 개일 때 파이프라인이 90개가 필요한 반면이 중앙 로그 방식은 열 개면 되는 거죠. 즉 n제곱의 복잡도가 n으로 떨어지는 것입니다. 그리고이 소비자 컨슈머는 데이터가 어디에서 왔는지 알 필요가 없습니다. 주문 데이터베이스에서 왔든 뭐 하에서 왔든 그냥 본인이 사용하고 싶은 로그를 소비하면 되는 것이죠. 그리고이 중앙 로그는 또 하나의 역할 버퍼 역할도 하게 됩니다. 예를 들어서 배치 시스템은 하루에 한 번만 읽어 가면 되고 실시간 시스템은 초단위로 읽어 가면 됩니다. 즉 컨슈머의 특징에 따라서 자신의 속도로 데이터를 소비만 하면 된다는 거죠. 그리고 데이터를 소비하는이 컨슈머가 갑자기 다운되더라도 다시 살아나서 중앙로그 허브에 저장되 있는 데이터를 본인이 가져간 그 이후부터 다시 읽어 가면 됩니다. 결과적으로 각 소비자가 자신의 속도에 맞게 자신의 상황에 맞게 데이터를 소비할 수 있는 거죠. 어 그런데 어이 중앙로그 허브하는게 지금 보면 굉장히 당연한 해결책처럼 보이잖아요.
근데 이게 지금 우리한테 당연하게 느껴지는 이유는 우리가 이미이 카프카에 익숙해져 있기 때문입니다.이 저자가 당시에 링크드인에서 카프카를 개발하던 당시에는이 로그를 중심으로 데이터를 통합 설계한다는 발상 자체가 새로운 것이었고 이런 중앙로그 허브 개념은 없었습니다. 기존 메시징 시스템들은 고성능 그리고 내구성 그리고 다중의 구독 그리고 리플레이 이와 같은 것들을 동시에 만족하지 못했었거든요. 그래서 링크드인이 직접 가를 만들었던 것입니다. 어 그래서 지금은 이렇게 표준 구현으로 받아들여지는이 당연해 보이는 해결책을 처음으로 만들어내는 것 그게 진짜 실력이고 혁신이었던 거죠. 그리고이 중앙구 허브 관점에서이 ETL을 다시 보면 기존 방식의 문제점이 또 하나 명확해지는게 있습니다.이 기존 ETL에서는 중앙에 DW팀이이 모든 시스템의 데이터의 정제 책임을 가졌습니다. 여기서 정제라는 것은 뭐 날짜 형식을 통일하고 뭐 널값을 제거하고 뭐 여러 개의 시스템에 데이터를 합치고 하는 즉이 원본 데이터를 사용 가능한 형태로 다듬는 작업을 정제라고 하는데요.
팀이 늘어나고 데이터가 많아질수록 DW 팀이 병목이 됩니다. 그래서 데이터 반영이 늦어지고 전체 조직의 데이터 활용 속도가이 DW팀의 처리 속도에 묶기게 되어 버리는 거죠. 그런데이 로그 중심 방식에서는 데이터를 만드는 팀이 정제 책임을 가지도록 합니다. 즉 생산자 데이터 생산자가 정제 후에 로그에 개시하도록 하는데요. 자신의 데이터를 가장 잘 아는 사람이 직접 정제해서 로그에 개시하라는 거죠. 그리고 중앙팀은 단지 구독만 하면 되는 구조. 어, 이것은 기술적인 선택이기도 하지만 어, 조직적 확장의 문제이기도 합니다. 팀이 100개가 되어도 각 팀이 자기가 생산하는 데이터에 책임을지면 중앙 팀에 부담이 집중되지가 않죠. 그렇게 하면 조직이 아무리 커져도 데이터 파이프라인이 함께 확장될 수 있는 구조가 되는 것입니다. 자, 이제 가프카의 핵심 설계 철학으로 넘어갑니다. 어, 가프카를 우리가 설명할 때 흔히 메시지 Q라고 많이들 하시는데요.이 J크랩스는 이것을 명확하게 부정합니다.이 원문에서는 이렇게 말합니다.
카프카는 데이터베이스도 아니고 로그기도 아니고 전통적인 메시징 시스템도 아니다. 그러면 카프카는 무엇일까요? J크랩스가 원문에서 직접 쓴 표현은 이렇습니다. 로그를 독립 서비스로. 이것이 원문에서 가프카의 본질을 표현한 문장입니다. 로그 as스탠더론 서비스. 어 이후에이 갑과 공식 문서와 컴플런트 통해서이 갑을 어 분사한 커밋로그라는 표현이 나오는데이 역시 원문의 철학을 압축적으로 잘 담고 있는 표현이죠.이 메시지 Q와 분산 커밋 로그는 뭐가 다를까요?이 이 메시지 Q는 원래이 테스크를 전달하고 처리되면 삭제되는 구조로 설계되었습니다. 우리가 잘 알고 있는 레빗 MQ가 대표적이죠. 컨슈머가 데이터를 읽어가면 메시지가 사라지는 거죠. 물론 요즘은 뭐 설정을 통해서 조정을 할 수 있습니다만 처음에 설계 철학 자체가 달랐다는 거죠.이 이 카프카는 처음부터 메시지를 기록하고 보존하는 것을 목적으로 설계된 겁니다. 그래서이 차이가이 카프카를 단순히 메시지 전달 도구가 아니라 조직 전체 데이터 흐름의 중추로 만드는 근거가 된 것이죠.
어, 여기 뭐 파티션인 그림은 뭐 다음 장에서 설명하겠습니다. 어, 가북카가 메시지 큐와 결정적으로 또 다른 기능이 있습니다. 어, 바로이 로그 컴팩션인데요. 카프카는 기본적으로 모든 메시지를 보존합니다. 연구적으로. 그런데이 계속 데이터가 쌓이다 보면 디스크가 부족해질 수 있죠. 그래서 카포카도 오래된 메시지를 정리를 해야 되는데 무조건 다 지우면 안 되는 경우가 있습니다. 어 일반적인이 리텐션 구조는 시간이나 용량 기준으로 오래된 메시지를 삭제하죠. 뭐 클릭 이벤트나 뭐 로그 매트릭처럼 시간이 지나면 의미가 줄어드는 데이터에 사용하기 적합하죠. 반면에이 로그 콤팩션은 같은 키에 오래된 데이터를 삭제하고 최신값은 유지시켜 줍니다.이 그림을 보시면 데이터가 이렇게 쌓이고 있다가 이렇게 키원 키원의 데이터 중에서 가장 최신 버전 4는 유지를 시켜주고 키 앞에 있는 키원은 삭제한다는 거죠. 기존 리텐션 구조였으면 오래된 건 무조건 삭제가 되는 거죠. 그렇지만 카북카는 이렇게 같은 키의 최신 상태는 유지해 준다는 겁니다.
어, 이것은 뭐 사용자, 뭐 계좌 잔액처럼 서로 다른 키에 대한 최신 상태가 필요한 데이터에 적합한 거죠. 이렇게 하면 카프카 토픽이 키별 최신 상태를 보장하는 저장소가 되고 카프카를 단순히 메시지 전달이 아니라 상태 저장소로 활용할 수 있는 근거가 되는 것이죠. 그래서이 리플레이 재생이 필요하거나 여러 소비자가 독립적으로 읽어야 한다면 카법카를 선택하고 단순하게 테스크를 전달하고 처리하는 용도라면 레빗 MQ가 적합한 거죠. 어, 그리고 앞장표에 이렇게 파티셔닝 그림이 잠깐 나왔었는데요.이 파티셔닝은이 카프카가 왜 빠른지를 설명할 수 있는 구조입니다. 이렇게 로그를 여러 파티션으로 나눠서 각 파티션이 독립적으로 동작할 수 있게 만들 수 있습니다. 파티션을 늘리면 처리량이 선형적으로 늘어납니다. 링크드 인해서는 하루에 600억건 이상의 메시지를 처리할 수 있다고 하는데요. 그 핵심 이유 중에 하나가 파티셔닝인 거죠. 자, 다음으로 실시간 스트림 처리와 로고의 관계를 이야기합니다.이 스트림 처리라는 것은 데이터가 발생하는 즉시 실시간으로 처리하는 방식을 말하는데요.이 스트림 처리를 배치의 반대 개념으로 보는 시각이 있는데 J크랩스는이를 완전히 뒤집습니다.이 저자는 이렇게 얘기합니다.이 배치는 윈도우 크기가 1인 스트림 처리다.
여기서 윈도우란 데이터를 처리하는 시간 단위를 말하는데요. 배치는 하루치 데이터를 모아서 한꺼번에 처리하니까 윈도우 크기가 하루 즉 1일인 스트림 처리와 같다는 의미입니다. 어 저자는이 배치를 미국의 인구 조사하고 비교해서 예를 들고 있습니다. 2790년에는이 말을 타고 돌아다니면서 종이에 인구 조사를 기록했으니까 배치가 당연했다고 합니다. 하지만 저자는이 배치 처리가이 시대의 유산이 자동화 과정에서 형태만 그대로 남아 있는 역사적 유물이라고 말하고 있습니다. 데이터는 항상 연속적으로 발생하고 데이터가 연속적으로 발생한다면 처리도 연속적이어야 한다. 그것이 자연스럽다라고 하고 이것이 스트림 처리의 본질이라고 얘기를 하고 있습니다. 어 실제이 링크드 인해서도 배치 데이터 수집은 거의 없다고 합니다. 대부분이 활동 데이터 또는 데이터베이스 변경 모두 연속적으로 발생하고 처리한다고 합니다. 다음으로 데이터 흐름 그래프와 상태 저장 처리입니다.이 이 스트림 처리 작업들은 로그를 통해서 연결됩니다.이 각 처리 단계는 로그에서 데이터를 읽고 자기의 작업을 하고 또 로그에 다시 씁니다.
이렇게 여러 개의 처리 단계가 로그를 매개로 연결되는 구조. 어, 이것이 데이터 흐름 그래프이고요. 그리고 로그는이 구조에서 두 가지 역할을 합니다. 첫 번째는 처리 단계 간의이 순서 보장이고 두 번째는이 컨슈머 소비자들의 속도 차이를 흡수하는 버퍼입니다. 데이터를 생산하는 속도가 소비하는 속도보다 빠를 때 그때 로그가 중간에서 버퍼 역할을 해서 소비자가 자신의 속도에 맞게 처리할 수 있도록 하는 거죠. 앞서 설명드린 내용이죠. 그런데이 스트림 즉 실시간 스트림 처리해서 상태를 유지해야 되는 경우도 있습니다. 예를 들어서 클릭 스트림 처리해서이 사용자별 클릭 횟수를 집계를 해야 된다면 어플리케이션이 상태를 메모리에 유지를 해야 됩니다. 근데 이때이 어플리케이션이 장애로 죽어 버리면 메모리 상태가 사라져 버리죠. 그럼 어떻게 복구를 해야 될까요? 해결책 역시 로그라는 것입니다. 로컬 데이터베이스의 상태를 저장하면서 변경 사항을 로그 백업하는 거죠. 그렇게 해서 장애가 발생하면 로그를 재생시켜서 상태를 복구시킬 수 있는 겁니다.이 카포가 스트림에이 스테이트스토가이 패턴을 현대적으로 구현한 대표적인 사례라고 할 수 있습니다.
어, 여기서 핵심 메시지는 스트림 처리도 로그가 중심이라는 것입니다. 처리 단계로 연결하는 것도 로그, 순서를 보장하는 것도 로그 장애를 복구하는 것도 로그라는 것이죠. 스트림 처리의 중심에는 항상 로그가 있다는 의미입니다. 어, 지금까지 로그가이 데이터베이스의 복구 그리고 데이터의 통합 어, 스트림 처리해서 어떤 역할을 하는지 살펴봤는데요. 이제는 한 발 살짝 더 물러나서 어, 가장 멀리서 그리고 가장 높은 추상화 수준에서 한번 바라보겠습니다.이 저자는 모든 분산 시스템을 두 가지 레이어로 분리할 수 있다고 말합니다. 바로 로그 레이어와 서빙 레이어인데요. 로그 레이어는 데이터를 안전하게 기록하고 서빙 레이어는 데이터를 빠르게 조회합니다. 로그 레이어는 순서 보장, 일관성, 복재, 복구를 담당합니다. 지금까지 우리가 계속 이야기해 온 것들이죠. 모든 분수한 시스템이 공통으로 필요한 것들입니다. 그리고 서빙 레이어는이 사용자나 어플리케이션의 요청에 직접 응답해 주는 영역입니다. 로그를 읽어서 빠르게 찾을 수 있는 인덱스 구조로 변환해 둡니다.
어이 부분은 어 시스템마다 다릅니다. 관객 데이터베이스는 뭐 비트리 인덱스 검색 엔진은 역 인덱스 뭐 올랩은 컬럼 스토어 콜이 방식이 다르기 때문에 인덱스 방식도 다른 거죠. 어 앞서이 로그와 테이블 이중성에서 로그가 원본이고 테이블이 파생물이라고 했죠. 역시 같은 개념입니다.이 관점으로 보면 뭐 레디스, 엘라스틱 서치, 카산드라 같은 시스템들은 사실 로그를 구독해서 각자의 방식으로 인덱싱하는 파생 뷰인 것이죠. 이렇게 생각하면 분산 시스템 설계가 훨씬 명확해집니다. 세 시스템을 도입할 때이 시스템이 로그 레이어인가 아니면 서빙 레이어인가 이것을 먼저 파악하면 그 시스템의 역할과 한계가 바로 보이기 때문이죠. 그래서 새로운 시스템을 설계할 때 로그 레이어와 서빙 레이어를 어떻게 분류할 것인가를 먼저 생각해 보세요.이 복잡해 보이는 분산 시스템도 결국에는이 두 가지 레이어의 조합으로 이해할 수 있습니다. 어 그렇다면 이렇게 기능이 분리된 시스템들을 어떻게 하나로 연결할 수 있을까요? 어 저자는 이것을 언번들링이라는 개념으로 설명합니다.
하나의 거대한 시스템에 묶여 있던 기능들을 풀어서 각각의 전문 시스템으로 분리한다는 뜻입니다. 원문에서 저자는 이렇게 예를 듭니다. 분산 조율은 주키퍼가 로그는 카프카 검색 엔진은 루신 네트워크 통신은 내디 데이터 직류라는 에이브로 이렇게 각 기능이 전문 시스템으로 분리되는 것이죠. 그리고 이렇게 분리된 시스템들을 하나로 연결하는 것이 바로 로그라는 것입니다.이 람다 아키텍처는 배치와 스트림을 함께 운영하는 구조고이 카프카 아키텍처는 배치를 없애고 스트림만으로 처리하는 구조입니다. 그리고 CQRS 이벤트 소싱은 앞서 말씀드린 대로 로그와 테이블 이중성을 구현한 아키텍처 패턴이고요. 아 참고로이 람 아키텍처 뭐 가크 아키텍처 이벤트 소싱은이 원문에 직접 나오는 내용은 아닙니다. 하지만 지금까지 우리가 배운이 로그 중심 철학이 현대 데이터 아키텍처에서 어떻게 구현되고 있는지를 보여주는 대표적인 사례라고 할 수 있습니다. 어, 이렇게 이름은 달라도 결국 그 중심에 항상 로그가 있는 것이죠. 이것이이 글이 2013년도에 쓰여졌음에도 지금까지 유효한 이유입니다.
저자가 제시한 로그 중심 철학은 트렌드가 아니라 원리였기 때문이죠. 자, 오늘 내용을네 가지 핵심 포인트로 한번 정리해 봤습니다. 로그를 이해하면 분수한 시스템의 본질이 보인다. 자, 첫 번째 로그는 분수한 시스템에서 순서와 일관성을 보장하는 가장 근본적인 추상화다. 추상화란 복잡한 내부 구현을 숨기고 핵심만 드러내는 것이잖아요. 자동차 핸들처럼 복잡한 기계 구조를 몰라도 핸들만 조작하면 방향을 바꿀 수 있죠. 그것처럼 로그도 분산 시스템에서 노드 간의 시간 불일치 그리고 네트워크 지연 장애 복구 뭐 분산 합의이 같은 수많은 복잡한 문제들을이 순서 있는 기록이라는 단순한 개념 하나로 다룰 수 있게 해 주기 때문에 근본적인 추상화라는 것입니다. 그리고 여기서 말하는이 순서와 일관성은 데이터 순서만을 의미하는 것은 아닙니다. 데이터 순서, 이벤트의 순서, 연산의 순서, 상태 변화의 순서 즉 분수한 환경에서 무엇이 어떤 순서로 발생했는가에 대한 법용적인 보장입니다. 이것이 로그가 분수한 시스템의 수많은 문제를 하나의 추상화로 풀어낼 수 있는 이유인 것이죠.
두 번째로 카프카는이 n제곱이라는 데이터의 통합 문제의 복잡성을 n으로 낮추기 위해 탄생한 로그를 독립 서비스로 만든 인프라입니다. 메시지 Q가 아닙니다. 저자는 링크드 인해서 겪었던이 분수한 시스템과 복잡한 데이터의 통합 문제를 해결하기 위해서 카프카라는 중앙 로그 허브를 개발했으며 이때 카프카는 단순히 메시지 큐가 아니라 조직 전체 데이터 흐름의 중추 그것이 카프카의 본질이었던 것이죠. 세 번째로 테이블과 로그의 이중성을 이해하면 이벤트 소싱, CQRS 같은 패턴이 자연스럽게 이해가 됩니다. 어, 로그를 재생하면 테이블이 되고 테이블의 변경을 발행하면 로그가 된다고 했습니다. 그리고 로그가 원본이고 테이블이 파생물이라고 했습니다. 이벤트 소싱은 최종 상태가 아니라 그 상태를 만들어낸 1년의 이벤트들을 로그합니다. 그리고 CQR에서는 쓰기는 이벤트 로그에 읽기는 그 로그를 재생한 파생 뷰에서 합니다. 이것들은 로그 테이블 이중성이라는 원문의 철학이 현대 아키텍처에서 구현된 대표적인 사례라고 생각합니다.
결국 이벤트 소싱과 CQR에서는 완전히 새로운 개념이 아니라 로그와 테이블의 이중성을 현실의 아키텍처로 구현한 것이라고 볼 수 있는 거죠.네 네 번째 모든 분수한 시스템은 로그 레이어와 서빙 레이어로 분류할 수 있습니다. 어 복잡해 보이는 시스템도 결국이 두 레이어의 조합이라고 하는데요. 로그 레이어는 순서 보장, 일관성, 복재, 복구를 담당하고 모든 분수한 시스템이 공통으로 필요한 것들이고 서빙 레이어는 사용의 커리에 빠르게 응답하기 위한 인덱스를 유지합니다.이 부분은 시스템마다 다를 수 있죠. 앞서 말씀드린 레디스, 엘락스틱, 서치, 카산드라와 같은 이름도 다르고 용도 달라 보이지만 사실 모두 로그를 파생 뷰라는 것이죠. 다시 말해서 로그가 원본이고이 시스템들은 파생물인 것입니다. 자, 마지막으로 어, 여러분께 어,이 여섯 가지 질문을 드리면서 마치겠습니다. 어, 강의가 끝난 후에 지금 다니시는 회사의 시스템을이 질문들로 한번 들여다 보시기 바랍니다. 자, 첫 번째 우리 회사의 분산 시스템의 데이터 일관성은 어떻게 보장하고 있는가?
즉 모든 서버들의 데이터 일관성을 로그 보장하고 있는가? 아니면 다른 메커니즘을 사용하고 있는가? 두 번째 서비스간 데이터 동계화가 혹시 n제곱의 복잡성을 가진 파이프라인으로 구성되어 있지 않은가? 즉 중앙 로그 허브 없이 서비스들끼리 직접 연결하고 있지는 않은가? 세 번째 어 우리 시스템은이 상태를 저장하는가 아니면 이벤트를 저장하는가? 감사 추적이 필요한 도메인의 최종 결과인 상태만 저장하고 있지는 않은가? 자,네 번째. 우류 회사는 카프카를 제대로 활용하고 있는가? 단순히 가북카를 메시지 Q로만 쓰고 있지 않은가? 리플레이 컴팩션은 활용하고 있는가? 그리고 다섯 번째이 데이터의 정제 책임이 데이터를 만드는 생산자에 있는가? 아니면 중앙의 팀이 모든 정제 책임을 떠막고 있는가? 그 중앙에 DW 팀이 병목이 되고 있지는 않은가? 자, 마지막으로 배치로 처리하고 있는 것들 중에서 실시간 스트림으로 전환하면 더 나은 것이 있는가? 배치가 관행이 된 것인가 아니면 정말 배지가 최선인가? 자,이 질문들로 어, 여러분의 시스템을 다시 들여다보는 계기가 되었으면 합니다.
자, 오늘 이렇게 해서 카프카를 창시한 분의 글을 한번 읽어봤습니다. 원문은이 링크인의 엔지니어링 블로그에서 직접 읽을 수 있습니다. 한번 읽어 보시길 권장드리고요. 오늘도 수고했습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 YouTube 코딩하는기술사 (개발/IT)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기