본문 바로가기
Kafka

[Kafka] 카프카란 무엇인가

by yonikim 2023. 12. 7.
728x90

 

 

카프카는(Kafka) 는 파이프라인, 스트리밍 분석, 데이터 통합 및 미션 크리티컬 애플리케이션을 위해 설계된 오픈소스 분산 이벤트 스트리밍 플랫폼이다. 

 

카프카는 2011년 미국 링크드인(Linkedin) 에서 개발했는데, 카프카 개발 전의 링크드인 데이터 처리 시스템을 보자.

 

 

한눈에 보기에도 복잡해보인다. 각 파이프라인이 파편화되어 있고, 시스템 복잡도가 높아서 새로운 시스템을 확장하기 어려웠다. 

이로 인해 새로운 시스템의 개발 필요성이 높아졌고, 아래와 같은 목표를 가지고 새로운 시스템을 개발하게 된다. 

  • 프로듀서와 컨슈머의 분리
  • 메시징 시스템과 같이 영구 메시지 데이터를 여러 컨슈머에게 적용 
  • 높은 처리량을 위한 메시지 최적화 
  • 트래픽 증가에 따른 스케일아웃이 가능한 시스템

 

 

카프카를 적용한 후 링크드인의 데이터 처리 시스템이다. 한 눈에 보기에도 훨씬 간결해진 것을 알 수 있다.

카프카를 적용함으로써 모든 이벤트/데이터의 흐름을 중앙에서 관리할 수 있게 된 것이다.

 

 


카프카의 특징


1. 높은 처리량으로 실시간 처리 

  • 다양한 액세스 데이터를 처리해야 하기 때문에 처리량이 우수해야 한다.
  • 사용자의 활동을 신속하게 파악하거나 사용자의 활동에 따라 즉시 피드백하기 위해서이다.
  • 실시간 처리는 수집부터 시작해 수백 밀리초에서 수 초 안에 데이터가 처리돼야 한다.

2. 임의의 타이밍에서 데이터를 읽음

  • 실시간이 아니어도 배치 처리를 할 수 있어야 한다. 

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

  • 데이터베이스나 데이터웨어하우스 등 다르제품과의 연결이 쉬워야 한다. 

4. 메시지를 잃지 않아야 함

  • 약간의 중복이 있더라도 데이터를 잃지 않는 것이 중요하다. (건마다 엄격하게 관리하면 처리 오버헤드가 커진다.)
  • 높은 처리량으로 실시간 처리라는 요건과의 균형을 가미해야 한다.

 

 


카프카의 구성요소 


 

 

일반적인 메시징 모델의 구성요소는 다음과 같다.

1. Producer: 메시지 생산자

2. Broker: 메시지 수집/전달 역할

3. Consumer: 메시지 소비자

일반적인 메시징 모델의 구성요소

 

 

 

 

카프카는 Message Queing Model 과 Pub/Sub Model 의 특징을 겸비했다. 

Queing 모델에서 여러 컨슈머가 분산 처리로 메시지를 소비하는 모델을 가져왔고, 

Pub/Sub 모델에서 여러 subscriber 들에게 동일한 메시지를 전달하고 토픽 기반으로 전달 내용을 변경하는 모델을 가져왔다.

 

카프카의 구성요소

 

1. 브로커(Broker)

  • 브로커는 메시지를 수신하고 전달하는 역할을 한다.
  • 여러 대의 클러스터로 구성할 수 있으며 브로커를 추가함으로써 수신/전달의 처리량 향상, 스케일아웃이 가능하다. 
  • 브로커에서 받은 데이터는 모두 디스크로 내보내지기 때문에, 디스크의 용량에 따라 장기간 보존할 수 있다.

2. 파티션(Prtition)

  • 토픽에 대한 대량의 메시지 입출력을 지원하기 위해, 브로커 상의 데이터를 읽고 쓰는 것을 파티션이라는 단위로 분할한다.
  • 토픽을 구성하는 파티션은 브로커 클러스터 안에 분산 배치되며, 프로듀서로부터 메시지 수신, 컨슈머에게 메시지 전달을 분산 실시함으로써, 하나의 토픽에 대한 대규모 데이터 수신과 전달을 지원하게 된다.
☞ 적정 파티션 수?
구성 및 요구사항에 따라 다르기 때문에 시스템을 설계할 때 잘 고려해야 하는데,
메시지 처리 속도, 컨슈머 그룹 내 컨슈머 개수, 컨슈머 내 스레드 수 등을 동시에 고려해야 한다.
파티션 수는 증가할 수 있지만, 한 번 증가한 파티션 수는 다시 줄일 수 없다. 

 

3. 프로듀셔(Producer)

  • 프로듀서는 프로듀서 API를 이용하여 브로커에 데이터를 송신하기 위해 구현된 애플리케이션이다. 
  • 토픽의 파티션에 메시지를 송신할 때, 버퍼 기능처럼 프로듀서의 메모리를 이용하여 일정량을 축적 후 송신한다. 
  • 데이터의 송신은 1) 지정한 크기까지 메시지가 축적되거나(batch.size) 2) 지정한 대기 시간에 도달하는 것(linger.ms) 중 하나를 트리거로 전송한다.
☞ 메시지 전송시 파티셔닝
1. Key 의 해시값을 사용한 송신
- 메시지는 Key 와 Value 로 이뤄져 있는데, Key 를 이용하여 송신처 파티션을 결정한다.
- 동일한 Key 를 가진 메시지는 동일한 ID 를 가진 파티션에 송신된다.
- partitionKey 를 이용하면 메시지 순서 보장은 가능하나, 대신 imbalance 를 챙겨야 한다.
2. 라운드로빈에 의한 송신 
- 메시지 Key 를 지정하지 않고 Null 로 한 경우, 라운드로빈 방식에 의해 여러 파티션으로 메시지를 송신한다.

 

 

3. 컨슈머(Consumer)

  • 컨슈머는 컨슈머 API를 이용하여 브로커에게 메시지를 전달받도록 구현된 애플리케이션이다. 

4. 컨슈머 그룹(Consumer Group) 

  • 컨슈머가 카프카 클러스터에서 메시지를 얻어 처리할 때, 컨슈머는 컨슈머 그룹 이라 불리우는 하나 이상의 컨슈머들로 이루어진 그룹을 형성하여 메시지를 얻는다. 
  • 컨슈머 그룹은 Group ID 로 구분된다. 
  • 메시지를 컨슈터 그룹의 어느 컨슈머가 수신하는가에 대한 할당은 수신할 토픽에 존재하는 파티션과 그룹 내 컨슈머를 매핑함으로써 가능하다. 컨슈머와 파티션의 매핑은 각 파티션에 반드시 하나의 컨슈머에 매핑된다. 
  • 반대로 파티션 수에 따라 하나의 컨슈머에 여러 파티션이 할당되는 경우도 있다. 
  • 컨슈머 그룹에서 기대한 대로 분산하여 메시지를 수신하기 위해서는 파티션 수가 적어도 컨슈머 그룹에 속하는 컨슈머보다 많아야 한다.  토픽의 파티션보다 컨슈머가 많을 경우 파티션이 할당되지 않은 (놀게 되는) 컨슈머가 발생할 수 있다. 

 

5. 오프셋(Offset)

 

  • 각 파티션에서 수신한 메시지에는 각각 일련번호가 부여된다. 이를 오프셋이라고 한다.
  • 즉 오프셋이란 파티션 단위로 메시지 위치를 나타내는 정보로, 컨슈머가 취득하는 메시지의 범위 및 재시도를 제어한다. 

6. 오프셋 커밋(Offset Commit)

  • 컨슈머는 어느 메시지까지 처리를 완료했는지 카프카 클러스터에 기록을 남길 수 있다. 정확하게 말하면 다음 수신 및 처리해야 할 메시지의 오프셋 기록 이다.
  • 오프셋 커밋의 기록은 컨슈머 그룹 단위로 이뤄진다. 컨슈머 그룹마다 각 토픽의 파티션에서 어느 오프셋까지 처리 완료했는지 정보를 기록한다.
  • 오프셋 커밋은 처리 완료 여부를 메시지마다 기록하는게 아니라 처리를 완료한 메시지 중에서 최대의 오프셋을 기록하는 형태로 이뤄진다. 이는 카프카가 임의의 메시지를 처리하는 것이 아니라 파티션 안의 메시지를 연속적으로 처리하는 것을 가정하고 있기 때문이다.
  • 중간에 메시지가 처리되지 않을 경우 무한 루프가 돌 수 있다. (수기로 메시지 커밋하는 경우)
  자동 Offset Commit  수동 Offset Commit 
장점 컨슈머는 오프셋 커밋을 명시적으로 실시할 필요가 없다.  해당 메시지 처리는 반드시 완료되어 있기 때문에 메시지 손실이 발생하지 않는다.
컨슈머 장애 발생시 메시지 중복을 최소화할 수 있다.
단점 컨슈머 장애가 발생했을 때 메시지가 손실되거나 메시지 중복이 발생할 수 있다. 메시지 양에 따르지만, 수동 오프셋 커밋이 자주 커밋 처리를 하므로 카프카 클러스터 부하가 높아질 수 있다.

 

 


더 나아가기

레플리카(Replica)

 

카프카는 메시지를 중계함과 동시에 서버가 고장났을 때 수신한 메시지를 잃지 않기 위해 복제구조를 갖추고 있다. 

레플리카 중 하나는 Leader 이며, 나머지는 Follower 라고 불린다. 

Follower 는 그 이름대로 Leader 로부터 메시지를 계속적으로 취득하여 복제를 유지하도록 동작한다.

다만 프로듀서/컨슈머와의 데이터 교환은 Leader 가 맡고 있다.

 

Leader Replica 의 복제 상태를 유지하고 있는 레플리카는 In-Sync Replica(ISR) 로 분류된다. 또한 복제 수와는 독립적으로 최소 ISR 수(min.insync.replicas) 설정이 가능하다.

고장 등으로 인한 일시적인 동기 지연을 허용하여 전체 읽고 쓰기를 계속하는 것이 가능하다.

 

복제 사용 시 오프셋 관리에는 LEO(Log End Offset) 이외의 High Watermark 라는 개념이 있다.

High Watermark 는 복제가 완료된 오프셋이며, 그 성질에는 반드시 LEO 와 동일하거나 오래된 오프셋을 나타낸다. 

컨슈머는 High Watermark 까지 기록된 메시지를 취득할 수 있다. 

 

 

Ack

복제에 대한 중요한 구성 요소로 프로듀서의 메시지 송신 시 Ack 설정에 대해 알아보자.

브로커에서 프로듀서로 메시지가 송신된 것을 나타내는 Ack 를 어느 타이밍에 송신할 것인지를 제어하는 것은 성능과 내장애성(브로커 서버 고장 시 데이터 분실 방지)에 큰 영향을 준다. 

Ack 설정 설명
0 프로듀서는 메시지 송신 시 Ack 를 기다리지 않고 다음 메시지를 송신함
1 Leader Replica 에 메시지가 전달되면 Ack 를 반환
All 모든 ISR 의 수만큼 복제되면 Ack 를 반환

 

프로듀서는 타임아웃 설정으로 Ack 가 돌아오지 않고 타임아웃된 Send 처리를 '송신 실패' 로 감지한다.

참고로 Ack 를 1 또는 All 로 설정했을 경우 타이밍이 의미하는 것은 각 복제에 '메시지가 전달'된 것으로 판단해 Ack 를 반환하는 타이밍이다. 이 타이밍에는 메시지가 디스크에 flush되는 것이 아니라 메모리(OS 버퍼)에 기록된다. 디스크에 flush 하는 영속화 타이밍은 다른 속성에서 제어한다.

 

ISR(In-Sync-Replicas)

Leader 파티션, Follower 파티션의 오프셋이 일치하여 싱크가 맞음을 뜻한다.

복제가 완료되지 않은 상태에서 Leader 파티션이 장애가 발생하게 되면 Follower 가 승급했을 때 데이터 유실이 일어날 수 있다.

 

 

 

 

 

 References

https://jaehoney.tistory.com/197

https://baek.dev/post/20/

728x90

'Kafka' 카테고리의 다른 글

[Kafka] docker compose 로 kafka 띄우기  (0) 2024.01.08