쏘카 데이터엔지니어링팀이 서버 로그를 BigQuery에 적재하는 파이프라인을 KDS+Firehose+Airflow 배치 구조에서 MSK+커스텀 Python Consumer 스트리밍 구조로 전환했다. 분류 비효율·신선도 부족·스키마 관리 부재 3가지 문제를 동시에 해결하며 데이터 지연을 1~2시간에서 약 3분으로 단축했다.
핵심 포인트- 기존 구조: KDS → Firehose → S3 → Airflow → GCS(타입별 분류) → BigQuery, 전 타입 처리 후 선별이라 S3/GCS 이중 중복 저장 발생
- 문제 3가지: 전 타입 분류 후 선별 비효율, Airflow 배치 1~2시간 신선도 한계, Schema Registry 없어 스키마 변경 시 수기 BigQuery 업데이트
- 전환 전략: KDS → MSK(Schema Registry 연동), Firehose+Airflow → 커스텀 Python Consumer, S3+GCS 이중 저장 → GCS 단일 SSOT
- Firehose 불채택: MSK 소스 설정 시 Dynamic Partitioning 불가, 메시지 변환에 Lambda 추가 필요 → 오버엔지니어링
- Kafka-connect 불채택: kafka-connect-protobuf-converter가 oneof 필드 파싱 시 모든 선택지를 null 포함 출력, Java/Kotlin 유지보수 부담
- Python ProtobufDeserializer 한계: Schema Registry 인자를 받지 않아 Writer Schema 교차검증 불가, 필드명 달라도 역직렬화 통과해 스키마 정합성 검증 불완전
상세 정리- Protobuf oneof 전략: 수백 개 로그 타입을 1개 상위 Log 메시지 + oneof data로 묶어 대분류별 1개 토픽 관리(토픽 수 최소화)
- Buf 도입: Protobuf 린팅·포맷팅·호환성검사·코드생성 자동화, bq-schema 플러그인으로 BigQuery 스키마 자동 생성
- 커스텀 Python Consumer(confluent-kafka): 버퍼 크기·버퍼 간격·DLQ 대상(MSK/PubSub)·파티션 키 조합(n개 컬럼)·적재 대상(S3/GCS) 설정 가능
- GCS 파티셔닝: type+timestamp 기준으로 gs://log/type=CREATE_SOCAR/ymd=2024-12-31/hour=23/uuid.json 형태 적재
- BigQuery View Table: GCS External Table(준실시간) + BigQuery 내부 테이블(일 배치)을 View로 결합해 신선도와 쿼리 성능 동시 확보
- 스키마 변경 프로세스: Protobuf 통합 레포 PR → GitHub Actions 린팅/호환성검사 → 개발 환경 테스트 → Python/Java 클래스 재생성·배포
- Writer/Reader Schema 교차검증: Protobuf Wire Format은 Tag Number+Wire Type만 포함, 필드명·메시지 구조 달라도 역직렬화 통과
- 결과: 신선도 1~2시간 → 약 3분, 네이버 제휴 서비스 로그 신규 파이프라인으로 안정 운영 중
왜 읽나MSK+Protobuf+커스텀 Consumer로 배치 파이프라인을 스트리밍으로 전환한 전 과정을 Firehose·Kafka-connect 불채택 이유와 Python Deserializer 한계까지 기술 결정 근거와 함께 정리한 데이터 엔지니어링 실전 사례다.