본문 바로가기

TIL(Today I Learned)

Apache Kafka란 무엇일까?

📌  Apache Kafka

빠르고 확장 가능한 작업을 위해 데이터 피드의 분산 스트리밍, 파이프 라이닝 미 재생을 위한 실시간 스트리밍 데이터를 처리하기 위한 목적으로 설계된 오픈 소스 분산형 Pub-Sub 구독 메시징 플랫폼(LinkedIn에서 개발)

 

📍 기존 데이터 시스템

시스템 복잡도 증가

  • 통합된 전송 영역이 없어 데이터 흐름을 파악하기 어렵고, 시스템 관리가 어렵다.
  • 특정 부분에서 장애 발생 시 조치 시간이 증가한다. -> 연결 되어있는 애플리케이션들을 모두 확인해야 하기 때문
  • HW 교체 / SW 업그레이드 시 관리포인트가 늘어나고, 작업시간이 증가한다. -> 연결된 애플리케이션에 side effect가 없는지 확인해야 한다.

데이터 파이프라인 관리의 어려움

  • 각 애플리케이션과 데이터 시스템 간의 별도의 파이프라인이 존재하고, 파이프라인 마다 데이터 포맷과 처리방식이 다르다.
  • 새로운 파이프라인 확장이 어려워지면서, 확장성 및 유연성이 떨어진다.
  • 또한 데이터 불일치 가능성이 있어 신뢰도가 감소한다.
💡 이러한 이유로 모든 이벤트/데이터의 흐름을 중앙에서 관리하는 카프카를 개발하게 되었다.

카프카 적용 후
 - 모든 이벤트/데이터의 흐름을 중앙에서 관리할 수 있게 됨
 - 새로운 서비스/시스템이 추가되도 카프카가 제공하는 표준 포맷으로 연결하면 되므로 확장성과 신뢰성이 증가
 - 개발자는 각 서비스간의 연결이 아닌, 서비스들의 비즈니스 로직에 집중 가능

 

📍 메세지 큐 (Message Queue, MQ)

  • 메시지 지향 미들웨어(MOM : Message Oriented Middleware)를 구현한 시스템으로 프로그램(프로세스) 간의 데이터를 교환할 때 사용하는 기술
  • MQ에서 메시지는 Endpoint 간에 직접적으로 통신하지 않고, 중간에 Queue를 통해 중개된다

 

장점

1. 비동기 : queue라는 임시 저장소가 있기 때문에 나중에 처리 가능

2. 낮은 결합도 : 애플리케이션과 분리

3. 확장성 : producer or consumer 서비스를 원하는대로 확장할 수 있음

4. 탄력성 : consumer 서비스가 다운되더라도 애플리케이션이 중단되는 것은 아니며 메시지는 지속하여 MQ에 남아있다.

5. 보장성 :

  • MQ에 들어간다면 결국 모든 메시지가 consumer 서비스에게 전달된다는 보장을 제공한다.
  • 대용량의 실시간 로그 처리에 특화되어 TPS가 우수하다.
  • 분산 처리에 효과적으로 설계되어 병렬처리와 확장(Scale Out), 고가용성(HA) 용이

 6. Pub-Sub 모델

   

  • 메시지를 받기를 원하는 consumer가 해당 topic을 구독함으로써 메시지를 읽어오는 구조
  • 기존에 publisher나 broker 중심적인 브로커 메시지와 달리 똑똑한 consumer 중심
  • broker의 역할이 줄어들기 때문에 좋은 성능을 기대할 수 있다.
  • pub/sub 모델은 비동기 메시징 전송 방식으로, 발신자의 메시지에는 수신자가 정해져 있지 않은 상태로 publish한다.그리고 이를 subscribe을 한 수신자만 정해진 메시지(topic)을 받을 수 있다. 이처럼 수신자는 발신자 정보가 없어도 원하는 메시지만 수신할 수 있으며, 이런 구조 덕분에 높은 확장성을 확보할 수 있다.
    Kafka, Redis, RabbitMQ 등이 있다.

 7. 파일 시스템에 메시지를 저장함으로써 영속성이 보장

  • 장애시 데이터 유실 복구 가능
  • 메시지가 많이 쌓여도 성능이 크게 저하되지 않는다.
  • 대규모 처리를 위한 batch 작업이 용이하다.

 

📍 메시지 브로커 / 이벤트 브로커

✔ 메시지 브로커

  • publisher가 생산한 메시지를 메시지 큐에 저장하고, 저장된 데이터를 consumer가 가져갈 수 있도록 중간 다리 역할을 해주는 브로커라고 볼 수 있다.
  • 보통 서로 다른 시스템(혹은 소프트웨어) 사이에서 데이터를 비동기 형태로 처리하기 위해 사용한다.(대규모 엔터프라이즈 환경의 미들웨어로서의 기능)
  • 이러한 구조를 보통 pub/sub 구조라고 하며 대표적으로는 Redis, RabbitMQ 소프트웨어가 있고, GCP의 pubsub, AWS의 SQS 같은 서비스가 있다.
  • 이와 같은 메시지 브로커들은 consumer가 큐에서 데이터를 가져가게 되면 즉시 혹은 짧은 시간 내에 큐에서 데이터가 삭제되는 특징들이 있다.

 

이벤트 브로커

  • 이벤트 브로커 또한 기본적으로 메시지 브로커의 큐 기능들을 가지고 있어 메시지 브로커의 역할도 할 수 있다.
  • 메시지 브로커와의 가장 큰 차이점은, 이벤트 브로커는 publisher가 생산한 이벤트를 이벤트 처리 후에 바로 삭제하지 않고 저장하여, 이벤트 시점이 저장되어 있어서 consumer가 특정 시점부터 이벤트를 다시 consume할 수 있는 장점이 있다.(예를 들어 장애가 일어난 시점부터 그 이후의 이벤트를 다시 처리할 수 있음.)
  • 또한 대용량 처리에 있어서는 메시지 브로커보다는 더 많은 양의 데이터를 처리할 수 있는 능력이 있다.
  • 이벤트 브로커에는 Kafka, AWS의 kinesis 같은 서비스가 있다.

 

📍 Kafka의 동작 방식 및 특징

  구성요소 / 용어 정리

1. Producer :

  • 메시지(이벤트)를 발행하여 생산(write)하는 주체
  • 메시지를 만들어서 카프카 클러스터에 전송한다.
  • 메시지 전송 시 Batch 처리가 가능하다.
  • 메시지 전송 시 topic을 지정한다.
  • key 값을 지정하여 특정 파티션으로만 전송이 가능하다.
  • 전송 acks값을 설정하여 효율성을 높일 수 있다.
  • ACKS=0 -> 매우 빠르게 전송. 파티션 리더가 받았는지 알 수 없다.
  • ACKS=1 -> 파티션 리더가 받았는지 확인. 기본값
  • ACKS=All -> 파티션 리더 뿐만 아니라 팔로워까지 메시지를 받았는지 확인

2. Consumer : 

  • 메시지(이벤트)를 구독하여 소비(read)하는 주체
  • 카프카 클러스터에서 메시지를 읽어서 처리한다.
  • 메시지를 Batch 처리할 수 있다.
  • 한개의 consumer는 여러개의 topic을 처리할 수 있다.
  • 메시지를 소비하여도 메시지를 삭제하지는 않는다. (Kafka delete policy에 의해 삭제)
    한번 저장된 메시지를 여러본 소비도 가능한다.
  • consumer는 consumer group에 속한다.
  • 한개 파티션은 같은 consumer group의 여러 개의 consumer에서 연결할 수 없다.

3. Queue : producer의 데이터를 임시 저장 및 consumer에 제공하는 곳

4. KafkaCluster : 카프카의 broker들의 모임. Kafka는 확장성과 고가용성을 위하여 broker들이 클러스터로 구성

5. Broker :

  • 각각의 카프카 서버, 동일 노드에 여러 브로커를 띄울 수 있다.
  • 실행된 카프카 서버를 말한다.
  • producer와 consumer는 별도의 애플리케이션으로 구성되는 반면, broker는 kafka 자체이다.
  • Broker는 Kafka Cluster 내부에 존재한다.
  • 서버 내부에 메시지를 저장하고 관리하는 역할을 수행한다.

6. Event : kafka에서 producer와 consumer가 데이터를 주고받는 단위. 메시지 또는 이벤트라고 한다.

카프카에 저장되는 메시지는 topic으로 분류, topic은 여러개의 partition으로 나뉘어짐.

 

7. Topic :

  • 이벤트가 모이는 곳. producer는 topic에 이벤트를 게시하고, consumer는 topic을 구독해 이로부터 이벤트를 가져와 처리한다.
  • topic은 파일시스템의 폴더와 유사하며, 이벤트는 폴더안의 파일과 유사하다.
  • topic에 저장된 이벤트는 필요한 만큼 다시 읽을 수 있다.
  • 각각의 메시지를 목적에 맞게 구분할 때 사용한다.
  • 메시지를 전송하거나 소비할 때 Topic을 반드시 입력한다.
  • Consumer는 자신이 담당하는 Topic의 메시지를 처리한다.

8. Partition :

  • Topic은 여러 broker에 분산되어 저장되며, 이렇게 분산된 topic을 partition이라고 한다.
  • 어떤 이벤트가 partition에 저장될지는 이벤트의 key에 의해 정해지며, 같은 key를 가지는 이벤트는 항상 같은 partition에 저장된다.
  • 한개의 토픽은 한 개 이상의 파티션으로 구성된다.
  • kafka는 topic의 partition에 저장된 consumer가 항상 정확히 동일한 순서로 partition의 이벤트로 읽을 것을 보장한다.
  • Topic 생성 시 partition 개수를 지정할 수 있다. (파티션 갯수 변경 가능.) 파티션은 메시지 추가만 가능한 파일이다(append-only).
  • 파티션이 1개라면 모든 메시지에 대해 순서가 보장된다.
  • 파티션 내부에서 각 메시지는 offset(고유 번호)로 구분된다.
  • 파티션이 여러개라면 Kafka 클러스터가 라운드 로빈 방식으로 분배해서 분산처리되기 때문에 순서보장이 되지 않는다.
  • 파티션이 많을수록 처리량이 좋지만 장애 복구 시간이 늘어난다.

9. Zookeeper :

  • 카프카 클러스터 정보 및 분산처리 관리 등 메타데이터 저장. 카프카를 띄우기 위해 반드시 실행되어야 한다.
  • 분산 애플리케이션 관리를 위한 코디네이션 시스템
  • 분산 메시지 큐의 메타 정보를 중앙에서 관리하는 역할

 

10. Offset :

  • consumer에서 메시지를 어디까지 읽었는지 저장하는 값. 파티션 내 각 메시지의 저장된 상대적 위치
  • 프로듀서가 넣은 메시지는 파티션의 맨 뒤에 추가(Queue)
  • consumer는 offset 기준으로 마지막 commit 시점부터 메시지를 순서대로 읽어서 처리한다.
  • 파티션의 메시지 파일은 처리 후에도 계속 저장되어 있으며 설정에 따라 일정시간 뒤에 삭제된다.
  • consumer group의 consumer들은 각각의 파티션에 자신이 가져간 메시지의 위치 정보(offset)을 기록
  • consumer 장애 발생 후 다시 살아나도, 전에 마지막으로 읽었던 위치에서부터 다시 읽어들일 수 있다.

 

 동작 원리

1. publisher는 전달하고자 하는 메시지를 topic을 통해 카테고리화 한다.

2. subscriber는 원하는 topic을 구독함으로써 메시지를 읽어온다.

3. publisher와 subscriber는 오로지 topic 정보만 알 뿐, 서로에 대해 알지 못한다.

4. kafka는 broker들이 하나의 클러스터로 구성되어 동작하도록 설계

5. 클러스터 내, broker에 대한 분산처리는 Zookeeper가 담당한다.

 

  장점 

  • 대규모 트래픽 처리 및 분산 처리에 효과적이다.
  • 클러스터 구성, Fail-Over, Replication 같은 기능이 있다.
  • 100Kb/sec 정도의 속도 (다른 메시지 큐보다 빠름)
  • 디스크에 메시지를 특정 보관 주기동안 저장하여 데이터의 영속성이 보장되고 유실 위험이 적다. 또한 Consumer 장애 시 재처리가 가능하다.

📍 하나의 topic을 여러개의 partition으로 분산시키는 이유

  • 병렬로 처리하기 위해 분산 저장한다.
  • 카프카의 토픽에 메시지가 쓰여지는 것도 어느정도 시간이 소비된다. 몇 천건의 메시지가 동시에 카프카에 write되면 병목현상이 발생할 수 있다.
  • 따라서 파티션을 여러개 두어서 분산 저장함으로써 write 동작을 병렬로 처리할 수 있다.
  • 다만, 한번 늘린 파티션은 절대 줄일 수 없기 때문에 운영 중에, 파티션을 늘려야 하는건 충분히 검토 후 실행되어야 한다.(최소한의 파티션으로 운영하고 사용량에 따라 늘리는 것을 권장한다.)
  • 파티션을 늘렸을 때 메시지는 Round-Robin 방식으로 쓰여진다. 따라서 하나의 파티션 내에서는 메시지 순서가 보장되지만, 파티션이 여러개일 경우에는 순서가 보장되지 않는다.

 

📍 Consumer Group 존재 이유

  • consumer의 묶음을 consumer group이라고 한다.
  • consumer group은 하나의 topic에 대한 책임을 갖고 있다.
  • 즉, 어떤 consumer가 down된다면, 파티션 재조정(rebalancing)을 통해 다른 consumer가 해당 파티션의 sub을 맡아서 한다. offset 정보를 그룹간에 공유하고 있기 때문에 down되기 전 마지막으로 읽었던 메시지 위치부터 시작한다.
  • consumer를 확장할 때는, partition도 같이 늘려주어야 한다.

📍 Push와 Pull 모델

kafka의 consumer는 pull 모델을 기반으로 메시지 처리를 진행한다. 즉, broker가 consumer에게 메시지를 전달하는 것이 아닌, consumer가 필요할 때, broker로부터 메시지를 가져와 처리하는 형태이다.

장점 :

1. 다양한 소비자의 처리 형태와 속도를 고려하지 않아도 된다.

2. 불필요한 지연없이 일괄처리를 통해 성능향상을 도모한다.

 

📍 Commit과 Offset

메시징 시스템은 broker에서 소비된 메시지에 대한 메타데이터를 유지한다. 즉, 메시지가 consumer에게 전달되면 broker는 이를 로컬에 기록하거나, 소비자의 승인을 기다린다.

 

📍 메시지(이벤트) 전달 컨셉

1. At most once(최대 한번)

메시지가 손실 될 수 있지만, 재전달은 하지 않는다.

2. At least once(최소 한번)

메시지가 손실되지 않지만, 재전달이 일어난다.

3. Exactly once(정확히 한번)

메시지는 정확히 한번 전달이 된다.

 

 

 

 

 

 

 

 

 

 

References :

https://velog.io/@holicme7/Apache-Kafka-%EC%B9%B4%ED%94%84%EC%B9%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80

https://galid1.tistory.com/793

https://ifuwanna.tistory.com/487

https://www.tibco.com/ko/reference-center/what-is-apache-kafka

https://www.ibm.com/kr-ko/topics/apache-kafka

https://aws.amazon.com/ko/what-is/apache-kafka/