Kafka 시니어 데이터베이스 기술면접
새 면접Q. Kafka를 이벤트 소싱 패턴의 영구 저장소로 사용할 때, 기존 RDBMS와 비교하여 데이터 모델링 관점에서 어떤 차이점이 있으며, 특히 스냅샷 전략과 컴팩션 정책을 어떻게 설계하시겠습니까?
이벤트의 불변성과 시간순 저장 특성, 그리고 log compaction의 동작 방식을 고려해보세요.
Kafka는 append-only 로그 구조로 이벤트를 불변 방식으로 저장하므로, RDBMS의 UPDATE/DELETE 기반 모델과 근본적으로 다릅니다. 데이터 모델링 시 엔티티의 현재 상태가 아닌 상태 변경 이벤트를 저장하며, 집계된 상태는 Consumer가 재구성합니다. 스냅샷 전략은 특정 시점의 상태를 별도 토픽에 저장하거나, 주기적으로 컴팩티드 토픽에 전체 상태 이벤트를 발행하는 방식으로 구현합니다. Log compaction은 cleanup.policy=compact로 설정하여 동일 키의 최신 값만 유지하도록 하며, 이를 통해 무한 증가하는 이벤트 로그를 관리 가능한 크기로 유지합니다. 실무에서는 segment.ms, min.cleanable.dirty.ratio 등의 파라미터를 조정하여 컴팩션 주기와 스토리지 효율성의 균형을 맞춥니다.
- • Append-only 로그 구조와 이벤트 불변성 원칙
- • 스냅샷을 통한 상태 재구성 성능 최적화
- • Log compaction을 활용한 스토리지 관리 전략
- • cleanup.policy와 관련 파라미터 튜닝
대규모 전자상거래 시스템에서 주문 이력을 이벤트 소싱으로 관리하면서 스토리지 비용을 최적화해야 할 때 사용됩니다.
Log compaction 사용 시 tombstone 메시지는 언제, 어떻게 활용하며, delete.retention.ms 설정이 중요한 이유는 무엇입니까?
Q. Kafka는 전통적인 데이터베이스의 인덱스 구조를 제공하지 않습니다. 수억 건의 메시지가 저장된 Kafka 토픽에서 특정 조건의 메시지를 빠르게 검색해야 하는 요구사항이 있을 때, 어떤 아키텍처 패턴과 보조 저장소를 활용하시겠습니까?
Kafka의 offset 기반 순차 읽기 특성과 CQRS 패턴, 그리고 외부 인덱스 저장소의 조합을 생각해보세요.
Kafka는 offset 기반 순차 접근만 지원하므로, 랜덤 액세스가 필요한 경우 CQRS 패턴으로 별도의 읽기 모델을 구축해야 합니다. Kafka Connect를 활용하여 Elasticsearch나 Solr 같은 검색 엔진으로 메시지를 싱크하고, 전문 검색과 복잡한 쿼리는 검색 엔진에서 처리합니다. 또는 Kafka Streams나 ksqlDB로 materialized view를 생성하여 RocksDB 기반 상태 저장소에 인덱스를 구축할 수 있습니다. 메시지 키 설계 시 검색 기준을 파티션 키로 활용하면 특정 파티션만 스캔하여 성능을 개선할 수 있습니다. 실무에서는 검색 빈도, 지연 허용도, 데이터 일관성 요구사항에 따라 동기/비동기 싱크 방식을 선택하고, 듀얼 라이트 문제를 방지하기 위해 Kafka를 단일 진실 공급원으로 유지합니다.
- • CQRS 패턴으로 읽기/쓰기 모델 분리
- • Kafka Connect를 통한 검색 엔진 싱크
- • Kafka Streams의 materialized view 활용
- • 파티션 키 설계를 통한 검색 범위 최소화
실시간 로그 분석 시스템에서 특정 사용자나 에러 코드로 빠르게 검색할 수 있는 인터페이스를 제공해야 할 때 사용됩니다.
Kafka Connect를 사용할 때 exactly-once 시맨틱을 보장하면서 Elasticsearch와 동기화하려면 어떤 설정과 전략이 필요합니까?
Q. Kafka의 트랜잭션 기능을 사용하여 여러 토픽에 원자적으로 메시지를 발행하는 시나리오에서, 프로듀서 장애 발생 시 좀비 인스턴스 문제와 트랜잭션 타임아웃을 어떻게 처리하며, 컨슈머 측에서는 어떤 설정으로 정확히 한 번(exactly-once) 처리를 보장하시겠습니까?
transactional.id의 역할과 isolation.level, 그리고 프로듀서 펜싱 메커니즘을 고려해보세요.
Kafka 트랜잭션은 transactional.id를 통해 프로듀서 인스턴스를 고유하게 식별하고, epoch 번호를 증가시켜 이전 인스턴스를 펜싱(fencing)함으로써 좀비 문제를 해결합니다. transaction.timeout.ms는 브로커가 트랜잭션을 자동으로 중단하는 시간으로, 애플리케이션의 처리 시간보다 충분히 길게 설정해야 하며 기본값 15분을 상황에 맞게 조정합니다. 컨슈머는 isolation.level=read_committed로 설정하여 커밋된 메시지만 읽도록 하고, enable.auto.commit=false로 수동 커밋을 사용합니다. Exactly-once를 위해서는 컨슈머도 트랜잭션 프로듀서가 되어 read-process-write 패턴을 하나의 트랜잭션으로 묶어야 하며, 이를 위해 Kafka Streams나 직접 트랜잭션 API를 사용합니다. 재시작 시 동일한 transactional.id를 사용하여 이전 트랜잭션을 자동으로 중단시키고 새로운 epoch로 시작합니다.
- • transactional.id와 epoch 기반 프로듀서 펜싱
- • transaction.timeout.ms 적절한 설정
- • isolation.level=read_committed 사용
- • read-process-write 패턴의 트랜잭션 통합
금융 시스템에서 계좌 이체 이벤트를 출금 토픽과 입금 토픽에 동시에 발행하면서 원자성을 보장해야 할 때 사용됩니다.
트랜잭션 사용 시 성능 오버헤드는 어느 정도이며, 어떤 상황에서 트랜잭션을 사용하지 않는 것이 더 나은 선택일 수 있습니까?
Q. Kafka 컨슈머 그룹에서 동일한 파티션의 메시지를 여러 컨슈머가 동시에 처리하지 못하도록 하는 내부 메커니즘은 무엇이며, 이로 인해 발생할 수 있는 처리량 병목 현상을 해결하기 위한 설계 전략은 무엇입니까?
파티션 할당과 컨슈머 그룹의 관계, 그리고 파티셔닝 전략을 고려해보세요.
Kafka는 컨슈머 그룹 내에서 하나의 파티션을 최대 하나의 컨슈머만 할당받도록 보장하여, 파티션 레벨에서 순서 보장과 동시성 제어를 수행합니다. 이는 그룹 코디네이터가 리밸런싱을 통해 관리하며, 컨슈머 수가 파티션 수보다 많으면 일부 컨슈머는 유휴 상태가 됩니다. 처리량 병목을 해결하려면 먼저 토픽의 파티션 수를 증가시켜 더 많은 컨슈머가 병렬로 처리할 수 있도록 합니다. 파티션 키를 적절히 설계하여 부하를 균등하게 분산시키고, 핫 파티션을 방지합니다. 단일 파티션 내에서도 처리량을 높이려면, 컨슈머가 메시지를 빠르게 폴링한 후 내부 스레드 풀로 비동기 처리하되, 오프셋 커밋은 순서를 보장하도록 관리해야 합니다. 순서 보장이 필요 없는 경우 파티션 키 없이 라운드로빈으로 분산시킬 수 있습니다.
- • 파티션당 하나의 컨슈머 할당 원칙
- • 파티션 수 증가를 통한 병렬성 확보
- • 파티션 키 설계로 부하 분산
- • 컨슈머 내부 스레드 풀 활용
실시간 주문 처리 시스템에서 특정 상품의 주문이 폭증하여 해당 파티션의 처리가 지연될 때 확장 전략을 수립할 때 사용됩니다.
파티션 수를 운영 중에 증가시킬 때 기존 메시지의 파티션 분포와 컨슈머에 어떤 영향을 미치며, 주의해야 할 점은 무엇입니까?
Q. Kafka 클러스터에서 특정 토픽의 프로듀서 지연(latency)이 급증하는 현상이 발생했습니다. 브로커의 페이지 캐시, 배치 설정, acks 정책, 그리고 파티션 리더 분산 관점에서 진단하고 최적화할 수 있는 방법들을 설명해주세요.
OS 레벨 캐시 활용, 네트워크 왕복 최소화, 복제 대기 시간, 브로커 부하 분산을 각각 고려해보세요.
먼저 브로커의 페이지 캐시 히트율을 확인하고, 메모리가 부족하면 불필요한 토픽 삭제나 retention 정책 조정으로 캐시 효율을 높입니다. 프로듀서의 linger.ms와 batch.size를 조정하여 더 큰 배치로 전송하면 네트워크 왕복을 줄이고 처리량을 높일 수 있지만, 지연시간과의 트레이드오프를 고려해야 합니다. acks=all 설정은 모든 ISR 복제 완료를 기다리므로 지연이 증가하는데, min.insync.replicas를 조정하거나 용도에 따라 acks=1로 완화할 수 있습니다. 파티션 리더가 특정 브로커에 집중되어 있는지 kafka-reassign-partitions 도구로 확인하고, 리더 재분산을 통해 부하를 균등하게 배치합니다. compression.type을 설정하여 네트워크 대역폭을 절약할 수 있지만 CPU 사용량이 증가하므로 상황에 맞게 선택합니다. JVM 가비지 컬렉션 로그를 분석하여 GC pause가 지연의 원인인지도 확인해야 합니다.
- • 페이지 캐시 효율성과 메모리 관리
- • 배치 설정을 통한 네트워크 최적화
- • acks와 복제 정책의 지연 트레이드오프
- • 파티션 리더 재분산을 통한 부하 균등화
대규모 IoT 센서 데이터 수집 시스템에서 초당 수십만 건의 이벤트를 처리하면서 p99 지연시간을 100ms 이하로 유지해야 할 때 사용됩니다.
프로듀서의 buffer.memory가 가득 차서 blocking이 발생하는 상황에서는 어떤 파라미터들을 조정하고, 애플리케이션 레벨에서는 어떻게 대응해야 합니까?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!