kafka 가 왜 필요할까?
현대 아키텍처의 흐름상 단일 서버 자원만으로 복잡해진 서비스를 지탱하기 어렵다.
그래서 일반적으로 여러 자원(서버, 컴퓨팅 엔진)을 분산시켜 각각을 고도화하는 방식 일명 마이크로서비스 아키텍처를 적용하는 곳이 많아졌고 성공 사례가 많아졌다.
분산된 서버 간에 발생하는 이벤트나 로그 데이터, 일명 스트리밍 데이터라고 불리는 것들을 실시간으로 처리해야하는 요구사항이 점점 늘어나게 되었는데, 이에 반해 기존의 아키텍처에서는 이런 실시간 스트리밍 데이터에 대한 처리가 쉽지 않았다.
위의 그림은 복잡한 현대 웹 아키텍처를 잘 보여준다.
위 그림에서도 알 수 있듯 하나의 앱/서비스에서 발생한 데이터들이 (일명 스트리밍 데이터) 시스템 전반에 걸쳐서 사용되는 것을 볼 수 있다.
이런 복잡한 아키텍쳐에서 많은 사람들은 다음 3가지에 피로를 느꼈다
- 거짓된 데이터
- 실시간 트랜잭션에 의한 성능 저하
- 준수하지 못한 메시징 시스템의 성능
피로감 1. 거짓된 데이터
위의 복잡한 아키텍처를 잘 보면 user side에서 발생한 데이터가 여러 시스템 컴포넌트를 거쳐서 재가공되는 것을 볼 수 있다.
이러한 상황에서 메시지 자체가 점점 본래의 의미를 잃게되고 시스템 이곳저곳에서 서로 다른 정보로서 사용되는 것이다. 여러 시스템을 거치면서 정보가 왜곡되고 변형되어 잘못된 분석 결과를 초래할 수 있다.
시간의 흐름에 따라 몇몇은 데이터의 본연의 의미를 보존하고 증명하는 무언가가 필요하다고 주장했다
우리는 이를 Single Source of Truth, 단일 진실 공급원 이라고 부르는데, 결국 단일진실공급원의 역할을 수행할 누군가가 필요했다.
피로감 2. 실시간 트랜잭션에 의한 성능 저하
영속화 과정에서 업데이트 연산을 안전하게 수행하기 위해서 일반적으로 hold and wait 방식을 사용한다.
대부분의 복잡한 비즈니스 상황은 특정 데이터에 대한 점유와 그 데이터를 원하는 다른 경쟁자들의 대기로 안전성을 보장한다.
이 과정에서 대기시간이 늘어나게 되며 그에 대한 여파로 서비스 응답 시간의 저하가 발생하여 사용자에게 불편한 경험을 제공하게 되었다.
이러한 상황은 실시간 트랜잭션 (OLTP, OnLine Transaction Process) 이 동기적으로 발생하기 때문에 문제가 되는 것이다.
문제를 해결하기 위해서는 동기 방식의 트랜잭션을 없애고 비동기 방식의 처리 프로세스를 지원하기 위해서 메시징 인프라가 필요하게 되었다.
위 상황의 예시를 들어 보겠다.
로그인을 하려면 서버 쪽에서 생각보다 많은 처리를 해줘야 한다. 로그인할 때 서버쪽에서 아이디 비밀번호만 조회하는 게 아니라 내부적으로 이 사용자가 언제 들어왔고 어디서 들어왔고 마지막 로그인 타임, 로그인 횟수 이런 것들을 다 업데이트해야 한다.
임영문 콘서트를 예매하기 위해 인터파크에 접속해서 로그인을 한다고 해보자.
만약 위에서 설명한 과정을 다 동기 처리를 해버리면 로그인하는데 세월아 네월아 걸린다.
그래서 사용자한테 일단 필요한 작업만 처리해 준다. 그냥 아이디 비밀번호만 확인해서 true/false만 반환해 주면 된다.
그리고 나머지 처리해야 할 데이터들인 로그인 타임, 로그인 시간, 로그인 기록들은 큐로 다 던져놓으면 된다.
핵심은 사용자에게 바로 보여야 할 부분은 동기적으로 처리하고 오래 걸리면서 사용자에게 바로 필요하지 않은 작업들에 대한 데이터들은 메시지 브로커로 다 보내면 된다. 이러한 방식을 통해 모든 걸 동기적으로 처리하는 것보다 빨라지고 대규모 트래픽도 좀 더 쉽게 해결할 수 있다.
아래 내용은 GPT에게 위 상황에 대해 또 다른 예시들을 보여 달라 했을 때 가져온 내용이다.
대기 시간, 성능 저하, 데드락 등의 문제는 주로 다음과 같은 상황에서 발생합니다.
1. 동시 사용자 증가
상황 설명: 특정 웹 애플리케이션이나 서비스에 동시에 많은 사용자가 접속할 때.
예시: 온라인 쇼핑몰에서 블랙 프라이데이 세일 기간 중 수천 명의 사용자가 동시에 결제를 시도하는 경우, 시스템이 동기적으로 요청을 처리하게 되면 각 사용자의 결제가 차례로 처리되면서 대기 시간이 길어지고, 이는 응답 속도의 저하로 이어집니다.
2. 복잡한 트랜잭션
상황 설명: 여러 데이터베이스 작업을 포함하는 복잡한 트랜잭션이 있을 때.
예시: 사용자가 상품을 구매하면서 결제와 재고 업데이트를 동시에 처리해야 하는 경우, 동기적으로 이 작업이 처리되면 재고 업데이트가 완료될 때까지 결제가 완료되지 않게 됩니다. 이로 인해 사용자는 결제 화면에서 오랜 시간 기다려야 할 수 있습니다.
3. 자원 경합
상황 설명: 여러 트랜잭션이 동일한 데이터 자원에 접근하려고 할 때.
예시: 두 개의 트랜잭션 A와 B가 동시에 사용자 계정 정보를 수정하려고 할 때, 하나의 트랜잭션이 자원을 점유하고 있는 동안 다른 트랜잭션은 대기해야 하며, 이로 인해 대기 시간이 길어질 수 있습니다.
4. 데드락 발생
상황 설명: 여러 트랜잭션이 서로 다른 자원을 점유한 채로 서로의 자원을 기다리는 경우.
예시: 트랜잭션 A가 데이터 X를 점유하고 트랜잭션 B가 데이터 Y를 점유한 상태에서, A가 Y를 필요로 하고 B가 X를 필요로 하면 두 트랜잭션이 서로 대기하게 되어 데드락 상황이 발생합니다. 이 경우 시스템은 이러한 트랜잭션을 해제하지 않으면 응답을 하지 않게 됩니다.
결론: 비동기 방식의 필요성
이러한 문제들은 특히 실시간 트랜잭션 처리(OLTP)가 필요한 환경에서 더욱 두드러지게 나타납니다.
사용자는 빠르고 매끄러운 경험을 기대하며, 이러한 대기 시간이나 성능 저하로 인한 불편함은 고객 이탈로 이어질 수 있습니다.
비동기 방식의 트랜잭션 처리는 이러한 문제를 해결하기 위해 채택됩니다. 메시징 인프라를 사용하면 각 트랜잭션이 독립적으로 처리되며, 대기 시간 없이 즉각적으로 반응할 수 있도록 하여 성능을 향상하고, 시스템의 안정성을 높일 수 있습니다.
실시간 트랜잭션 처리(OLTP)가 필요한 환경은 일반적으로 빠른 응답 속도와 높은 동시성을 요구하는 시스템이나 애플리케이션을 말합니다. 구체적인 예시는 다음과 같습니다:
1. 온라인 쇼핑몰
설명: 사용자들이 상품을 검색하고 결제하는 과정에서 빠르고 즉각적인 응답이 필수적입니다.
예시: 블랙 프라이데이와 같은 이벤트 기간에 수천 명이 동시에 결제를 시도할 경우, 시스템이 즉각적으로 처리하지 않으면 고객이 불편함을 느끼고 구매를 포기할 수 있습니다.
2. 은행 및 금융 서비스
설명: 고객의 계좌 이체, 잔고 조회, 결제 등의 트랜잭션이 실시간으로 이루어져야 하며, 데이터의 정확성과 신뢰성이 매우 중요합니다.
예시: 사용자가 ATM에서 현금을 인출할 때, 계좌의 잔고가 실시간으로 업데이트되어야 하며, 이러한 정보를 기반으로 다른 사용자들도 서비스를 이용할 수 있어야 합니다.
3. 항공 예약 시스템
설명: 사용자들이 항공편을 검색하고 예약할 때 실시간으로 좌석 가용성을 확인하고 결제해야 합니다.
예시: 특정 항공편이 이미 예약되었거나 만석일 경우, 다른 고객이 그 항공편을 예약하지 않도록 신속하게 정보를 업데이트해야 합니다.
결론
이와 같은 환경에서는 실시간 트랜잭션 처리가 필수적이며, 사용자 경험을 극대화하고 시스템의 신뢰성을 보장하기 위해 비동기 처리 방식과 메시징 인프라가 중요하게 여겨집니다.
피로감 3. 준수하지 못한 메시징 시스템의 성능
메시징 인프라는 앞선 동기 방식의 트랜잭션 저하를 회피할 수 있는 좋은 기술이다.
이러한 메시징 인프라는 데이터 상호작용을 위한 컴포넌트가 직접 연결을 하는 것이 아니라 중간에 위치한 message exchange 가 실제 메시지를 교환해 주는 역할을 수행했다.
메시징 시스템 내부의 exchanger 들은 시스템 내에서 통신이라는 중요한 역할을 수행하기 때문에 신뢰성에 집중하여 설계되었다.
결국 신뢰성에 집중하다 보니 성능에 대해서는 큰 관심사가 아니었는데, 메시지 인프라에 대한 책임이 커지며 부하가 많아져 결국 좋지 않은 사용 경험을 사용자에게 제공하였다.
이 상황에서 등장한 카프카
복잡해진 현대 웹 아키텍처를 해결하기 위해 linkedin에서는 Jay Kreps와 여러 엔지니어들을 필두로 사내에서 사용할 중앙 집중형 메시징 인프라인 kafka 를 개발하였다.
그리고 앞서 말한 3가지의 문제를 멋지게 해결하며 linkedin의 핵심 infrastructure로 자리 잡게 되었고 앞선 아키텍처를 다음과 같은 형태로 간소화하게 되었다고 한다
카프카가 다른 메시징 인프라와 차별점을 가지며 현존하는 최강의 데이터 플랫폼 인프라로 자리 잡았다.
그 특성을 한 번 살펴보자.
log based architecture
카프카를 설명하기 위해 가장 적합한 단어는 로그 시스템이다.
로그는 append only와 seeking by offset이라는 특성이 있는데, 카프카 역시 이벤트 메시지들을 로그로 취급한다.
카프카는 로그 지향 시스템이기 때문에 특정 시점에 발생한 로그를 변경하거나 중간 삽입을 지원하지 않는다.
카프카는 휘발성 메모리에만 임시로 저장하여 특정 클라이언트가 소비하게 되면 사라지도록 설계된 다른 메시징 인프라와 다르게, 메시지를 전부 저장한다
메시지를 전부 저장하는 특성덕에 추후 컨슈머 파트에서 이야기하겠지만 카프카를 사용한다면 메시지를 언제든지 다시, 어느 시점이든 읽어올 수 있다.
high availability & high scalability
카프카는 일반적으로 zookeeper 라는 분산 코디네이터와 함께 동작한다.
분산되어 있는 카프카 인스턴스들을 클러스터링 하는 것을 기조로 하기 때문에 이 특성을 활용하여 zero downtime을 지원하는 scaling 이 가능하다.
또한 카프카는 현대의 다른 메시징 인프라의 장점들과 마찬가지로 producer와 consumer 가 명확히 분리되어 있다.
결국 과거 messaging infra에서 볼 수 있는 과중한 일을 처리하는 exchanger 보다 빠른 성능을 제공한다.
Refs
'Kafka' 카테고리의 다른 글
Kafka KRaft Mode (0) | 2024.07.12 |
---|---|
Kafka 기본 개념 (0) | 2024.07.12 |