[Kafka] Kafka Definition

Sunwu Park·2024년 9월 18일
0

MessageQueue

목록 보기
1/4

목차

  • Kafka Topics
  • Producer and Message Key
  • Consumers
  • Consumer Groups
  • Kafka Brokers
  • Topic Replication
  • Producer Acknowledgements
  • Zookeeper
  • KRaft

1. Kafka Topics

Kafka는 데이터 스트리밍 플랫폼으로, 데이터베이스의 테이블과 유사한 "토픽(topics)" 개념을 사용하여 특정한 데이터 스트림을 다룹니다.
토픽은 이름으로 식별되며, 메시지는 다양한 형식으로 전송될 수 있습니다.
=> 이 메시지들의 순서는 하나의 연속된 데이터 흐름, 즉 "데이터 스트림(data stream)"이라고 부릅니다.
하지만 Kafka에서는 이 토픽을 쿼리할 수는 없고, 대신 "컨슈머(consumers)"를 통해 데이터를 읽어야 합니다.

파티션(Partitions)과 오프셋(Offsets)

Kafka의 토픽은 여러 "파티션"으로 나뉘어져 있으며, 각 파티션 내의 메시지들은 순차적으로 정렬되어 있습니다. 이때 각 메시지는 "오프셋(offset)"이라고 불리는 고유한 식별 번호를 가지며, 이는 파티션 내에서만 의미를 가집니다. 예를 들어, 파티션 0의 오프셋 3과 파티션 1의 오프셋 3은 서로 다른 데이터를 나타냅니다.

오프셋은 메시지가 삭제된 경우에도 재사용되지 않으며, 파티션 내에서만 순서가 보장됩니다. 즉, 여러 파티션 간의 메시지 순서는 보장되지 않습니다. 기본적으로 Kafka는 데이터를 특정 파티션에 무작위로 할당하지만, 키(key)를 제공하면 이를 기준으로 파티션에 할당할 수 있습니다.

Kafka의 불변성(immutability)

Kafka의 중요한 특징 중 하나는 "불변성"입니다. 한 번 파티션에 기록된 데이터는 변경할 수 없다는 점입니다. 이는 데이터 무결성을 유지하고, 신뢰성 있는 데이터 스트림을 제공하는 데 중요한 역할을 합니다.

데이터 보존 기간

Kafka에서 데이터는 영구적으로 저장되지 않으며, 기본적으로 1주일 동안만 유지됩니다. 이 보존 기간은 설정을 통해 조정할 수 있습니다. 이 때문에 Kafka는 실시간 데이터 처리가 필요한 시스템에서 많이 사용됩니다. 데이터가 일시적으로만 저장되므로, 컨슈머는 데이터를 빠르게 읽고 처리해야 합니다.

트럭 GPS 예시

예를 들어, "truck_gps"라는 토픽이 있다고 가정해봅시다. 이 토픽은 특정 트럭의 GPS 위치 데이터를 Kafka로 전송하는데 사용됩니다. 트럭의 ID와 위치 정보가 포함된 메시지가 Kafka로 전송되면, "truck_gps"라는 토픽에 기록됩니다. 이 토픽은 10개의 파티션으로 나뉘어져 있을 수 있습니다. 이때, 각 트럭의 GPS 위치 정보는 특정 파티션에 기록되며, 해당 파티션 내에서만 순서가 보장됩니다.

결론

Kafka의 데이터 스트리밍 구조는 매우 유연하고 확장성이 높습니다. 불변성 원칙과 파티션, 오프셋 개념을 통해 데이터 처리와 순서를 관리하며, 이로 인해 대규모 실시간 데이터 처리가 필요한 시스템에서 효과적으로 활용될 수 있습니다. 데이터는 설정된 기간 동안만 보존되므로, 컨슈머는 데이터를 빠르게 처리하고 활용해야 합니다. Kafka는 실시간 데이터 처리, 로그 수집, 트랜잭션 처리 등 다양한 분야에서 사용되며, 특히 대용량 데이터를 효율적으로 다루기 위해 설계된 강력한 도구입니다.

2. Producer and Message Key

Kafka에서 데이터는 Producer를 통해 특정 토픽(Topics)에 전송되며, 이 토픽들은 여러 파티션(Partitions)으로 나뉩니다. Kafka의 Producer가 데이터를 어떻게 관리하고, Message Key를 사용하는 방법, 그리고 메시지 직렬화가 어떻게 이루어지는지를 자세히 설명하겠습니다.

Producer와 Kafka 파티션

Kafka의 Producer는 데이터를 직접 토픽에 기록하는 역할을 합니다. 여기서 중요한 점은, 토픽이 단일 저장소가 아니라 여러 개의 파티션(Partitions)으로 나뉘어 있다는 것입니다. 각각의 파티션은 독립적으로 동작하며, Kafka는 이러한 파티션을 통해 대규모 데이터를 병렬로 처리할 수 있습니다.

위 그림에서 볼 수 있듯이, Producer는 어떤 파티션에 데이터를 기록할지 알고 있으며, 브로커(Kafka 서버)가 실패하더라도 자동으로 복구하는 기능을 갖추고 있습니다. 이를 통해 높은 가용성과 안정성을 보장합니다.

Message Key의 중요성

Kafka에서 Producer는 메시지와 함께 Key를 보낼 수 있습니다. 이 Key의 유무에 따라 데이터가 어떻게 분배될지가 결정됩니다.

  1. Key가 null인 경우: 메시지는 라운드 로빈(Round Robin) 방식으로 파티션에 분배됩니다. 즉, 모든 파티션에 골고루 메시지가 분배되어 균등한 부하를 유지합니다.
  2. Key가 있는 경우: 해당 Key는 해싱(Hashing) 알고리즘을 통해 특정 파티션에 할당됩니다. 동일한 Key를 가진 모든 메시지는 항상 동일한 파티션으로 전송됩니다. 이는 특정 Key(예: truck_id)에 대한 메시지 순서를 보장해야 할 때 매우 유용합니다.

Kafka 메시지 직렬화

Kafka는 Producer로부터 데이터를 받을 때, 반드시 바이트(bytes) 형태로 받아야 합니다. 이는 Kafka가 메시지를 가장 효율적으로 전송하고 처리할 수 있도록 설계된 방식입니다. 따라서, 모든 데이터는 직렬화(Serialization)를 통해 바이트로 변환됩니다.

메시지 직렬화는 주로 메시지의 값(value)Key 모두에 적용됩니다. Producer는 데이터를 바이트로 직렬화한 후 Kafka로 전송하며, Consumer는 이를 다시 역직렬화(Deserialization) 하여 원래의 데이터 형태로 변환합니다.

자주 사용하는 직렬화 형식으로는 다음이 있습니다:

  • String: 일반 문자열 데이터를 직렬화할 때 사용됩니다.
  • Int, Float: 정수 또는 부동소수점 데이터를 직렬화할 때 사용됩니다.
  • Avro: 복잡한 데이터 구조를 직렬화하는 데 사용되는 스키마 기반 직렬화 형식입니다.
  • Protobuf: Google에서 개발한 직렬화 형식으로, Avro와 비슷하게 구조화된 데이터를 효율적으로 직렬화할 수 있습니다.
Kafka Message Key Hashing

결론

Kafka의 Producer는 Message Key를 통해 파티션을 관리하고, 데이터를 효율적으로 분배합니다. Key를 사용하면 특정 데이터의 순서를 보장할 수 있으며, 이는 대규모 실시간 데이터 스트리밍 환경에서 매우 중요한 역할을 합니다. 또한, Kafka의 직렬화 기능은 데이터를 바이트로 변환하여 전송 및 처리 속도를 최적화합니다.

Kafka의 이러한 기능들은 대용량 데이터를 처리할 때 특히 강력한 도구로 작용하며, 다양한 직렬화 형식을 지원하여 유연한 데이터 처리 환경을 제공합니다.

Consumers

Kafka에서 컨슈머(Consumers)토픽(Topic)으로부터 데이터를 읽는 역할을 합니다. Kafka의 데이터 읽기 방식은 풀 모델(Pull Model)을 따르며, 컨슈머는 필요할 때 데이터를 요청하여 가져옵니다. 이를 통해 시스템 리소스를 효율적으로 사용할 수 있습니다.

Consumers의 동작 방식

컨슈머는 어떤 브로커(Broker)로부터 데이터를 읽어야 하는지 자동으로 인식합니다. 만약 브로커에 장애가 발생하더라도 컨슈머는 이를 감지하고, 데이터를 읽어올 수 있도록 자동으로 복구하는 메커니즘을 가지고 있습니다.

컨슈머는 각 파티션 내에서 오프셋(Offset) 순서에 따라 데이터를 읽습니다. 즉, 낮은 오프셋에서 높은 오프셋으로 순차적으로 데이터를 가져오며, 이를 통해 각 파티션 내에서의 순서를 보장할 수 있습니다. 하지만, 파티션 간의 순서는 보장되지 않으므로 특정 데이터 순서를 유지하려면 같은 파티션에 데이터를 저장하는 것이 중요합니다.

위 그림은 컨슈머가 여러 파티션에서 데이터를 읽어오는 과정을 보여줍니다. 각 컨슈머는 특정 파티션에서 데이터를 순차적으로 가져오며, 파티션 간에는 독립적으로 작동합니다.

Consumer의 직렬화/역직렬화(Deserializer)

Kafka의 컨슈머는 역직렬화(Deserialization)를 통해 바이트(bytes) 형태로 전송된 데이터를 원래의 객체나 데이터로 변환합니다. 이는 컨슈머가 데이터를 쉽게 처리할 수 있도록 하는 과정입니다. 역직렬화는 메시지의 값(Value)Key 모두에 적용됩니다.

  • 역직렬화(Deserializer): 바이트 형태의 데이터를 다시 객체 또는 데이터로 변환하는 과정입니다. 이를 통해 Producer가 보낸 데이터를 컨슈머가 이해할 수 있는 형태로 변환합니다.

중요한 고려 사항: Producer 데이터 타입 유지

Producer가 데이터를 전송할 때 사용한 타입을 변경하면 안 됩니다. 이는 컨슈머가 동일한 데이터를 원활하게 역직렬화할 수 있도록 보장하기 위해서입니다. Producer가 데이터를 직렬화한 방식에 맞춰 컨슈머도 동일한 방식으로 역직렬화해야 데이터가 제대로 처리될 수 있습니다.

Consumer Groups란 무엇인가?

Kafka의 Consumer Group은 여러 컨슈머가 그룹을 이루어 특정 토픽에서 데이터를 읽고 처리하는 구조입니다. 하나의 애플리케이션에서 여러 컨슈머가 데이터를 처리해야 할 때, 이들 컨슈머는 Consumer Group을 형성해 각각 독립된 파티션에서 데이터를 읽습니다. 이로 인해 동일한 데이터를 중복 처리하지 않으면서도 병렬로 데이터를 처리할 수 있습니다.

Consumer Group의 작동 방식

Consumer Group Example

위 그림은 하나의 Consumer Group 내에서 각 컨슈머가 서로 다른 파티션에서 데이터를 읽는 구조를 보여줍니다. Consumer4는 비활성화 상태이며, 데이터를 읽지 않습니다. 이러한 구조는 병렬 데이터 처리를 가능하게 하며, 만약 하나의 컨슈머가 실패하더라도 다른 컨슈머가 그 역할을 대신 수행할 수 있도록 유연성을 제공합니다.


여러 컨슈머가 하나의 토픽을 읽는 방식

Kafka의 토픽(Topic)에 여러 컨슈머가 존재하는 경우, 이들은 Consumer Group을 통해 데이터를 나누어 처리합니다. 하지만 이 과정에서 컨슈머의 배치 방식이나 동작 방식에 따라 서로 다른 시나리오가 발생할 수 있습니다.

1. 하나의 Consumer Group 내에서 여러 컨슈머가 있을 때

같은 토픽에서 여러 파티션을 나누어 처리합니다. 각 컨슈머는 서로 다른 파티션의 데이터를 읽으며, 동일한 데이터는 중복해서 처리되지 않습니다. Kafka는 파티션을 기준으로 데이터를 분배하므로, Consumer Group 내에서 파티션의 개수보다 많은 컨슈머가 있을 경우 일부 컨슈머는 데이터를 받지 못할 수 있습니다.

  • 파티션의 수가 컨슈머의 수보다 많을 경우, 하나의 컨슈머가 여러 파티션의 데이터를 처리할 수 있습니다.

2. 여러 Consumer Group이 같은 토픽을 읽을 때

만약 동일한 토픽을 다른 Consumer Group이 읽는다면, 각 Consumer Group은 동일한 데이터를 읽을 수 있습니다. 예를 들어, 서비스 A와 서비스 B가 같은 토픽을 사용해야 할 경우, 각기 다른 Consumer Group을 형성하여 동일한 데이터를 중복 처리할 수 있습니다. 이는 같은 데이터를 기반으로 다양한 작업을 수행할 수 있도록 도와줍니다.


Consumer Offsets과 다중 컨슈머

Kafka에서 오프셋(Offset)은 각 컨슈머가 데이터를 읽은 위치를 나타냅니다. 여러 Consumer Group이 동일한 토픽에서 데이터를 처리할 때, 각 그룹은 독립적인 오프셋을 가지며 이를 기반으로 어디까지 데이터를 읽었는지를 기억합니다. Kafka는 이 정보를 __consumer_offsets 토픽에 저장하여 관리합니다.

오프셋이 관리되는 방식 덕분에 컨슈머가 실패하거나 재시작되더라도 마지막으로 읽은 위치에서 데이터를 다시 읽을 수 있습니다. 각 컨슈머는 Kafka로부터 데이터를 처리한 후 주기적으로 오프셋을 커밋해야 합니다. 이 오프셋이 커밋되면, 브로커가 이를 관리하고, 컨슈머가 종료되거나 실패할 경우 마지막 커밋된 위치부터 다시 데이터를 읽을 수 있습니다.


Consumer Group을 활용한 다양한 시나리오

1. 하나의 Consumer Group

하나의 Consumer Group을 사용할 경우, 여러 컨슈머가 각각 다른 파티션에서 데이터를 처리합니다. 이를 통해 데이터는 병렬로 처리되며, 처리 속도가 향상됩니다. 다만, 파티션 내에서만 데이터 순서가 보장되므로 여러 파티션 간의 데이터 순서는 보장되지 않습니다.

2. 여러 Consumer Group

같은 토픽을 여러 애플리케이션에서 사용할 때는 각각 별도의 Consumer Group을 사용할 수 있습니다. 이렇게 하면 동일한 데이터를 여러 애플리케이션이 중복 처리할 수 있으며, 각각의 서비스에서 다른 작업을 수행할 수 있습니다. 예를 들어, 하나의 애플리케이션은 데이터 분석을, 다른 애플리케이션은 알림을 처리할 수 있습니다.


메시지 전달 보장 방식 (Delivery Semantics)

Kafka에서는 컨슈머가 데이터를 처리할 때, 오프셋을 자동으로 커밋하는 것이 기본 설정입니다. 그러나 경우에 따라 수동 커밋을 설정하여 더욱 세밀하게 데이터를 처리할 수 있습니다. 이때 Kafka는 3가지의 메시지 전달 보장 방식을 제공합니다.

  1. At least once (최소 한 번 보장)
    메시지가 처리된 후 오프셋을 커밋합니다.
    만약 처리 과정에서 오류가 발생하면, 해당 메시지를 다시 읽어 중복 처리가 발생할 수 있습니다. 이 경우 시스템에서 멱등성(idempotent)을 보장해야 합니다. 즉, 동일한 메시지를 여러 번 처리해도 시스템에 영향을 주지 않도록 해야 합니다.

  2. At most once (최대 한 번 보장)
    메시지를 수신하자마자 오프셋을 커밋합니다.
    만약 처리 과정에서 문제가 생기면, 해당 메시지는 다시 읽히지 않으므로 일부 메시지가 유실될 수 있습니다.

  3. Exactly once (정확히 한 번 보장)
    Kafka 내부에서 Kafka 스트림 API를 통해 제공되는 트랜잭셔널 API를 활용하여 정확히 한 번만 데이터를 처리할 수 있습니다. 외부 시스템과의 통합에서는 멱등성을 보장하는 컨슈머를 사용해야 합니다.


결론

Kafka의 Consumer Group은 대규모 데이터를 병렬로 처리할 수 있는 강력한 구조입니다. 이를 통해 여러 컨슈머가 동일한 토픽에서 데이터를 나누어 읽고 처리할 수 있으며, 다중 컨슈머 환경에서도 데이터를 효율적으로 처리할 수 있습니다. 오프셋을 통해 각 컨슈머의 데이터 처리 위치를 관리할 수 있으며, 메시지 전달 보장 방식을 통해 데이터 처리의 신뢰성을 높일 수 있습니다.

Kafka의 Consumer Group을 잘 이해하고 활용하면, 실시간 데이터 처리확장성 있는 시스템을 구축하는 데 큰 도움이 될 것입니다.

Kafka Brokers

Kafka 클러스터와 브로커 이해하기

Kafka는 대규모 데이터를 실시간으로 처리할 수 있는 분산형 메시지 스트리밍 플랫폼으로, 그 중심에는 여러 개의 브로커(Brokers)가 있습니다. 이 글에서는 Kafka 클러스터와 브로커의 역할, 그리고 브로커 간의 동작 방식에 대해 자세히 알아보겠습니다.


Kafka 클러스터와 브로커의 개념

1. Kafka 클러스터란?

Kafka 클러스터는 여러 개의 브로커(Brokers)로 구성되어 있습니다. 각 브로커는 Kafka 서버를 의미하며, 클러스터 내에서 토픽 파티션(Topic Partitions)을 관리합니다. 이때 각 브로커는 고유한 ID(정수)로 식별됩니다.

Kafka 클러스터의 중요한 특징 중 하나는 클러스터 내의 모든 브로커가 서로의 상태와 정보를 알고 있다는 점입니다. 즉, 클러스터에 있는 어느 브로커에 연결되든, 그 브로커는 다른 모든 브로커, 토픽, 파티션에 대한 메타데이터를 가지고 있어 전체 클러스터에 접근할 수 있습니다.

  • Kafka 클러스터는 확장 가능하며, 브로커 수를 유연하게 늘릴 수 있습니다.
  • 수평적 확장성(horizontal scaling)을 지원하여 성능과 안정성을 유지하면서도 손쉽게 확장할 수 있습니다.

2. 브로커의 역할

Kafka에서 브로커(Broker)는 데이터를 저장하고 관리하는 서버 역할을 합니다. 각 브로커는 하나 이상의 파티션을 담당하며, 클러스터 내에서 역할을 분담하여 데이터를 효율적으로 처리합니다. Kafka 브로커의 핵심 역할은 다음과 같습니다:

  • 메시지 저장: 클라이언트로부터 받은 데이터를 특정 토픽의 파티션에 저장합니다.
  • 데이터 전송: 컨슈머에게 데이터를 전송하며, 이때 각 컨슈머는 자신이 구독한 토픽의 데이터를 읽습니다.
  • 메타데이터 관리: 각 브로커는 모든 토픽, 파티션, 브로커에 대한 메타데이터를 관리합니다. 이를 통해 클러스터의 상태와 구조를 유지합니다.

Kafka 브로커와 클라이언트 연결

Kafka 클러스터에 있는 어느 브로커에 연결하든, 클라이언트는 전체 클러스터에 연결할 수 있습니다. 이를 가능하게 하는 것이 바로 Kafka 브로커의 부트스트랩 서버(Bootstrap Server) 역할입니다.

1. 부트스트랩 서버 (Bootstrap Server)

Kafka 클러스터에서 부트스트랩 서버란, 클라이언트가 Kafka 클러스터에 연결될 때 최초로 접속하는 브로커를 말합니다. 클라이언트는 부트스트랩 서버를 통해 전체 클러스터의 상태를 인식하며, 이후 자동으로 다른 브로커들과도 연결됩니다.

  • 스마트 클라이언트(Smart Clients): Kafka 클라이언트는 스마트 연결 메커니즘을 가지고 있어, 한 브로커에만 연결해도 전체 클러스터와 연결됩니다. 따라서 클라이언트는 모든 브로커의 정보를 알 필요 없이, 부트스트랩 서버에만 연결하면 됩니다.

  • 브로커 간 메타데이터 공유: 각 브로커는 클러스터에 있는 모든 토픽, 파티션, 브로커의 메타데이터를 알고 있으므로, 부트스트랩 서버에만 연결되면 클라이언트는 클러스터 전체에 접근할 수 있습니다.

2. 브로커의 수와 클러스터 확장

Kafka 클러스터는 일반적으로 3개의 브로커로 시작하는 것이 권장됩니다. 그러나 대규모 클러스터에서는 100개 이상의 브로커를 포함할 수 있습니다. 브로커가 많아질수록, 각 브로커는 더 많은 데이터를 저장하고 처리할 수 있게 되며, Kafka의 확장성과 성능을 더욱 극대화할 수 있습니다.


Kafka 클러스터의 수평 확장 (Horizontal Scaling)

Kafka는 수평적 확장을 통해 데이터 처리량을 늘릴 수 있습니다. 브로커를 추가하는 것만으로도 클러스터의 처리 능력을 쉽게 확장할 수 있습니다. 이러한 수평 확장은 대규모 데이터를 효율적으로 관리하고 처리하기 위해 필수적입니다.

각 브로커는 독립적으로 동작하면서도 클러스터 전체의 데이터 처리를 분담하므로, 브로커의 수를 늘리면 처리 속도가 향상되고, 데이터 처리의 안정성이 높아집니다.


결론

Kafka의 브로커클러스터는 대규모 데이터 스트리밍 시스템에서 매우 중요한 역할을 합니다. Kafka 클라이언트는 단 하나의 부트스트랩 서버에만 연결하면 전체 클러스터에 접근할 수 있으며, 수평 확장을 통해 더 많은 데이터를 효율적으로 처리할 수 있습니다. 이러한 구조 덕분에 Kafka는 확장성 높은 실시간 데이터 처리 플랫폼으로 널리 사용되고 있습니다.

Topic Replication

Kafka의 토픽 복제(Topic Replication)란?


Kafka에서 토픽 복제(Topic Replication)는 데이터의 가용성과 안정성을 높이기 위한 중요한 기능입니다. 복제는 브로커가 실패하더라도 다른 브로커가 복제된 데이터를 제공할 수 있게 하여, 시스템의 안정성을 유지할 수 있게 합니다. Kafka의 각 파티션(Partition)은 복제본을 가지고 있으며, 이를 통해 데이터 손실을 방지하고 서비스 중단을 최소화합니다.


토픽 복제의 기본 개념

Kafka에서 토픽 복제는 각 파티션의 데이터를 여러 브로커에 복제하는 방식으로 이루어집니다. 복제본의 개수를 나타내는 값은 Replication Factor라고 하며, 일반적으로 2 또는 3으로 설정됩니다. 복제본의 개수가 많을수록 시스템의 안정성이 높아지지만, 자원 소모도 증가하게 됩니다.

리더(Leader)와 팔로워(Follower) 개념

Kafka에서 각 파티션리더(Leader)팔로워(Follower)로 나뉩니다.

  • 리더(Leader):
    파티션의 데이터를 관리하고, 모든 프로듀서컨슈머는 리더와 통신하여 데이터를 송수신합니다.
    리더는 각 파티션에 대해 단 하나만 존재합니다.
  • 팔로워(Follower):
    리더의 데이터를 복제하여 가지고 있는 복제본입니다. 팔로워는 리더의 데이터를 주기적으로 동기화하여, 리더가 실패할 경우 그 역할을 대신할 준비를 합니다.


이와 같은 구조를 통해 하나의 브로커가 다운되더라도, 다른 브로커가 리더 역할을 대신할 수 있어 데이터 손실을 방지하고 서비스의 지속성을 유지할 수 있습니다.


Kafka의 복제 메커니즘

1. 복제 인수(Replication Factor)

Kafka에서 Replication Factor는 각 파티션의 복제본이 몇 개의 브로커에 분산되어 저장되는지를 결정합니다. 예를 들어, Replication Factor가 3이라면, 하나의 파티션은 3개의 브로커에 복제되어 저장됩니다.

복제본 중 하나는 리더(Leader)로 선택되고, 나머지는 팔로워(Follower)로 작동합니다. 만약 리더가 다운되면, Kafka는 팔로워 중 하나를 새로운 리더로 승격시켜 데이터를 계속해서 제공할 수 있도록 합니다.

2. 리더와 팔로워의 동기화(In-Sync Replicas, ISR)

Kafka에서는 ISR(In-Sync Replicas)라는 개념을 통해 리더와 팔로워의 동기화를 관리합니다. ISR에 포함된 브로커들은 리더와 동기화된 상태를 유지하며, 리더가 문제가 생기면 ISR 중 하나가 자동으로 리더로 승격됩니다.

리더는 팔로워에게 데이터를 복제하고, 이 복제본들이 ISR에 포함됩니다. Kafka는 팔로워들이 리더와 충분히 동기화된 상태일 때만 데이터를 소비자로 내보내며, 동기화되지 않은 팔로워는 ISR에 포함되지 않으므로 리더로 승격되지 않습니다.

3. 데이터 읽기와 쓰기

  • 프로듀서리더에게만 데이터를 전송할 수 있습니다. 데이터가 리더에 기록되면, 팔로워가 그 데이터를 복제하여 동기화합니다.
  • 컨슈머는 기본적으로 리더로부터 데이터를 읽습니다. 그러나 복제본에서 데이터를 읽는 옵션을 활성화할 경우, 가장 가까운 복제본에서 데이터를 읽을 수 있어 네트워크 비용을 줄이고 지연 시간을 최소화할 수 있습니다.

이 구조를 통해 Kafka는 데이터 가용성을 보장하고, 안정성 있는 분산 데이터 스트리밍 시스템을 구축할 수 있습니다.


토픽 복제의 장점

  1. 높은 가용성:
    한 브로커가 장애가 발생해도 다른 브로커가 복제된 데이터를 제공할 수 있습니다. 이를 통해 서비스 중단 없이 시스템을 지속적으로 운영할 수 있습니다.

  2. 데이터 손실 방지:
    복제본을 사용하면 브로커가 고장 나더라도 데이터를 안전하게 보호할 수 있으며, 데이터 손실의 위험을 최소화할 수 있습니다.

  3. 유연한 확장성:
    복제본의 개수는 필요에 따라 조정할 수 있습니다. 복제본이 많을수록 안정성은 높아지지만, 자원 소모가 증가합니다.


복제 설정 시 고려 사항

  1. 복제 인수 설정:
    복제 인수를 너무 높게 설정하면 리소스가 많이 소비될 수 있으므로, 가용성과 자원 효율성을 고려해 적절한 복제 인수를 선택해야 합니다. 일반적으로 2에서 3 정도가 권장됩니다.

  2. ISR 관리:
    ISR에 포함되지 않은 팔로워는 동기화되지 않은 상태이므로, 리더로 승격될 수 없습니다. 따라서 Kafka는 ISR을 지속적으로 관리하여 시스템의 안정성을 유지합니다.

  3. 리더 전환 시점:
    리더 브로커가 장애가 발생하면 Kafka는 자동으로 팔로워 중 하나를 새로운 리더로 승격시킵니다. 이 과정에서 데이터 손실을 방지하기 위해 ISR 동기화가 중요합니다.


결론

Kafka의 토픽 복제는 시스템의 안정성과 가용성을 보장하기 위한 핵심 기능입니다. 복제를 통해 데이터 손실 없이 브로커 장애를 복구할 수 있으며, 서비스 중단을 최소화할 수 있습니다. 리더팔로워 구조를 통해 복제가 이루어지며, ISR을 통해 리더와 팔로워의 동기화를 관리합니다. 이를 통해 Kafka는 대규모 데이터를 안정적으로 관리하고 처리하는 분산 시스템의 중요한 역할을 수행합니다.

Producer Acknowledgements

Kafka 토픽 내구성(Topic Durability)이란?

Kafka에서 토픽 내구성(Topic Durability)은 데이터 손실을 방지하고 시스템 가용성을 보장하기 위한 중요한 개념입니다. Kafka는 데이터가 복제(replication)를 통해 여러 브로커에 분산 저장되기 때문에, 특정 브로커가 장애를 일으켜도 데이터를 안전하게 보호할 수 있습니다. 복제본의 개수는 복제 인수(Replication Factor)로 결정되며, 이 값을 기준으로 Kafka의 내구성 수준이 결정됩니다.


복제 인수와 내구성의 관계

Kafka에서 복제 인수(Replication Factor)는 한 파티션의 데이터가 몇 개의 브로커에 복제되는지를 나타내는 값입니다. 예를 들어, 복제 인수가 3이라면 하나의 파티션은 3개의 브로커에 복제되어 저장됩니다. 이 복제본들이 데이터를 안전하게 보호하여 브로커 장애에도 데이터를 복구할 수 있는 능력을 제공합니다.

  • 복제 인수가 N일 때, Kafka는 최대 N-1개의 브로커가 손실되어도 데이터를 복구할 수 있습니다.
    즉, 복제본이 여러 브로커에 분산되어 저장되어 있으므로, N-1개의 브로커가 손실되더라도 여전히 하나의 복제본이 남아 있어 데이터를 복구할 수 있습니다.

복제 인수와 내구성 예시

  • 복제 인수 3일 경우:
    복제 인수가 3인 토픽은 최대 2개의 브로커를 잃더라도 데이터를 잃지 않고 복구할 수 있습니다. 이는 각 파티션의 데이터가 3개의 브로커에 복제되어 있기 때문에, 1개의 복제본이 남아 있으면 복구가 가능하다는 뜻입니다.

    Replication Factor 3

    위 그림처럼, 복제본이 3개 있을 때 2개의 브로커가 손실되더라도 남은 1개의 복제본에서 데이터를 복구할 수 있습니다.

  • 복제 인수 2일 경우:
    복제 인수가 2일 때는 최대 1개의 브로커가 손실되더라도 데이터를 복구할 수 있습니다. 두 개의 브로커 중 하나가 고장 나더라도 나머지 하나에서 데이터를 복구할 수 있습니다.


Kafka 내구성의 핵심 장점

  1. 데이터 손실 방지:
    Kafka는 복제를 통해 브로커 장애 시에도 데이터를 안전하게 보호합니다. 복제본이 여러 브로커에 분산 저장되므로, 브로커가 실패해도 데이터 손실이 발생하지 않습니다.

  2. 브로커 장애 시 복구 능력:
    복제 인수에 따라 여러 브로커가 손실되어도 시스템이 자동으로 복구됩니다. 예를 들어, 복제 인수가 3이면 최대 2개의 브로커가 손실되더라도 데이터를 안전하게 복구할 수 있습니다.

  3. 가용성 향상:
    Kafka는 여러 복제본을 통해 데이터를 분산 저장함으로써 브로커 장애에도 서비스를 중단 없이 지속할 수 있습니다. 이를 통해 고가용성(High Availability)을 보장합니다.


복제 인수 설정 시 고려 사항

  1. 복제 인수의 균형:
    복제 인수가 클수록 데이터가 더 많이 복제되어 안정성이 높아지지만, 그만큼 자원 소모도 커집니다. 일반적으로 복제 인수는 2에서 3 사이로 설정하는 것이 권장됩니다.

  2. 가용성과 비용:
    복제본을 여러 개 유지하려면 추가적인 브로커 자원이 필요합니다. 따라서 복제 인수를 결정할 때는 시스템의 가용성 요구 사항자원 소모를 함께 고려해야 합니다.


결론

Kafka의 토픽 내구성은 복제를 통해 데이터의 안정성과 가용성을 보장하는 중요한 메커니즘입니다. 복제 인수에 따라 여러 브로커가 손실되어도 데이터를 안전하게 복구할 수 있으며, 서비스의 지속성을 유지할 수 있습니다. 복제 인수 N에 대해 최대 N-1개의 브로커가 손실되어도 데이터를 복구할 수 있으므로, 복제 인수를 적절히 설정하는 것이 Kafka의 안정성을 유지하는 핵심입니다.

Zookeepr

Kafka와 Zookeeper의 관계 및 변화

Kafka는 오랫동안 Zookeeper를 활용하여 브로커와 토픽을 관리하고, 파티션의 리더 선출을 담당해 왔습니다. 그러나 Kafka의 발전과 함께 Kafka Raft라는 새로운 기술이 도입되면서 Zookeeper의 역할이 점차 줄어들고 있으며, Kafka 4.x부터는 Zookeeper 없이도 동작할 수 있게 됩니다. 이 글에서는 Kafka에서 Zookeeper가 어떻게 동작하는지, 그리고 Kafka의 변화 과정을 자세히 설명하겠습니다.


Zookeeper의 역할

Kafka는 Zookeeper를 통해 브로커와 클러스터 상태를 관리합니다. Zookeeper는 클러스터에 대한 여러 중요한 작업을 수행하는데, 그 중 몇 가지 핵심 역할은 다음과 같습니다:

1. 브로커 관리

Zookeeper는 Kafka 클러스터 내의 브로커 리스트를 관리합니다. 클러스터 내 브로커의 상태 변화를 실시간으로 모니터링하고, 새로운 브로커가 추가되거나 브로커가 종료되는 등의 변화를 Kafka에 알립니다.

2. 리더 선출

Kafka는 파티션마다 하나의 리더를 두고, 그 리더가 파티션의 데이터를 관리합니다. Zookeeper는 파티션의 리더 선출을 담당하며, 리더 브로커가 장애가 발생할 경우 새로운 리더를 선출하는 과정을 관리합니다. 이를 통해 Kafka는 리더 장애 시에도 신속하게 복구할 수 있습니다.

3. 변경 사항 알림

Zookeeper는 새로운 토픽이 생성되거나 삭제되는 등 Kafka 클러스터에서 발생하는 다양한 이벤트를 Kafka에 알립니다. 이를 통해 Kafka는 클러스터의 변화를 즉각 반영하고, 안정적인 운영을 유지합니다.

4. Zookeeper의 운영 방식

Zookeeper는 홀수 개의 서버로 구성되는 것이 일반적입니다. 이는 주로 리더 선출을 위한 투표 과정을 위해서입니다. Zookeeper는 리더-팔로워 구조로 동작하며, 리더는 데이터를 쓰고 팔로워들은 데이터를 읽는 역할을 수행합니다.


Kafka와 Zookeeper의 변화

Kafka는 오랫동안 Zookeeper에 의존하여 클러스터를 관리해왔지만, 최근 Kafka의 발전과 함께 Zookeeper의 역할이 축소되고 있습니다. Kafka 2.x부터는 점차 Zookeeper의 의존성을 줄이기 시작했으며, Kafka 3.x부터는 Zookeeper 없이도 동작할 수 있도록 설계되었습니다. 이 변화는 KIP-500이라는 Kafka 개선 제안을 통해 이루어졌으며, Kafka Raft Consensus Algorithm(KRaft)을 도입하게 되었습니다.

1. Kafka 2.x에서의 변화

  • Kafka 2.x 버전에서는 Zookeeper를 여전히 사용하고 있지만, 점차 Zookeeper의 역할이 줄어들고 있습니다.
  • Kafka CLI 도구인 kafka-topics.sh와 같은 명령어는 이제 Zookeeper 대신 Kafka 브로커를 참조하여 토픽을 관리하게 되었습니다. 이는 Kafka 클러스터의 관리 작업을 더 일관성 있고 효율적으로 처리할 수 있게 합니다.
  • Kafka 2.2 버전부터는 토픽 생성 및 삭제 작업을 포함한 대부분의 관리 작업이 Zookeeper 대신 Kafka 브로커를 통해 이루어집니다. 이로 인해 Zookeeper 의존성이 감소하고, 클라이언트와의 통합이 쉬워졌습니다.

2. Kafka 3.x와 Kafka Raft

  • Kafka 3.x에서는 Zookeeper 없이도 Kafka 클러스터를 운영할 수 있는 기능이 도입되었습니다. Kafka Raft(KRaft)라는 새로운 합의 알고리즘이 적용되어, Zookeeper의 기능을 대체할 수 있게 되었습니다.
  • Kafka Raft는 Zookeeper 없이도 브로커를 관리하고, 리더 선출 및 파티션 관리를 수행할 수 있으며, 이를 통해 더 안정적이고 안전한 클러스터 운영이 가능합니다.

3. Kafka 4.x에서는 Zookeeper 제거**

  • Kafka 4.x부터는 Zookeeper가 완전히 제거될 예정입니다. Kafka 클러스터는 Kafka Raft를 통해 운영되며, Zookeeper의 모든 기능이 Kafka 내부에서 처리됩니다.
  • 이 변화는 Kafka 클러스터의 복잡성을 줄이고, 보안과 성능을 더욱 개선할 수 있게 할 것입니다.


Zookeeper와 보안

Zookeeper는 설계상 Kafka보다 보안에 취약할 수 있습니다. 따라서 Kafka 클러스터에서 Zookeeper를 사용할 때는 Zookeeper 포트를 제한하여 Kafka 브로커로부터만 트래픽을 허용해야 합니다. Kafka 클라이언트는 Zookeeper에 직접 연결되지 않도록 구성하는 것이 바람직합니다. Kafka 3.x 이후로는 Zookeeper 대신 Kafka 브로커가 클라이언트의 연결 지점이므로, 클라이언트는 더 이상 Zookeeper와 직접 통신할 필요가 없습니다.


결론

Kafka는 Zookeeper를 통해 클러스터를 관리하고 안정성을 유지해왔지만, Kafka 2.x부터는 Zookeeper의 역할이 점차 축소되었고, Kafka 3.x에서는 Kafka Raft(KRaft)를 통해 Zookeeper 없이도 클러스터를 운영할 수 있게 되었습니다. Kafka 4.x부터는 Zookeeper가 완전히 제거될 예정이며, Kafka는 더욱 효율적이고 보안성이 강화된 상태로 운영될 것입니다. 이러한 변화는 Kafka 클러스터의 관리와 확장성을 더욱 개선하는 데 큰 역할을 할 것입니다.

0개의 댓글