1장. 아파치 카프카 개요

문법식·2022년 8월 4일
0
post-thumbnail

아파치 카프카가 탄생한 배경에 대해서 알아보았다.

아파치 카프카란

카프카는 여러 대의 분산 서버에서 대량의 데이터를 처리하는 분산 메시징 시스템이다. 메시지를 받고, 받은 메시지를 다른 시스템이나 장치에 보내기 위해 사용된다.

카프카는 대량의 데이터를 높은 처리량실시간으로 취급하기 위한 제품으로 다음 4가지를 실현할 수 있다.

  • 확장성: 여러 서버로 확장 구성할 수 있기 때문에 데이터 양에 따라 시스템 확장이 가능하다.
  • 영속성: 수신한 데이터를 디스크에 유지할 수 있기 때문에 언제라도 데이터를 읽을 수 있다.
  • 유연성: 연계할 수 있는 제품이 많기 때문에 제품이나 데이터 시스템을 연결하는 허브 역할을 한다.
  • 신뢰성: 메세지 전달 보증을 하므로 데이터 분실을 걱정하지 않아도 된다.

카프카 탄생 배경

카프카는 링크드인 웹사이트에서 생성되는 로그를 처리하여 웹사이트 활동을 추적하는 것을 목적으로 개발되었다. 웹에서 생성되는 대량의 로그를 분석하여 사용자가 웹에서 하는 활동을 모니터링하고 서비스 개선에 활용하는 것이다. 링크드인이 실현하려는 목표는 다음과 같았다.

  • 높은 처리량으로 실시간 처리한다.
  • 임의의 타이밍에서 데이터를 읽는다.
  • 다양한 제품과 시스템에 쉽게 연동한다.
  • 메시지를 잃지 않는다.

높은 처리량으로 실시간 처리한다.

링크드인은 전 세계 사용자의 방대한 엑세스 데이터를 처리해야 하기에 처리량이 우수해야 한다. 또한 사용자의 활동을 신속하게 파악하거나 사용자의 활동에 따라 즉시 피드백하기 위해서는 사용자의 활동 단위로 실시간 처리가 가능해야 한다.

임의의 타이밍에 데이터를 읽는다.

링키드인은 기존 시스템에서 수집한 엑세스 로그를 일정 시간마다 배치 처리로 취급하고 싶은 요구가 있었다. 데이터를 사용하는 타이밍이 반드시 실시간이 아니라 이용 목적에 다라 다를 가능성이 있기 때문에 데이터를 전달할 때 버퍼 역할도 가능하기를 원했다.

다양한 제품과 시스템에 쉽게 연동한다.

링크드인에서는 데이터의 발생원이 되는 데이터 소스와 관련된 시스템이 하나가 아니라 여러 개였다. 또한 이용 목적에 따라 여러 인프라도 존재하고 있었다. 하둡을 사용해서 대량의 데이터를 처리하는 기존 방식은 다른 데이터 소스와 인프라에 전부 적용하기엔 현실적인 방법이 아니었다. 다른 데이터베이스나 데이터 웨어하우스 등 다른 제품과 연결으 쉽게 하고 싶다는 요구가 있었다.

메시지를 잃지 않는다.

취급하는 메시지가 방대하더라도 메시지를 잃어버리면 안 됐다. 다만, 링크드인의 목표를 위해서는 한 건 한 건의 메시지를 엄격하게 관리하기 보다는 약간의 중복이 있더라도 메시지를 잃지 않는 것이 중요했다. 건마다 엄격하게 관리하면 처리 오버헤드가 커지는 것은 이미 인식하고 있었으므로, 높은 처리량으로 실시간 처리라는 요건과 균형을 가미하여 현실적으로 제거해도 좋은 것을 찾아야 했다.


카프카 이전 제품

카프카 이전 제품은 요구를 부분적으로 충족하긴 했지만, 전부 충족하는 제품은 없었다. 데이터를 전달하거나 데이터를 로드할 때 필요한 제품에는 크게 나누어 메시지 큐, 로그 수집, ETL 도구가 있다.

메시지 큐

한 건의 레코드 단위로 실시간 처리할 때 가장 먼저 떠오르는 것은 메시지 큐이다. 메시지 큐가 요구 사항을 만족하지 못한 것은 아래와 같다.

  • 강력한 전달 보증이 오버스펙이었다.

    메시지 큐는 하나의 메시지가 정확히 한 번만 전송되는 것을 보증했다. 또한 커밋/롤백을 지원했다. 그러나 링크드인에서 다루는 로그의 성질을 고려하면 엄격한 트랜잭션 관리는 오버 스펙이며, 그보다 높은 처리량의 실현이 우선순위가 더 높은 상황이었다. 메시지는 분실하지 않은 채 송수신 보증을너무 중시한 나머지 처리량이 나오지 않는 것이 바람직하지 않다는 게 당시의 상황이었다.
  • 스케일 아웃이 용이한 제품이 아니었다.

    대량의 메시지를 처리하는 데 1대의 서버로만 대응하는 것은 한계가 있다. 그러므로 처음부터 여러 대의 서버를 사용할 것을 전제할 필요가 있었다. 메시지 큐 제품에도 클러스터 구성을 취하는 것이 있었지만 실제로는 가용성을 위한 중복 구성에 주안점을 두고 있었다. 처리 성능을 높이는 목적으로 필요 시 노드를 추가할 수 있는 스케일 아웃 기능을 전제로 한 제품이 당시에는 없었다.
  • 메시지가 대량으로 쌓이는 것을 예상하지 않았다.

    카프카 등장 이전의 메시지 큐에서는 메시지를 쌓아둘 수 있었는데, 큐에 쌓인 메시지는 즉시 이용되는 것으로 예상하고 있었지 장시간에 걸쳐 대량으로 축적하는 것을 예상하지 않았다. 링크드인에서는 실시간 처리 외에도 메시지를 배치 처리로 이용하는 것도 가정하고 있었다. 일정량의 데이터를 일정 기간마다 묶음으로 받아 데이터 웨어하우스에서 처리하기 위해서는 데이터의 축적 시간은 훨씬 길어야 했지만 기존 메시지 큐로는 감당할 수 없었다.

로그 수집 시스템

실시간으로 데이터를 수집한다는 관점에서 생각할 수 있는 것은 로그 수집을 위한 미들웨어다. 주로 웹 서버 등의 프론트엔드 서버의 로그를 수집하기 위한 것이다.
각 프론트엔드 서버가 로그를 중계용 서버에 전송하고, 거기서 로그를 수집하여 데이터베이스와 분산 파일 시스템 HDFS(Hadoop Distributed File System)에 축적한다. 원래 대량의 로그를 처리하는 것을 가정하고 있었기 때문에 분산 환경의 다중 서버 구성으로 이루어져 있었다. 그러나 링크드인에서 사용하기에는 다음과 같은 문제점이 있었다.

  • HDFS로 데이터 축적과 배치 처리만 고려했다.

    이들 제품은 대량의 로그를 HDFS에 축적하고 하둡 맵리듀스에서 일괄 처리하는 것이 주목적이다. 링크드인에서도 하둡을 사용하고 있엇지만, 동시에 데이터 웨어하우스를 이용한 데이터 분석도 실시하고 있어 모두 하둡에서 동작하도록 애플리케이션을 다시 작성하는 것은 현실적이지 않았다.
    또한 앞에서 언급했듯이 데이터는 배치 처리로만 이용할 뿐만 아니라 실시간으로도 처리하고자 하는 요구가 있었다. 따라서 HDFS는 링크드인의 목표를 달성하기엔 불충분했다.
  • 수신하는 쪽이 임의로 메시지를 수신하기 어렵다.

    기존 제품에서는 로그 수집 기반 서버에서의 push에 의해 수신자에게 메시지가 전달되는 구조였다. 그러나 링크드인에서는 다양한 활용이 필요했기 때문에 각 수신자가 자신의 속도나 처리의 빈도에 따라 수신할 수 있어야 했다.
    따라서 로그 수집 기반 서버가 그 뒤에 있는 수신 시스템의 수신 여부를 일일이 모니터링하면서 push 하는 것보다는 수신 시스템이 메시지를 갖고 가는 pull 바식이 오히려 사용하기 쉽다고 생각했다.

ETL 도구

데이터 발생원에서 데이터를 추출하고 필요에 따라 변한해 데이터베이스와 데이터 웨어하우스에 로드하는 기능을 갖추고 있는 ETL 도구가 있다. ETL 도구에서는 다음과 같은 부분이 요구 사항을 충족하지 못했다.

  • 데이터를 파일 단위로 다룬다.

    카프카 등장 이전에 대량의 데이터를 높은 처리량으로 전달하려면 데이터를 파일 단위 등으로 뭉쳐서 배치 처리로 전송하는 것이 일반적이었다. 그러나 링크드인은 한 건의 레코드 단위실시간 처리를 하고 싶다는 요구사항이 존재했다. 그래서 ETL 도구는 링크드인의 목표를 달성하기엔 불충분했다.
  • 수신하는 쪽이 메시지를 수신하기 어렵다.

    로그 수집과 동일한 논의가 ETL 도구에서도 있었다.

카프카로 링크드인 요구 사항 실현하기

링크드인의 요구사항

  • 높은 처리량으로 실시간 처리한다.
  • 임의의 타이밍에서 데이터를 읽는다.
  • 다양한 제품과 시스템에 쉽게 연동한다.
  • 메시지를 잃지 않는다.

실현 수단

  • 메시징 모델과 스케일 아웃형 아키텍처
  • 디스크로의 데이터 영속화
  • 이해하기 쉬운 API 제공
  • 전달 보증

핵심은 메시징 모델과 스케일 아웃형 아키텍처이며, 디스크로의 데이터 영속화도 중요 사항이다.

메시징 모델과 스케일 아웃

  • 높은 처리량으로 실시간 처리한다.
  • 임의의 타이밍에서 데이터를 읽는다.
  • 다양한 제품과 시스템에 쉽게 연동한다.

위와 같은 요구사항을 만족하기 위해 카프카에서는 메시징 모델을 채용했다. 일반적으로 메시징 모델은 다음 세 가지 요소로 구성된다.

  • Producer: 메시지 생산자
  • Broker: 메시지 수집/전달 역할
  • Consumer: 메시지 소비자

카프카는 큐잉 모델과 Publish/Subscribe 메시징 모델의 특징을 겸비한 형태로 만들어졌다.

큐잉 모델

브로커 안에 큐를 준비해, 프로듀서에서의 메시지가 큐에 담기고, 컨슈머가 큐에서 메시지를 추출한다. 하나의 큐에 대해 컨슈머가 여러 개 존재하는 것을 생각할 수 있다. 이 모델은 컨슈머를 여러 개 준비함으로써 컨슈머에 의한 처리를 확장시킬 수 있으며, 컨슈머가 메시지를 받으면 다른 컨슈머는 메시지를 받을 수 없다.

펍/섭 메시징 모델

이 모델에서는 메시지 생산자인 프로듀서를 퍼블리셔, 메시지 소비자의 해당 컨슈머를 서브스크라이버라고 한다.
퍼블리셔가 서브스크라이버에게 직접 메시지를 보내는 것이 아니라 브로커를 통해 전달한다. 퍼블리셔는 누가 그 메시지를 수신하는지 알 수 없고 브로커에 있는 토픽이라고 불리는 카테고리 안에 메시지를 등록한다.
한편 서브스크라이버는 여러 개 존재하는 토픽 중 하나를 선택하여 메시지를 받는다. 어러 서브스크라입가 동일한 토픽을 구독하기로 결정한다면, 이 여러 서브스크라이버는 동일한 메시지를 받는다 또한 다른 토픽에서는 다른 메시지를 받을 수 있다.
펍/섭 메시징 모델은 TV나 라디오 전파 수신을 상상하면 이해하기 쉽다 TV 방송국과 라디오 방송국은 개별 가정에서 누가 수신하고 있는지 고려하지 않고 방송 전파를 발신하며, 각 가정은 자신이 보고 싶은 프로그램만 선택하여 방송을 수신한다.
1개의 토픽에 주목한 경우를 큐잉 모델과 비교하면 여럿이 존재하는 모든 서브스크라이버는 동일한 메시지를 받게 된다. 병렬로 동작하는 복수의 서브스크라이버에게 전달할 수 있다는 장점이 있지만, 동일한 메시지에 대한 처리이기 때문에 브로커의 토픽에 축적되는 메시지 그룹 입장에서 보면 처리 능력을 높이는 효과는 없다. 따라서 큐잉 모델과 펍/섭 메시징 모델은 장점과 단점이 공존한다.

카프카 메시징 모델

높은 처리량을 실현하기 위해서는 어떻게 확장성 있는 구성을 할 수 있을지가 관건이었다.
따라서 카프카에서는 큐잉 모델에서 실현한 여러 컨슈머가 분산 처리로 메시지를 소비하는 모델과 펍/섭 메시징 모델에서 실현한 여러 서브스크라이버에 동일한 메시지를 전달하고, 토픽 기반으로 전달 내용을 변경하는 모델로 되어있다. 이 모델을 실현하기 위해 컨슈머 그룹이라는 개념을 도입하여 컨슈머를 확장 구성할 수 있도록 설계하고 있다.
여러 컨슈머가 동일 토픽을 분산하여 메시지를 읽음으로써 처리의 확장성을 담보한다. 브로커가 1대라면 병목이 발생하거나, 장기간에 걸쳐 임의의 타이밍에 데이터를 읽도록 하려면 1대만으로는 야이 부족할 수 있다. 그래서 브로커도 복수 구성으로 동작하도록 되었으며, 결가적으로는 전체적으로 확장 구성을 하고 있는 것이다.

디스크로의 데이터 영속화

  • 다양한 제품과 시스템에 쉽게 연동한다.
  • 메시지를 잃지 않는다.

위의 두 가지 요구를 만족하기 위해 카프카는 브로커에 보낸 메시지를 디스크에 영속화하고 있다.
메시지 큐에서도 데이터 영속화를 실시하는 제품도 있지만 실시간 접속에만 중점을 두고 있는 경우가 많으며 기본적으로 장기 보존을 가정하지 않는다. 배치 처리의 경우 데이터를 일정 기간마다 모아야 할 필요가 있기 때문에 데이터를 메모리에서만 유지하는 것은 용량 면에서 불가능하다. 따라서 카프카의 메시지 영속화는 디스크에서 이루어진다. 카프카는 디스크에 영속화함에도 불고하고 높은 처리량을 제공한다는 특징이 있다.
또한 들어오는 데이터를 받아들이면서 한 묶음으로 장기 보존을 목적으로 영속화할 수 있기 때문에 카프카를 스토리지 시스템으로도 간주할 수 있다.

이해하기 쉬운 API 제공

  • 다양한 제품과 시스템에 쉽게 연동한다.

위의 요구사항을 만족하기 위해 카프카에서 프로듀서와 컨슈머를 쉽게 접속할 수 있도록 Connect API를 제공한다. 각각 이 API를 이용하여 각종 외부 시스템과 접속한다. 또한 API를 기반으로 카프카에 접속하기 위한 프레임워크로 Kafka Connect도 제공한다.

전달 보증

  • 메시지를 잃지 않는다.

카프카에서는 At Most Once, At Least Once, Exactly Once 세 가지 수준으로 전달을 보증한다.

종류개요재전송 유무중복 삭제 유뮤비고
At Most Once1회는 전달을 시도해본다.XX메시지는 중복되지 않지만 상실될 수도 있다.
At Least Once적어도 1회는 전달한다.OX메시지는 중복될 가능성은 있지만, 상실되지는 않는다.
Exactly Once1회만 전달한다.OO중복되거나 상실되지도 않고 확실하게 미시지가 도달하지만, 성능이 나오기 힘들다.

메시지 큐에서는 Exactly Once 수준을 주목적으로 하는 경우가 많다. 따라서 트랜잭션 관리를 위한 메커니즘이 마련돼 있다. 그러나 카프카 개발 초기에는 높은 처리량을 구현해야 했기 때문에 Exactly Once 수준의 보증은 미루고 최소한 메시지 분실 방지를 위한 At Least Once 수준으로 전달을 보증했다.
At Least Once를 실현하기 위해 Ack와 오프셋 커밋이라는 개념을 도입하고 있다.(네트워크 이론에서의 개념과 비슷해서 따로 정리 안하겠다.)

Exactly Once 실현

카프카의 유용성이 높아지면서 Exactly Once 수준의 전달을 보증하고자 하는 요구가 높아졌다. 그러다보니 카프카에 트랜잭션 개념을 도입하여 전달을 보증한다.
Exactly Once 수준에서는 구체적으로 쌍방간의 실현이 모두 필요하다. 첫 번째는 프로듀서와 브로커의 상호 교환 사이에서, 그리고 두 번째는 브로커와 컨슈머의 상호 교환 사이에서 필요하다. 프로듀서와 브로커의 상호 교환 사이를 살펴보면 양쪽 모두에서 시퀀스 번호를 관리해 중복되는 실행을 제거하는 방법을 사용한다. 한편, 브로커와 컨슈머 간 교환에 있어서는 컨슈머에 대해 트랜잭션의 범위를 해석하고, 트랜잭션 중단 시 중단까지의 처리를 파기하는 기능이 있다. Exactly Once 수준의 전달을 보증하려면 카프카뿐만 아니라 프로듀서에 해당하는 상위 시스템과 컨슈머에 해당하는 하위 시스템에도 상태 관리가 요구된다. 즉, 카프카 단독으로는 전달 보증을 실현하기 어렵다. 하지만 적어도 카프카는 트랜잭션 관리 메커니즘을 갖추고 있기 때문에 상위와 하위 시스템 사이에서 필요로 하는 상태 관리를 위한 조건이 갖추어지면 전달은 보증된다.

profile
백엔드

0개의 댓글