카프카 버전 업그레이드
카프카 버전 업그레이드를 해야할 일이 생겨 버전별 차이 및 업그레이드 방법에대해 알아봤다. 자료는 kafka 공식 document에서 찾아보았다. kafka broker와 kafka-clients만 업그레이드 해야 했기 때문에 kafka-connect와 streams는 업그레이드 내용을 찾아볼 때 제외하였다.
아래는 자료출처이다.
https://kafka.apache.org/downloads#2.0.0
Apache Kafka
Apache Kafka: A Distributed Streaming Platform.
kafka.apache.org
https://kafka.apache.org/documentation/#upgrade_200_notable
Apache Kafka
Apache Kafka: A Distributed Streaming Platform.
kafka.apache.org
버전별 기능
버전별 업그레이드 기능
1.1.0
- 변경 내용
- 브로커 구성 옵션의 동적 업데이트 (KIP-226)
- 일부 브로커 구성 옵션을 브로커를 재시작하지 않고도 동적으로 업데이트할 수 있습니다.
- Kafka 컨트롤러의 성능이 개선
- Kafka 클러스터를 종료할 때 컨트롤러가 브로커를 순차적으로 종료하도록 제어하는 방식이 개선되어 더 빠르게 종료
- ZooKeeper 세션 만료 문제 해결:
- 이전 버전에서는 특정 상황에서 ZooKeeper 세션이 예상치 않게 만료되는 경우가 발생할 수 있었습니다. 이러한 엣지 케이스가 수정되어 안정성이 향상되었습니다.
- 특정 시나리오에서 ZooKeeper와의 연결이 끊어지거나 세션이 만료되면 브로커가 클러스터에서 제대로 제거되지 않는 문제가 있었습니다. 이 문제는 Kafka 1.1.0에서 수정되어 브로커가 올바르게 제거되고 클러스터가 안정적으로 유지됩니다.
- 증분 페치 요청(incremental fetch requests) 도입 (KIP-227)
- KIP-227은 증분 페치 요청을 도입하여 많은 파티션을 가진 클러스터에서 복제를 더 효율적으로 만듭니다.
- Kafka 1.1.0에서는 증분 페치 요청을 도입하여, 복제 시 마지막으로 전송된 오프셋 이후의 데이터만 전송합니다. 예를 들어, 리더 브로커가 팔로워 브로커에게 데이터를 전송할 때 마지막으로 전송된 오프셋 이후의 변경된 데이터만 보내기 때문에 네트워크 대역폭을 절약할 수 있습니다.
- 기존 방식: 모든 Fetch 요청에서 전체 데이터를 요청합니다. 이는 데이터 양이 많을수록 네트워크와 시스템 자원을 많이 소모합니다.
- 증분 방식: 마지막 Fetch 요청 이후의 변경된 데이터만 요청합니다. 이를 통해 불필요한 데이터 전송을 줄여 네트워크와 시스템 자원의 효율성을 높입니다.
- 로그 디렉터리 간의 복제본 이동 지원 (KIP-113)
- 로그 디렉터리 간의 복제본 이동을 지원. 데이터의 이동이 가능해짐으로써 디스크 교체, 확장 등의 작업을 유연하게 수행할 수 있습니다.
- Kafka 1.1.0에서는 브로커가 실행 중인 상태에서도 복제본을 다른 로그 디렉터리로 이동할 수 있습니다. 예를 들어, topicA의 파티션 0이 디스크 A에 저장되어 있고, 디스크 A가 가득 차서 디스크 B로 이동하려는 경우, 다음과 같이 설정할 수 있습니다
- 브로커 구성 옵션의 동적 업데이트 (KIP-226)
2.0.0
- 변경 내용
- 기본 시간 초과 설정
- 새로운 소비자 설정 default.api.timeout.ms가 추가되어 KafkaConsumer API에서 사용할 기본 시간 초과를 지정할 수 있습니다.
- 접두사 ACL 지원 (KIP-290)
- 접두사 ACL(Access Control List)은 대규모 보안 배포 환경에서 접근 제어 관리를 단순화합니다. 예를 들어, 회사에서 'projectA'로 시작하는 모든 주제(topic)에 대한 접근 권한을 부여하려고 할 때, 이제는 모든 주제를 개별적으로 설정할 필요 없이 한 번에 설정할 수 있습니다. 이는 대량의 주제, 소비자 그룹 또는 트랜잭션 ID에 대한 접근 권한을 쉽게 관리할 수 있게 해줍니다.기존 방식: projectA_topic1, projectA_topic2 각각에 대해 접근 권한을 설정합니다.
//projectA-로 시작하는 모든 토픽에 대해 User:Alice에게 읽기 권한을 부여. kafka-acls --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:Alice --operation READ --topic projectA-*
- 접두사 ACL(Access Control List)은 대규모 보안 배포 환경에서 접근 제어 관리를 단순화합니다. 예를 들어, 회사에서 'projectA'로 시작하는 모든 주제(topic)에 대한 접근 권한을 부여하려고 할 때, 이제는 모든 주제를 개별적으로 설정할 필요 없이 한 번에 설정할 수 있습니다. 이는 대량의 주제, 소비자 그룹 또는 트랜잭션 ID에 대한 접근 권한을 쉽게 관리할 수 있게 해줍니다.기존 방식: projectA_topic1, projectA_topic2 각각에 대해 접근 권한을 설정합니다.
- 클라이언트 스로틀링 알림 :
- 클라이언트가 스로틀링(속도 제한) 되기 전에 이를 알림으로 받을 수 있습니다. 이는 클라이언트가 네트워크 오류와 큰 스로틀 시간 사이를 구분할 수 있도록 도와줍니다.기존 방식: 클라이언트가 네트워크 오류인지 스로틀링 때문인지 알 수 없음.
- 새 방식: 스로틀링 알림을 통해 클라이언트가 문제의 원인을 명확히 이해하고 대처할 수 있습니다.
- SSL 신뢰 저장소의 동적 업데이트
- Kafka 브로커를 재시작하지 않고도 SSL 신뢰 저장소를 업데이트할 수 있습니다. 즉, 보안 인증서와 관련된 파일들을 변경할 때 브로커를 다시 시작할 필요가 없다는 의미입니다. 또한, 브로커 시작 전에 ZooKeeper에서 보안 설정(예: SSL 키스토어 비밀번호)을 미리 설정할 수 있습니다. 이를 통해 중요한 비밀번호를 ZooKeeper에 암호화된 상태로 저장할 수 있습니다.기존 방식: SSL 인증서를 갱신할 때마다 Kafka 브로커를 재시작해야 합니다.
- 새 방식: SSL 인증서를 갱신해도 브로커를 재시작할 필요 없이 변경 사항이 즉시 적용됩니다.
- SSL 연결에서 호스트 이름 검증 기본 활성화
- 호스트 이름 검증은 SSL 연결에서 서버의 신원을 확인하는 방법입니다. SSL을 통해 서버와 클라이언트가 안전하게 통신하려면, 클라이언트는 서버가 신뢰할 수 있는 서버인지 확인해야 합니다. 이를 위해 서버의 SSL 인증서에 포함된 호스트 이름과 실제로 연결된 서버의 호스트 이름이 일치하는지 확인합니다. 기존 방식은 다음과 같습니다.
- 클라이언트는 서버의 SSL 인증서를 검증하지 않음.
- 공격자가 중간에 서버로 위장하여 데이터를 가로챌 수 있음.
- 클라이언트는 서버의 SSL 인증서에 포함된 호스트 이름이 실제 서버의 호스트 이름과 일치하는지 확인함.
- 호스트 이름이 일치하지 않으면 연결을 차단하여 중간자 공격을 방지함.
- 사용자가 'https://example.com'에 접속할 때, 브라우저는 서버의 SSL 인증서에 포함된 호스트 이름이 'example.com'인지 확인합니다.
- 호스트 이름이 일치하면, 브라우저는 서버와 안전하게 통신을 시작합니다.
- 호스트 이름이 일치하지 않으면, 브라우저는 경고 메시지를 표시하고 연결을 차단합니다.
- 호스트 이름 검증은 SSL 연결에서 서버의 신원을 확인하는 방법입니다. SSL을 통해 서버와 클라이언트가 안전하게 통신하려면, 클라이언트는 서버가 신뢰할 수 있는 서버인지 확인해야 합니다. 이를 위해 서버의 SSL 인증서에 포함된 호스트 이름과 실제로 연결된 서버의 호스트 이름이 일치하는지 확인합니다. 기존 방식은 다음과 같습니다.
- 기본 시간 초과 설정
2.1.0
- 변경 내용
- 활성 소비자 그룹에 대해 커밋된 오프셋이 만료되지 않도록 방지 KIP-211
- 설명:KIP-211은 활성 소비자 그룹에 대해 커밋된 오프셋이 만료되지 않도록 방지하는 기능입니다.
- KIP-211은 활성 소비자 그룹의 경우 오프셋이 만료되지 않도록 하여, 소비자가 지속적으로 데이터를 처리할 수 있도록 보장합니다. 활성 소비자 그룹은 정기적으로 하트비트(heartbeat)를 보내며, 이를 통해 클러스터는 해당 소비자가 여전히 활성 상태임을 인식합니다.
- 예시:예를 들어, 특정 소비자 그룹 "groupA"가 토픽 "topicA"를 읽고 있다고 가정합니다. 이 소비자 그룹은 1시간 동안 활동하지 않으면 오프셋이 만료될 수 있습니다. KIP-211이 적용되면, 이 소비자 그룹이 활성 상태인 한 오프셋은 만료되지 않으며, 1시간 이상의 비활동 시간 후에도 이전에 커밋된 위치에서 계속 읽을 수 있습니다.
- 프로듀서에서 직관적인 사용자 타임아웃 제공 (KIP-91)
- 설명:KIP-91은 프로듀서에서 직관적인 사용자 타임아웃을 제공하는 기능입니다. Kafka 프로듀서 설정에서 타임아웃 값을 구성할 때 더 직관적인 방법을 제공합니다.
- 예시:기존 방식에서는 request.timeout.ms, delivery.timeout.ms 등의 설정이 서로 상호작용하여 타임아웃을 결정합니다. KIP-91에서는 delivery.timeout.ms를 통해 전체 타임아웃을 명확하게 설정할 수 있습니다. 예를 들어, delivery.timeout.ms를 30초로 설정하면, 프로듀서는 30초 내에 메시지를 전송하려고 시도하며, 실패하면 명확한 타임아웃 오류를 반환합니다.
- 카프카의 복제 프로토콜이 좀비 브로커를 더 잘 차단하도록 개선
- 설명:KIP-320은 Kafka의 복제 프로토콜이 좀비 브로커를 더 잘 차단하도록 개선하는 기능입니다.
- 예시:예를 들어, 브로커 B가 네트워크 문제로 인해 Zookeeper와 연결이 끊겼지만, 클러스터의 다른 브로커들과는 여전히 연결되어 있는 상황을 가정합니다. 이 브로커가 좀비 브로커가 될 수 있습니다. KIP-320이 적용되면, 클러스터는 브로커 B가 리더로서 역할을 수행할 자격이 있는지 재검토하고, 필요시 새로운 리더를 선출하여 데이터 일관성을 보장합니다.
- 활성 소비자 그룹에 대해 커밋된 오프셋이 만료되지 않도록 방지 KIP-211
2.2.0
- 변경 내용
- 명령 줄 도구 bin/kafka-topics.sh에 AdminClient 지원 추가
- AdminClient API : 토픽 관리, 브로커 관리, ACL(Access Control Lists) 설정 등 다양한 관리 작업을 프로그래밍 방식으로 수행합니다.
- Kafka 2.2.0에서는 bin/kafka-topics.sh 스크립트가 AdminClient API를 지원하게 되었습니다. 이를 통해 Kafka 브로커와 직접 상호작용하여 관리 작업을 수행할 수 있습니다.
- 기존 kafka-topics.sh는 Kafka 토픽 관리를 위해 Zookeeper와 직접 상호작용하는 방식으로 동작했지만 개선됐습니다.
- 개선된 소비자 그룹 관리: 기본 group.id가 빈 문자열 대신 null로 설정
- Kafka 2.2.0에서는 group.id가 null로 설정되므로, group.id를 명시적으로 설정하지 않으면 오류가 발생하여 사용자에게 명확한 피드백을 제공합니다.
- API 개선 → API 개선된 부분 이전 코드와 연동되나 확인 필요
- Producer: introduce close(Duration) :주어진 시간 내에 프로듀서를 종료하도록 합니다. 프로듀서를 종료할 때 타임아웃을 설정하여, 종료 작업이 무기한 지연되는 것을 방지할 수 있습니다.
Producer<String, String> producer = new KafkaProducer<>(props); // 메시지 전송 producer.send(new ProducerRecord<>("my-topic", "key", "value")); // 10초 내에 프로듀서 종료 producer.close(Duration.ofSeconds(10));- AdminClient: introduce close(Duration)AdminClient API에도 close(Duration) 메서드가 도입되었습니다. 이 메서드는 주어진 시간 내에 AdminClient를 종료하도록 합니다. AdminClient를 종료할 때 타임아웃을 설정하여, 종료 작업이 무기한 지연되는 것을 방지할 수 있습니다.
AdminClient adminClient = AdminClient.create(props); // AdminClient 사용 adminClient.close(Duration.ofSeconds(10));
- 새로운 Serdes 및 기본 메서드 구현
- 새로운 Serdes(Serializer/Deserializer)와 기본 메서드 구현이 추가되었습니다. 이는 사용자 정의 데이터 타입의 직렬화 및 역직렬화를 지원합니다. Kafka에서 데이터를 주고받을 때, 데이터를 바이트 배열로 직렬화하거나 역직렬화하는 과정이 필요합니다. 새로운 Serdes는 이러한 작업을 더 쉽게 수행할 수 있도록 도와줍니다.
public class MyCustomType { private String field1; private int field2; // getters and setters } public class MyCustomTypeSerde extends Serdes.WrapperSerde<MyCustomType> { public MyCustomTypeSerde() { super(new JsonSerializer<>(), new JsonDeserializer<>(MyCustomType.class)); } }
- 명령 줄 도구 bin/kafka-topics.sh에 AdminClient 지원 추가
2.3.0
- 변경 내용
- KIP-461 레플리카 fetcher의 동작을 개선
- 특정 파티션에서 오류가 발생했을 때 전체 스레드가 종료되지 않고 해당 파티션만 드롭한 후 나머지 파티션에 대한 작업을 계속 진행합니다.
- Static Membership 적용
- 동적 멤버십은 Kafka는 기본적으로 그룹 멤버(예: 소비자)에게 임시 ID를 할당합니다. 이 ID는 멤버가 다시 시작하거나 재가입할 때마다 변경됩니다. ID가 변경되면 그룹 리밸런스가 발생하여 많은 작업이 재할당됩니다. 특히 상태가 큰 애플리케이션은 작업을 다시 복구하는 데 시간이 오래 걸려 일시적으로 가용성이 떨어질 수 있습니다.
- 정적 멤버십을 사용하면 그룹 멤버가 고유한 영구 ID를 가지게 됩니다. 이 ID는 멤버가 다시 시작해도 변경되지 않습니다. 고유한 ID 덕분에 멤버십이 변경되지 않아 불필요한 리밸런스가 발생하지 않습니다.
- incremental AlterConfigs API가 추가되었고, 기존의 AlterConfigs API는 폐기
- AlterConfigs API : 클러스터의 리소스(예: 토픽, 브로커, 사용자 등)의 구성(config)을 동적으로 변경할 수 있게 해주는 API
- 기존 API는 전체 브로커 구성을 변경해야 했기 때문에 비효율적이었습니다. 새로운 API는 특정 설정만 변경할 수 있도록 하여 더 효율적입니다.
- 최소 ISR(동기 복제본) 수 이하의 파티션 추적
- Kafka 1.1.0에서는 최소 ISR(In-Sync Replicas) 수 이하인 파티션을 추적할 수 있는 기능이 추가되었습니다.
- 최소 ISR 수를 충족하지 않는 상태가 계속되면 데이터 손실의 위험이 증가합니다. 이를 조기에 감지하고 해결함으로써 데이터 손실을 방지할 수 있습니다.
- 자동 토픽 생성을 선택적으로 비활성화
- Kafka 소비자가 브로커에서 자동 토픽 생성을 비활성화할 수 있는 기능이 추가되었습니다.
Properties props = new Properties(); props.put(ConsumerConfig.ALLOW_AUTO_CREATE_TOPICS_CONFIG, "false"); KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
- KIP-461 레플리카 fetcher의 동작을 개선
2.4.0
- 변경 내용
- 소비자가 가장 가까운 복제본에서 데이터를 가져올 수 있도록 허용합니다.
- 만약 소비자가 여러 데이터 센터에 걸쳐 있는 Kafka 클러스터에 연결되어 있다면, 소비자는 자신이 있는 데이터 센터에 가장 가까운 복제본에서 데이터를 가져올 수 있습니다. 이렇게 하면 데이터 전송 시간이 단축됩니다.
- 증분 협력 리밸런싱 지원합니다.
- 리밸런싱이 필요할 때 모든 소비자가 동시에 영향을 받지 않고, 일부 소비자만 영향을 받아 더 빠르게 리밸런싱이 완료
- MirrorMaker 2.0 (MM2)
- 두 개 이상의 데이터 센터가 있는 대기업이 각 데이터 센터에 있는 Kafka 클러스터 간에 데이터를 실시간으로 복제하고 동기화할 수 있습니다.
- Kafka 2.4.0에서는 파티션 재할당을 위한 새로운 Admin API가 추가
- 기존 방법: 기존에는 파티션 재할당을 수동으로 수행해야 했으며, 이 과정에서 문제가 발생하면 상태를 잃을 수 있었습니다.
- 새로운 방법: 새로운 Admin API를 사용하면 파티션 재할당을 자동화하고 더 안전하게 수행할 수 있습니다. 예를 들어, 클러스터 확장을 위해 새로운 브로커를 추가하고, 특정 파티션을 이 브로커로 옮겨야 할 때 Admin API를 사용하면 재할당 작업이 간편해집니다. 하지만, 업그레이드 중에는 이 작업을 시작하지 말아야 합니다. 업그레이드 도중에 재할당을 시작하면 상태가 손실될 위험이 있기 때문입니다.
- 스티키 파티셔닝
- 생산자가 메시지를 한 번 특정 파티션에 배정하면, 가능한 한 그 파티션에 계속해서 메시지를 보냅니다. 한 파티션에 가능한 많은 메시지를 보내기 때문에 배치 전송의 효율성이 높아집니다.
- 소비자가 가장 가까운 복제본에서 데이터를 가져올 수 있도록 허용합니다.
2.6.0
- 변경 내용
- client.dns.lookup 기본값 변경
- 설명: client.dns.lookup 설정의 기본값이 default에서 use_all_dns_ips로 변경되었습니다. 이는 호스트 이름이 여러 IP 주소로 해석되는 경우, 클라이언트가 각 IP에 순차적으로 연결을 시도하여 더 안정적인 연결을 보장합니다.
- 예시: 글로벌 웹 서비스가 여러 데이터 센터에 분산되어 운영되는 경우, 클라이언트가 특정 데이터 센터에 연결하는 데 문제가 생기면 다른 데이터 센터로 자동으로 연결을 시도할 수 있습니다. 이는 서비스 가용성을 높이는 데 도움이 됩니다.
- 성능 개선
- 브로커에 많은 수의 파티션이 있을 때 성능이 크게 개선되었습니다. 대규모 Kafka 클러스터에서 더 많은 파티션을 처리할 때도 일관된 성능을 유지할 수 있습니다.
- client.dns.lookup 기본값 변경
2.7.0
- 변경 내용
- 브로커 및 리스너 연결 속도 제한
- 브로커 전체 및 리스너별 연결 생성 속도 제한: 브로커 및 각 리스너별로 연결 생성 속도를 제한할 수 있는 기능이 추가되었습니다.
- 예시: 대규모 온라인 서비스가 여러 클라이언트로부터 높은 트래픽을 받을 때, 각 클라이언트가 브로커에 과도한 연결 요청을 보낼 수 있습니다. 이 경우 브로커의 자원이 고갈되어 성능 저하가 발생할 수 있습니다.
- 해결책: 브로커 및 리스너별로 연결 생성 속도를 제한하여 이러한 상황을 방지할 수 있습니다. 예를 들어, 브로커는 초당 100개의 연결만 허용하도록 설정할 수 있습니다. 이를 통해 브로커의 안정성을 유지하고 과부하를 방지할 수 있습니다.
- 클라이언트 발견 및 기능 게이팅 (KIP-584)
- 유연하고 운영하기 쉬운 솔루션: 클라이언트 발견, 기능 게이팅 및 롤링 업그레이드를 위한 유연하고 운영하기 쉬운 솔루션을 제공합니다.
- 새로운 브로커 기능이 추가된 경우, 모든 클라이언트가 이 기능을 지원하는지 확인해야 합니다. 브로커는 클라이언트가 지원하는 기능을 인식하고, 이를 기반으로 새로운 기능을 활성화할지 결정할 수 있습니다. 예를 들어, 브로커가 새로운 메시지 압축 형식을 지원하는 경우, 클라이언트가 이 형식을 지원하는지 확인하고, 지원하는 클라이언트에게만 이 기능을 활성화할 수 있습니다. 이를 통해 업그레이드 과정을 단순화하고, 클러스터의 안정성을 유지할 수 있습니다.
- 토픽 및 파티션 생성/삭제 제한 (KIP-599)
- 클러스터 보호: 클러스터가 과도한 토픽 및 파티션 생성/삭제 요청으로 인해 손상되지 않도록 보호하는 기능입니다.
- 예시: 개발자가 실수로 수천 개의 토픽을 생성하거나 삭제하는 스크립트를 실행할 경우, 클러스터는 이러한 대량 요청을 처리하지 못하고 중단될 수 있습니다.
- 해결책: KIP-599를 통해 클러스터가 한 번에 처리할 수 있는 생성/삭제 요청의 수를 제한할 수 있습니다. 예를 들어, 클러스터는 한 번에 최대 10개의 토픽 생성 요청만 처리하도록 설정할 수 있습니다. 이를 통해 클러스터의 안정성을 유지하고 개발자의 실수로 인한 중단을 방지할 수 있습니다.
- 브로커 및 리스너 연결 속도 제한
2.8.0
- 변경 내용
- ZooKeeper를 자체 관리 쿼럼으로 대체하는 초기 접근
- ZooKeeper 없이 Kafka 클러스터를 관리할 수 있는 초기 버전으로, 운영 복잡성을 줄이고 더 나은 일관성을 제공(아직은 비추천하는 기능)
- 토픽 식별자:
- 토픽에 고유한 식별자를 추가하여, 토픽을 보다 쉽게 식별하고 관리할 수 있게 되었습니다.
- ZooKeeper를 자체 관리 쿼럼으로 대체하는 초기 접근
3.0.0
- 변경 내용
- Kafka 프로듀서의 강력한 전달이 Default로 세팅
- Kafka 프로듀서의 강력한 전달 보장(strong delivery guarantees)이 기본적으로 활성화되었습니다. 이는 메시지가 브로커에 안전하게 전달되도록 보장하며, 데이터 손실을 방지합니다. ‘acks = all’이 default입니다.
- Kafka Raft 지원과 메타데이터 토픽의 스냅샷 기능(KRaft)
- ZooKeeper 없이 클러스터 메타데이터를 관리할 수 있습니다. 메타데이터 토픽의 특정 시점 상태를 스냅샷으로 저장합니다. 스냅샷을 사용하면 클러스터 재시작 시 빠르게 메타데이터를 복구할 수 있습니다.
- OffsetFetch 및 FindCoordinator 요청 최적화
- Kafka 3.0.0에서는 OffsetFetch와 FindCoordinator 요청이 최적화되어 성능이 향상되었습니다.
- OffsetFetch 요청: 소비자 그룹의 오프셋을 가져오는 요청으로, 각 파티션에서 마지막으로 처리된 메시지의 오프셋을 반환합니다.
- FindCoordinator 요청: 특정 소비자 그룹의 조정자 브로커를 찾는 요청입니다. 소비자 그룹 조정은 메시지 소비를 조정하는 중요한 역할을 합니다.
- 메시지 형식 v0 및 v1 사용 중단 → 메시지 형식 변화시 Client API 변화 있는지 확인해야 한다.
- Kafka 3.0.0에서는 오래된 메시지 형식 v0와 v1이 사용 중단되었습니다. 이는 최신 메시지 형식(v2)을 사용하도록 유도하기 위함입니다.
- 메시지 형식 v2: v2 형식은 성능과 기능이 향상되었으며, 다양한 최적화가 포함되어 있습니다.
- The deprecation of support for Java 8 and Scala 2.12
- Java 8 버전 Deprecation 예정.
- client의 Java 버전에도 영향이 있는지 공식적인 명시가 없는 상태 → 서버와 클라이언트의 Java 버전을 맞추는 것이 권장 사항
- Kafka 프로듀서의 강력한 전달이 Default로 세팅
3.1.0
- 변경 내용
- FetchRequest가 Topic ID를 지원 (KIP-516)
- FetchRequest에 Topic ID 지원 기능이 추가되었습니다. 이 기능은 브로커와 클라이언트 간의 통신에서 토픽 이름 대신 고유 식별자인 Topic ID를 사용할 수 있게 합니다.
- 고유한 Topic ID를 사용하여 데이터를 요청할 수 있습니다. 이 방법은 토픽 이름이 변경되거나 충돌하는 경우에도 안정적으로 작동합니다.
- 브로커 수 메트릭 추가 (KIP-748)
- Kafka 클러스터의 브로커 수를 모니터링할 수 있는 새로운 메트릭이 추가되었습니다. 이 메트릭을 사용하면 클러스터 내의 브로커 수를 쉽게 확인하고 관리할 수 있습니다.
- 대규모 Kafka 클러스터를 운영할 때 브로커 수가 변경되면 이를 즉시 파악하여 대응할 수 있습니다.
- Java 17지원
- FetchRequest가 Topic ID를 지원 (KIP-516)
3.2.0
- 변경 내용
- log4j 1.x가 reload4j로 대체(KIP-801) → 현재 1.0.1에서 사용되는 log4j 버전 확인 필요
- log4j 1.x는 보안 문제로 인해 더 이상 사용되지 않으며, 이를 대신해 reload4j가 사용
- StandardAuthorizer for KRaft (KIP-801)
- Kafka Raft (KRaft) 모드에서 사용할 수 있는 새로운 권한 부여 방식인 StandardAuthorizer가 도입되었습니다. 이를 통해 KRaft 모드에서의 보안 설정이 간편해지고, 권한 관리를 일관되게 유지할 수 있습니다.
- 파티션 리더에게 파티션 복구 힌트를 보내기 (KIP-704)
- 클라이언트가 파티션 리더에게 파티션 복구를 위한 힌트를 보낼 수 있는 기능이 추가되었습니다. 이를 통해 파티션 리더가 데이터 복구 작업을 더 효율적으로 수행할 수 있습니다.
- Kafka 브로커 중 하나가 실패하여 재시작할 때, 클라이언트가 해당 브로커에게 특정 파티션의 복구가 필요하다는 힌트를 보내면, 브로커는 이를 기반으로 복구 작업을 신속하게 수행합니다.
- JoinGroupRequest와 LeaveGroupRequest에 이유가 첨부 (KIP-800)
- 소비자가 그룹에 가입할 때, "새로운 컨슈머 인스턴스 시작" 또는 "기존 인스턴스 복구" 등의 이유를 첨부할 수 있습니다.
- 소비자가 그룹을 떠날 때, "애플리케이션 종료" 또는 "컨슈머 인스턴스 장애" 등의 이유를 기록하여 나중에 분석할 수 있습니다.
- 정적 멤버십 프로토콜을 사용하면 리더가 할당을 건너뜀 (KIP-814)
- 정적 멤버십을 사용하면, 새로운 소비자가 그룹에 추가되거나 기존 소비자가 제거될 때마다 리더가 재할당 작업을 수행할 필요가 없습니다.
- 예를 들어, 정적 멤버십을 사용하는 컨슈머 그룹에서 특정 컨슈머 인스턴스가 일시적으로 오프라인이 되더라도, 기존 할당 정보가 유지되어 다른 인스턴스가 영향을 받지 않습니다.
- 컨슈머 인스턴스가 일시적으로 오프라인이 되더라도, 기존의 할당된 파티션을 유지하여 재할당(rebalance) 과정을 건너뛰게 합니다. 이를 통해 컨슈머 그룹의 안정성과 성능을 크게 향상시킬 수 있습니다.
- log4j 1.x가 reload4j로 대체(KIP-801) → 현재 1.0.1에서 사용되는 log4j 버전 확인 필요
3.3.1
- 변경 내용
- KRaft 프로덕션 준비 상태 KIP-833
- KRaft가 이제 프로덕션 환경에서 사용할 수 있도록 준비되었습니다.
- KRaft 기반의 Kafka 클러스터를 새로운 버전의 KRaft로 업그레이드하는 절차가 정의됐습니다.
- KRaft 컨트롤러 쿼럼의 건강 상태를 모니터링하는 기능을 도입됐습니다.
- Strictly Uniform Sticky Partitioner KIP-794
- 스티키 파티셔너 개선
- 기존 스티키 파티셔너의 버퍼링 장점을 유지하면서도, 메시지의 균일한 분산을 추가로 고려
- 일정 시간이나 메시지 수가 지나면, 현재 파티션의 부하를 다른 파티션과 비교. 만약 다른 파티션들이 덜 사용되었으면, 덜 사용된 파티션으로 전환하여 메시지 전송
- KRaft 프로덕션 준비 상태 KIP-833
3.4.0
- 변경 내용
- ZooKeeper에서 KRaft로의 마이그레이션(초기 엑세스) KIP-866
- Kafka 클러스터를 ZooKeeper 모드에서 KRaft 모드로 마이그레이션할 수 있는 기능을 추가
- 브로커를 한 번에 하나씩 KRaft 모드로 재시작하여 중단 없는 마이그레이션 가능.
- Time based cluster metadata 스냅샷 KIP-876
- KIP-876은 일정 시간마다 클러스터 메타데이터의 스냅샷을 생성하는 새로운 속성을 추가
- 주기적으로 메타데이터의 스냅샷을 생성하여, 장애 발생 시 메타데이터 복구
- "generation" 필드 consumer protocol에 추가 KIP-792
- 소비자 프로토콜에 "generation" 필드를 추가
- 필드는 소비자가 마지막으로 안정적인 세대(generation)에 속해 있었던 시점
- 사용 예시 : 소비자 A와 소비자 B가 같은 소비자 그룹에 속해 있고, 두 소비자가 특정 파티션에 대한 소유권을 주장하고 있다고 가정해 보겠습니다. 그룹 리더는 각 소비자로부터 받은 세대 정보를 비교하여 어떤 소비자가 해당 파티션에 대해 최신 클레임을 가지고 있는지 결정할 수 있습니다. 이를 통해 파티션 할당이 더 효율적이고 정확하게 이루어집니다.
- 프로듀서 ID 만료를 위한 별도 구성 KIP-854
- 프로듀서 ID의 만료를 보다 효율적으로 관리하기 위해 별도의 구성 설정을 도입
- producer.id.expiration.ms 파라미터를 통해 프로듀서 ID의 만료 시간을 독립적으로 설정
- 이전에는 Kafka에서 프로듀서 ID와 트랜잭션 ID의 만료가 동일한 설정을 따랐습니다. 즉, transactional.id.expiration.ms 파라미터가 프로듀서 ID와 트랜잭션 ID의 만료 시간을 함께 제어했습니다. 이는 불필요하게 많은 메모리를 사용할 수 있었고, 특히 대규모 클러스터에서 문제가 될 수 있었습니다.
- Kafka 소비자를 위한 랙 인식 파티션 할당 KIP-881
- 소비자가 파티션 할당 및 리밸런싱 시 랙을 인식할 수 있도록 프로토콜을 확장
- 데이터 가용성과 내구성을 높일 수 있습니다. 랙 인식 파티션 할당은 랙, 데이터센터 또는 기타 물리적 위치를 고려하여 소비자에게 파티션을 할당합니다.
- ZooKeeper에서 KRaft로의 마이그레이션(초기 엑세스) KIP-866
3.5.0
- 변경 내용
- KRaft 브로커 인증을 위한 SCRAM 지원 추가 KIP-900
- KRaft 모드의 Kafka 브로커 간 인증을 위해 SCRAM(Simple Authentication and Security Layer) 메커니즘을 구성하는 기능을 추가
- KRaft 모드에서 SCRAM 인증을 설정하면, kafka-storage.sh 스크립트를 사용하여 브로커 간의 보안 인증을 설정할 수 있습니다. 이를 통해 브로커 간 통신이 안전하게 유지됩니다.
- 오래된 브로커 에포크를 가진 복제본이 ISR에 가입하지 않도록 함 KIP-903
- 브로커 에포크(Broker Epoch)는 Kafka에서 각 브로커의 현재 상태나 시점을 나타내는 숫자
- 브로커가 비정상적으로 종료된 후 다시 시작될 때 오래된 데이터를 가진 복제본이 ISR에 포함되지 않도록 함으로써, 데이터 손실을 방지하고 클러스터의 일관성을 유지할 수 있습니다.
- KRaft 브로커 인증을 위한 SCRAM 지원 추가 KIP-900
3.6.0
- 변경 내용
- 메모리 최적화 KIP-863
- 역직렬화 시 byte[] 대신 ByteBuffer를 사용하여 메모리 할당을 줄이고 메모리 성능을 개선
- 업데이트된 공개 인터페이스에는 Deserializer 클래스, ByteBufferDeserializer 클래스, StringDeserializer 클래스가 포함
- Zookeeper 3.8.2로 업그레이드 KIP-902
- ZooKeeper 버전을 3.8.2로 업그레이드합니다. 새 버전에는 여러 업데이트와 보안 개선 사항이 포함되어 있습니다.
- 서버 측 트랜잭션 방어 KIP-890
- hanging transactions은 트랜잭션이 완료되지 않고 중단된 상태로 남아있는 경우를 말합니다.
- hanging transactions 방지를 위해 파티션 추가를 검증하는 기능을 도입
- IPv4/IPv6에 대한 중복 리스너 수락 KIP-797
- KIP-797을 통해 브로커는 서로 다른 IP 스택(IPv4와 IPv6)에서 동일한 포트로 리스너를 구성할 수 있습니다.
- 메타데이터 트랜잭션 KIP-868
- 이전에는 KRaft 레이어에서 메타데이터 트랜잭션이 없었으며, Raft 합의 레이어에서 페치 크기 제한으로 인해 대규모 원자적 기록 세트를 처리하기 어려웠습니다.
- 메타데이터 트랜잭션을 도입하여, BeginTransaction, Number of records, EndTransaction 또는 AbortTransaction으로 구성됩니다. 이는 Raft 합의 레이어에서 원자적 기록 배치를 사용하는 메커니즘을 제공합니다. 마커 기록을 도입하여 더 큰 원자적 기록 세트를 여러 배치로 처리할 수 있게 합니다.
- KRaft 성능 측정을 위한 추가 메트릭 KIP-938
- KIP-938은 새로운 컨트롤러, 로더, 스냅샷 방출기 KRaft 성능 메트릭을 추가합니다. 이를 통해 성능 모니터링과 최적화가 가능해집니다.
- 메시지 타임스탬프 유효성 검사 개선 KIP-937
- 메시지 타임스탬프에 대한 추가적인 유효성 검사 로직을 도입하여, 데이터 무결성을 강화하고 잘못된 타임스탬프 처리를 방지
- 미래의 타임스탬프는 잘못된 형식일 수 있으므로 이를 거부하고 예외
- 원격 로그 세그먼트에 대한 추가 사용자 정의 메타데이터 KIP-917
- 원격 로그 세그먼트에 추가적인 사용자 정의 메타데이터를 포함할 수 있는 기능을 도입
// 예시 코드: 사용자 정의 메타데이터를 포함한 RemoteStorageManager의 copyLogSegmentData() 메서드 public class CustomRemoteStorageManager implements RemoteStorageManager { @Override public void copyLogSegmentData(LogSegmentData segmentData) { Map<String, String> customMetadata = new HashMap<>(); customMetadata.put("creationTime", "2023-06-01T12:00:00Z"); customMetadata.put("source", "data-source-1"); segmentData.setCustomMetadata(customMetadata); // 원격 저장소로 데이터 복사 로직 } }
- 메모리 최적화 KIP-863
3.7.0
- 변경 내용
- 소비자 리밸런스 프로토콜의 차세대 버전 KIP-848
- 새로운 간소화된 소비자 리밸런스 프로토콜은 복잡성을 소비자에서 브로커의 그룹 코디네이터로 이동시키고, 프로토콜을 점진적으로 변경
- 리더 발견 최적화 KIP-951
- 파티션의 새로운 리더를 클라이언트가 발견하는 시간을 최적화하여, 리더십 변경(브로커 재시작, 파티션 재할당 등)이 발생할 때 생산/페치 요청의 엔드 투 엔드 지연 시간을 줄입니다.
- 공식 Apache Kafka Docker 이미지 제공 KIP-975
- Java 11 지원 중단 예정 KIP-1013
- Kafka 브로커에 대한 Java 11 지원이 사용 중단(dprecated)으로 표시되었으며, Kafka 4.0에서는 지원이 중단될 예정입니다
- 클라이언트는 계속해서 JDK 11 이상을 사용하여 Kafka 브로커에 연결할 수 있습니다.
- 클라이언트 메트릭 및 관측 KIP-714
- 운영자가 클러스터에 연결된 클라이언트의 성능 및 상태를 더 잘 모니터링할 수 있도록 클라이언트 수준의 메트릭을 표준화된 텔레메트리 인터페이스를 통해 제공
- Kafka 클라이언트를 위한 지수 백오프 KIP-580
- 브로커가 과부하 상태이거나 일시적인 네트워크 문제로 인해 요청이 실패할 수 있습니다. 클라이언트는 이러한 실패한 요청을 재시도(retry)하게 됩니다. 이때 클라이언트가 재시도하는 간격을 백오프(backoff) 시간이라고 합니다.
- 클라이언트의 재시도 백오프 시간을 고정된 시간에서 지수 증가 시간으로 변경
- 브로커가 과부하 상태일 때 클라이언트가 요청을 점진적으로 느리게 보내어 브로커에 부담을 줄이는 효과
- 티어드 스토리지의 추가 메트릭 KIP-963
- 티어드 스토리지는 Kafka에서 데이터를 로컬 브로커의 디스크에 저장하는 대신 원격 저장소(예: 클라우드 스토리지)에 저장할 수 있는 기능
- KIP-963은 티어드 스토리지 기능을 위해 새로운 메트릭을 도입하여, 성능을 더 잘 모니터링하고 문제를 해결하며 예방할 수 있도록 합니다.
- 오래된 Client Protocol API 버전 제거 KIP-896
- Apache Kafka 2.1 이전의 모든 클라이언트 요청 API 버전을 사용 중단(deprecated)으로 표시하고, Apache Kafka 4.0에서 이러한 요청 버전에 대한 지원을 완전히 제거
- Apache Kafka 2.1 이전의 모든 클라이언트 요청 API 버전을 사용 중단(deprecated)으로 표시
- 소비자 리밸런스 프로토콜의 차세대 버전 KIP-848
kafka broker와 kafka-clients 호환성
kafka를 사용하기 위해 메시지를 받고 전송하는 broker와 API를 제공하는 kafka-clients 버전이 달라도 되나 고민이 되었다. kafka broker와 kafka-clients 호환성에 대해 다음 블로그를 참고하여 조사하였다.
Client and broker compatibility across Kafka versions
An overview on client and broker version compatibility. Maintaining compatibility across different Kafka clients and brokers is a common issue. Mismatches among client and broker versions can occur as part of any of the following scenarios: Upgrading your
docs.cloudera.com
https://www.conduktor.io/kafka/kafka-broker-and-client-upgrades/
https://www.conduktor.io/kafka/kafka-broker-and-client-upgrades/
www.conduktor.io
https://cwiki.apache.org/confluence/display/KAFKA/Compatibility+Matrix
Compatibility Matrix - Apache Kafka - Apache Software Foundation
KIP-35 - Retrieving protocol version introduced a mechanism for dynamically determining the functionality of a Kafka broker and KIP-97: Improved Kafka Client RPC Compatibility Policy introduced a new compatibility policy and guarantees for the Java clie
cwiki.apache.org
Kafka 버전의 주요(minor) 변경 사항에 따른 클라이언트와 브로커 간의 호환성은 다음과 같이 요약할 수 있다.
- 주요(minor) 버전 차이:
- Kafka 버전의 주요(minor) 부분에서 변화가 있는 경우, 클라이언트와 브로커는 완전히 호환되지 않을 수 있다. 이는 특정 기능이 사용할 수 없게 될 수 있다는 것을 의미한다.
- 예를 들어, Kafka 2.3.x 클라이언트는 2.4.x 브로커와는 완전히 호환되지 않을 수 있다.
- 유지 보수(maintenance) 버전 차이:
- 유지 보수(maintenance) 버전 간의 차이는 호환성을 결정하는 데 고려되지 않는다. 이는 유지 보수 업데이트가 주로 버그 수정이나 소규모 개선사항을 포함하고 있기 때문이다.
- 예를 들어, Kafka 2.3.1 클라이언트는 2.3.2 브로커와 호환됩니다.
- 버전 1.0.0 이후의 호환성:
- Kafka 버전 1.0.0 이후의 모든 클라이언트와 브로커는 기본적으로 호환된다. Cloudera Runtime에서 제공하는 모든 클라이언트와 브로커 버전도 호환된다.
- 이 경우, 오래된 클라이언트 버전이 새로운 브로커 버전과 통신할 수는 있지만, 일부 기능에는 제한이 있을 수 있다.
3번 조건에 따라 Kafka의 클라이언트와 브로커 버전 간 호환성은 주요(minor) 버전에서 차이가 나는 경우 일부 기능이 사용 불가능할 수 있지만, 기본적인 기능은 사용 가능하다는 것을 의미한다. 유지 보수(maintenance) 버전 차이는 호환성에 큰 영향을 미치지 않는다.
하지만 그럼에도 클라이언트와 브로커 버전 간 호환을 맞추는 것을 추천한다. 새로운 기능을 사용하고 싶지만 클라이언트 API에서 지원하지 않아 사용에 제한이 생길 수 있기 때문이다.
현재 프로젝트에서는 모든 카프카 브로커를 중단시키고 쉽게 업그레이드가 가능했다. 만약 무중단으로 브로커 클러스터를 업그레이드 해야 되면 공식 document에 upgrade 부분를 보고 따라하면 된다.
https://kafka.apache.org/documentation/#upgrade
Apache Kafka
Apache Kafka: A Distributed Streaming Platform.
kafka.apache.org
'kafka' 카테고리의 다른 글
| 협력적 스티키 파티션 할당 전략 (0) | 2024.07.08 |
|---|---|
| static membership (0) | 2024.07.08 |
| 리더 에포크 (0) | 2024.07.08 |
| Kafka 기초 및 명령어 (0) | 2024.07.08 |