실무에서 Kafka를 운영하다 보면 Not Enough Replica
문제로 인해 메시지가 유실되는 경우를 경험할 수 있습니다. 이는 데이터의 내결함성과 가용성을 저하시키며, 시스템의 신뢰성을 위협할 수 있습니다. 이 블로그에서는 Spring Kafka Admin을 활용하여 Kafka 토픽 설정을 검증하고 Not Enough Replica
문제를 해결하는 방법을 안내합니다.
Not Enough Replica
문제는 Kafka 클러스터에서 특정 토픽의 파티션에 대해 설정된 복제본(replica)이 충분하지 않을 때 발생합니다. 이 문제는 주로 다음과 같은 경우에 발생할 수 있습니다:
1. 복제 인수(Replica Factor)가 너무 낮게 설정된 경우.
2. 최소 인-싱크 복제본(min.insync.replicas) 값이 적절히 설정되지 않은 경우.
3. 브로커 실패로 인해 일부 복제본이 오프라인 상태인 경우.
예를 들어, 복제 인수가 2로 설정된 토픽이 있다고 가정해 봅시다. 이 토픽의 파티션에 대해 최소 인-싱크 복제본 값이 2로 설정된 경우, 두 개의 복제본이 모두 정상적으로 동작해야만 메시지가 손실되지 않습니다. 그러나 만약 하나의 브로커가 다운되거나 네트워크 문제가 발생하면 복제본의 수가 최소 인-싱크 복제본 수보다 적어져 메시지 유실이 발생할 수 있습니다.
Spring Kafka Admin을 사용하여 토픽의 복제 인수와 파티션 수, 그리고 min.insync.replicas
설정을 검증하는 방법을 살펴보겠습니다. 아래는 이를 구현하는 예제 코드입니다:
예시 코드 일뿐 회사 코드와 관련이 없습니다.👻
import org.apache.kafka.clients.admin.AdminClient;
import org.apache.kafka.clients.admin.AdminClientConfig;
import org.apache.kafka.clients.admin.DescribeTopicsResult;
import org.apache.kafka.clients.admin.TopicDescription;
import org.apache.kafka.clients.admin.Config;
import org.apache.kafka.clients.admin.DescribeConfigsResult;
import org.apache.kafka.common.config.ConfigResource;
import org.apache.kafka.common.config.TopicConfig;
import java.util.Collections;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
public class KafkaTopicValidator {
private final AdminClient adminClient;
public KafkaTopicValidator(String bootstrapServers) {
Properties config = new Properties();
config.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
this.adminClient = AdminClient.create(config);
}
public boolean validateTopic(String topicName) throws ExecutionException, InterruptedException {
// 토픽 설명 가져오기
DescribeTopicsResult describeTopicsResult = adminClient.describeTopics(Collections.singletonList(topicName));
TopicDescription topicDescription = describeTopicsResult.values().get(topicName).get();
// 토픽 설정 가져오기
ConfigResource configResource = new ConfigResource(ConfigResource.Type.TOPIC, topicName);
DescribeConfigsResult describeConfigsResult = adminClient.describeConfigs(Collections.singletonList(configResource));
Config topicConfig = describeConfigsResult.values().get(configResource).get();
// 복제 인수 추출
int replicaFactor = topicDescription.partitions().get(0).replicas().size();
// 토픽 설정에서 min.insync.replicas 값 추출
String minInSyncReplicasStr = topicConfig.get(TopicConfig.MIN_IN_SYNC_REPLICAS_CONFIG).value();
int minInSyncReplicas = Integer.parseInt(minInSyncReplicasStr);
// 조건 검증
return replicaFactor >= minInSyncReplicas;
}
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Usage: KafkaTopicValidator <bootstrap-servers> <topic-name>");
System.exit(1);
}
String bootstrapServers = args[0];
String topicName = args[1];
KafkaTopicValidator validator = new KafkaTopicValidator(bootstrapServers);
try {
boolean isValid = validator.validateTopic(topicName);
if (isValid) {
System.out.println("The topic configuration is valid.");
} else {
System.out.println("The topic configuration is invalid.");
}
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
} finally {
validator.adminClient.close();
}
}
}
AdminClient
인스턴스를 생성합니다.min.insync.replicas
값을 가져옵니다.min.insync.replicas
값보다 크거나 같은지 비교합니다.💡 TIP
min.in.sync.replicas값이 타이트하면 broker에 장애가 났을때 이벤트 발행이 실패됨.
여유 있게 설정하기!
Kafka 토픽의 올바른 구성을 보장하는 것은 메시지 유실을 방지하고, event platform의 신뢰성을 높이는 데 필수적입니다. Spring Kafka Admin을 활용하면 이 검증 과정을 자동화하고 Kafka 토픽이 최적으로 구성되었는지 확인할 수 있습니다. 실무에서 이러한 문제를 사전에 방지함으로써 안정적이고 효율적인 Kafka 운영을 유지할 수 있습니다.
여건이 된다면, 인프라팀에서 SRE를 위해 관련 검증서버를 람다로 띄워 관리 하는 것도
어플리케이션의 코드 중복을 줄이고 신뢰성 있는 서비스로 나이가는 방향일 듯 합니다!
💡 TIP
현재 저희 팀에서도 위의 옵션 외에도 토픽의 존재여부 등을 어플리케이션 실행 시점에 검증중이며, 실패시 어플리케이션이 뜨지 않도록 설계했습니다.
질문이 있거나 추가 도움이 필요하시면 언제든지 연락주세요!