Engineering Note
Rednote는 왜 Kafka를 Fluss로 바꿨나: 실시간 인덱싱 전환에서 얻은 교훈
Rednote의 핵심 실시간 인덱싱 경로에서 Kafka가 만든 읽기 증폭과 과거 데이터 재처리 병목, Fluss 전환 구조와 성과, 다른 파이프라인에 적용할 조건을 정리합니다.
Rednote(샤오홍슈)는 핵심 실시간 인덱싱 경로의 Kafka를 Fluss로 옮기고 있습니다. Kafka를 전면 교체하려는 결정은 아닙니다. 검색·추천·광고 서비스가 함께 읽는 다수 열을 가진 테이블에서 전체 행 전송과 과거 데이터 재처리가 만든 비용을 해결하기 위한 선택입니다.
이 사례가 중요한 이유는 “어느 브로커가 더 빠른가”를 비교하지 않기 때문입니다. 이벤트 데이터가 다수 열을 가진 테이블 형태로 쌓이고, 여러 서비스가 그중 일부 열만 읽으며, 과거 데이터를 이용해 인덱스를 자주 재구축한다면 메시지 전달 경로는 사실상 반복 조회용 데이터 저장소가 됩니다. Rednote는 이처럼 쓰임새와 구조가 어긋난 문제를 Kafka 증설이 아니라 데이터 경로 변경으로 풀었습니다.
Rednote 사례 한눈에 보기
| 구분 | 내용 |
|---|---|
| 대상 | 검색·추천·광고 서비스가 서로 다른 열을 읽는 핵심 실시간 인덱싱 경로 |
| 기존 문제 | 전체 행 전송에 따른 읽기 증폭, 느린 과거 데이터 읽기, 실시간 조회 서비스와 인덱스 재구축 작업의 자원 경쟁 |
| 전환 | Apache Arrow 형식으로 Fluss에 기록하고, 실시간 조회 서비스는 필요한 열만 조회하며, 과거 데이터는 객체 저장소에서 직접 읽음 |
| 데이터 레이크 | 같은 실시간 데이터를 Paimon에 기록해 두 경로의 병행 검증, 데이터 탐색, 과거 데이터 활용에 사용 |
| 공개 성과 | CPU 약 30% 감소, 쓰기 데이터 전송량 약 50% 감소, 인덱스 구축 시간 약 50~80% 단축, 실시간 조회 서비스가 사용하는 네트워크 대역폭 약 30~90% 절감, 최고 처리량 약 3배 |
| 검증 방식 | Kafka 성능을 기준으로 한 부하 시험, 장기간 병행 운영, 단계적 트래픽 전환 |
이 수치는 다수 열을 가진 실시간 인덱스 테이블을 다루는 Rednote의 환경에서 측정한 결과입니다. 모든 Kafka 작업에 그대로 적용되는 성능 보장은 아닙니다. Rednote의 Kafka→Fluss 전환 사례
전환 전: 서로 다른 세 가지 읽기 작업이 Kafka에 몰렸다
Rednote에서는 앞단의 데이터 처리 플랫폼이 여러 실시간 조회 서비스가 사용할 다수 열을 가진 테이블을 Kafka에 기록했습니다. 실시간 조회 서비스는 Kafka에서 최신 데이터를 읽고, 전체·증분 인덱스 구축 작업은 로컬 디스크와 객체 저장소에 보관된 데이터를 다시 읽었습니다. 하나의 Kafka 경로가 실시간 데이터 전달과 장기 보관 데이터 읽기, 인덱스 구축을 모두 떠안았습니다.
문제 1. 일부 열만 필요해도 전체 행을 읽어야 했다
검색·추천·광고 서비스가 필요로 하는 열은 서로 달랐습니다. 하지만 Rednote의 Kafka 기반 구조에서는 일부 열만 필요해도 테이블의 전체 행을 전송하고 처리했습니다. 같은 테이블을 읽는 서비스가 늘수록 사용하지 않는 데이터도 반복해서 네트워크를 통과했습니다.
Rednote가 공개한 일부 인덱싱 작업에서는 데이터를 읽는 서비스가 늘면서 읽기 증폭이 약 1,000배에 이르렀습니다. 이 정도면 불필요한 전체 행 전송이 서비스 하나의 문제가 아니라 네트워크와 계산 자원 전반의 문제로 이어집니다.
문제 2. 과거 데이터도 브로커를 거쳐야 했다
인덱스 재구축에는 최신 이벤트만으로 충분하지 않습니다. 객체 저장소에 있는 과거 데이터를 대량으로 다시 읽어야 합니다. 기존 구조에서는 클라이언트가 객체 저장소의 데이터를 곧바로 읽지 못하고 Kafka 브로커를 거쳐 전달받았습니다.
이 경유 과정은 과거 데이터 읽기를 느리게 만들 뿐 아니라, 실시간 전달을 담당하는 브로커가 대규모 과거 데이터 조회까지 처리하게 했습니다.
문제 3. 인덱스 재구축이 실시간 조회 서비스와 경쟁했다
전체·증분 인덱스 구축 작업은 높은 동시성으로 과거 데이터를 읽습니다. 이 작업이 브로커의 네트워크 대역폭과 페이지 캐시를 사용하면서 지연에 민감한 실시간 조회 서비스와 경쟁했습니다. 핵심 문제는 Kafka의 절대 성능이 아니라 성격이 다른 두 작업을 같은 읽기 경로에 올린 데 있었습니다.
전환 후: Fluss가 데이터 접근 방식에 맞춰 경로를 나눴다
두 그림은 Apache Fluss의 Rednote 전환 사례 원문에서 인용했습니다. 원문은 Apache License 2.0으로 배포됩니다. 세부 글자가 작다면 전환 전 그림과 전환 후 그림을 원본 크기로 볼 수 있습니다.
변화 1. 전체 행 전송을 필요한 열 읽기로 바꿨다
앞단의 데이터 처리 플랫폼은 Apache Arrow 형식으로 Fluss에 기록합니다. 실시간 조회 서비스는 테이블의 전체 행 대신 자신에게 필요한 열만 읽습니다. 데이터를 읽는 서비스가 많고 테이블의 열이 많을수록 읽지 않아도 되는 데이터를 줄이는 효과도 커집니다.
여기서 중요한 점은 Kafka가 언제나 행 형식만 지원한다는 뜻이 아니라는 것입니다. Rednote가 사용하던 테이블 기록·소비 방식이 전체 행 전송을 반복했고, Fluss의 열 기반 스트리밍 저장 구조가 해당 접근 방식에 더 잘 맞았다는 의미입니다.
변화 2. 과거 데이터가 Kafka 브로커를 거치지 않게 했다
인덱스 구축 작업은 객체 저장소의 Fluss 로그 파일을 직접 읽을 수 있습니다. 대규모 과거 데이터 조회가 Kafka 브로커를 거치지 않으므로 인덱스 구축 작업이 브로커의 네트워크 대역폭과 캐시를 놓고 실시간 조회 서비스와 경쟁하지 않습니다. 최신 데이터를 읽는 경로와 과거 데이터를 병렬로 재처리하는 경로가 분리된 것입니다.
변화 3. Paimon을 검증과 과거 활용 경로로 연결했다
Rednote는 Fluss의 Lakestream을 이용해 같은 실시간 데이터를 Apache Paimon에도 기록했습니다. 전환 과정에서는 기존 경로와 새 경로를 함께 운영하며 결과를 비교하고 데이터를 탐색했습니다. 이후에는 과거 데이터 재처리와 오프라인 분석, 일괄 인덱스 구축에 활용할 수 있는 기반이 됐습니다.
이 부분도 단순히 저장소 하나를 추가한 것으로 보면 안 됩니다. 실시간 경로와 과거 데이터 경로를 분리하면서도 같은 데이터를 비교하고 검증할 수 있는 공통 기반을 만든 것이 핵심입니다.
공개된 성과는 경로 변경 전체의 결과다
Rednote가 공개한 개선은 쓰기, 실시간 조회 서비스의 데이터 읽기, 인덱스 구축에서 함께 나타났습니다.
| 영역 | 공개된 결과 | 직접 연결되는 변화 |
|---|---|---|
| 쓰기 경로 | CPU 약 30% 감소, 쓰기 데이터 전송량 약 50% 감소 | Arrow 기반 기록과 인덱싱 작업에 맞춘 데이터 저장 구조 |
| 인덱스 구축 | 전체·증분 구축 시간 약 50~80% 단축 | 객체 저장소의 과거 데이터를 병렬로 읽고 Kafka 브로커 경유 제거 |
| 실시간 데이터 읽기 | 네트워크 대역폭 약 30~90% 절감, 최고 처리량 약 3배 | 필요한 열만 읽어 전체 행의 반복 전송 감소 |
이 수치를 “Fluss는 Kafka보다 항상 몇 배 빠르다”로 일반화해서는 안 됩니다. Rednote는 데이터 형식, 읽기 경로, 과거 데이터 접근, 데이터 레이크 연결을 함께 바꿨습니다. 공개 성과는 이 전체 변화가 특정 인덱싱 작업에서 만든 결과입니다.
Rednote 사례에서 일반화할 수 있는 전환 조건
Rednote와 비슷한 조건이 겹칠수록 Kafka 기반 결과 전달 경로를 Fluss로 바꿀 근거가 커집니다.
| 확인할 조건 | Rednote에서 나타난 모습 |
|---|---|
| 결과 테이블이 다수 열로 구성되어 있는가 | 검색·추천·광고 서비스가 다수 열을 가진 인덱스 테이블 하나를 공유 |
| 서비스마다 필요한 열이 다른가 | 서비스별로 일부 열만 사용하지만 기존에는 전체 행을 전송 |
| 같은 데이터를 반복해서 읽는 규모가 큰가 | 여러 실시간 조회 서비스가 같은 데이터를 읽으면서 일부 작업의 읽기 증폭이 약 1,000배까지 증가 |
| 과거 데이터를 자주 대량으로 읽는가 | 전체·증분 인덱스 구축 작업이 객체 저장소의 오랜 데이터를 조회 |
| 과거 데이터 읽기가 실시간 조회 서비스와 경쟁하는가 | 브로커 대역폭과 페이지 캐시를 공유해 실시간 조회 서비스에 영향 |
| 결과를 실시간과 데이터 레이크에서 함께 쓰는가 | Fluss의 실시간 데이터 읽기와 Paimon 기반 검증·탐색·과거 활용을 함께 운영 |
Flink나 Spark가 만든 다수 열의 파생 결과를 Kafka에 기록하고, 여러 서비스와 인덱스 작업이 그 결과를 반복해서 읽는다면 Rednote와 비슷한 구조가 될 수 있습니다. 다만 이는 Rednote가 공개한 구성도를 그대로 복제한다는 뜻이 아니라, 사례에서 확인한 데이터 접근 방식을 다른 파이프라인에 적용하는 것입니다.
Kafka를 남겨야 하는 경계
Rednote 사례도 Kafka 전면 교체의 근거가 되지는 않습니다. 다음과 같은 경로는 Kafka가 여전히 자연스럽습니다.
- 외부 서비스와의 계약이 토픽·파티션·컨슈머 그룹을 중심으로 잡혀 있습니다.
- Kafka Connect나 기존 Kafka 클라이언트가 수집과 전달의 핵심입니다.
- Kafka 컨슈머별 재시도, DLQ(실패 메시지 보관 큐), 이벤트 순서처럼 메시지 전달 과정의 제어가 중요합니다.
- 결과가 반복해서 조회하는 테이블이 아니라 독립 서비스에 전달할 명령이나 알림입니다.
- 실시간 조회 서비스가 읽을 필요가 없고 분석만 한다면 Fluss를 추가하지 않고 데이터 레이크에 직접 기록하는 편이 단순합니다.
따라서 질문은 “Kafka를 없앨 수 있는가”가 아닙니다. 이 Kafka 경로가 여전히 메시지를 전달하는가, 아니면 다수 열을 가진 테이블을 반복 조회하고 과거 데이터를 다시 읽는 저장 경로가 되었는가를 먼저 판단해야 합니다.
Rednote가 보여 준 전환 순서
Rednote는 성능 시험 하나만으로 핵심 경로를 바꾸지 않았습니다.
- 중요한 Kafka 성능 지표를 기준으로 부하 시험을 수행했습니다.
- 기존 경로와 Fluss 경로를 장기간 병행 운영하며 데이터 정확성을 비교했습니다.
- 검증을 통과한 일부 핵심 작업부터 트래픽을 단계적으로 옮겼습니다.
- 테이블 관리, 다중 테넌시, 모니터링·알림, 데이터 계보, 클러스터 운영, 백업과 데이터 레이크 적재 관리도 함께 준비했습니다.
공개 당시 단일 테이블은 하루 약 10억 건, 10TB를 처리하고 있었습니다. Rednote는 2026년 하반기에 100개가 넘는 테이블로 이전 범위를 넓힐 계획도 밝혔습니다. 수치 자체보다 중요한 것은 이 규모에서도 Kafka 기준 부하 시험, 두 경로의 병행 운영, 단계적 전환을 생략하지 않았다는 점입니다. Rednote의 전환 검증과 확장 계획
다른 조직도 읽기 증폭이나 과거 재처리 경쟁이 큰 결과 경로 하나부터 시작하는 편이 안전합니다. 지연·처리량·비용뿐 아니라 중복과 누락, 스키마 변경, 장애 뒤 복구 결과를 함께 검증한 뒤 데이터를 읽는 서비스를 옮겨야 합니다.
Kafka 운영에서는 토픽·파티션·Kafka 컨슈머 랙(아직 처리하지 않은 레코드 수)을 보지만, Fluss 전환 뒤에는 테이블 상태, 객체 저장소로의 데이터 이동, 데이터 레이크 적재, 처리 작업의 상태까지 관측 범위가 넓어집니다. Konduo는 Kafka와 Fluss 같은 데이터 플랫폼을 플러그인으로 연결해 상태와 메트릭, 알림 대응을 한 흐름에서 관리하도록 설계된 통합 관리 운영 플랫폼입니다. 단계적 전환에서는 기존 경로와 새 경로의 운영 지표를 함께 비교할 수 있어야 합니다.
마무리: Rednote가 교체한 것은 Kafka 전체가 아니라 맞지 않게 된 데이터 경로다
Rednote의 Kafka→Fluss 전환은 범용 브로커 성능 비교가 아닙니다. 다수 열을 가진 테이블에서 여러 서비스가 일부 열만 읽고, 과거 데이터를 이용해 인덱스를 자주 재구축하며, 그 작업이 실시간 조회 서비스와 같은 자원을 쓰는 구간을 바꾼 사례입니다.
Fluss는 이 구간에서 필요한 열만 읽게 하고, 과거 데이터 읽기를 객체 저장소 경로로 분리하며, Paimon을 검증과 과거 활용 경로로 연결했습니다. 그 결과 쓰기 비용, 실시간 조회 서비스의 네트워크 대역폭, 인덱스 구축 시간, 최고 처리량이 함께 개선됐습니다.
따라서 Rednote 사례에서 얻을 수 있는 결론은 명확합니다. Kafka 토픽이 메시지 전달을 넘어 다수 열을 가진 결과 테이블의 전달과 반복 조회, 과거 데이터 재처리까지 맡고 있다면, Kafka를 더 확장하기 전에 데이터 접근 방식 자체가 Fluss에 더 잘 맞는지 검토할 가치가 있습니다.
함께 읽기 좋은 글
- Apache Fluss란: Kafka·Flink·Iceberg 사이의 스트리밍 레이크하우스 — Kafka, Flink, Iceberg, Fluss가 데이터 경로에서 맡는 역할을 비교합니다.
- Apache Fluss 첫 실행: Flink Quickstart에서 확인할 것들 — Flink SQL로 Fluss의 Log Table과 Primary Key Table을 직접 확인합니다.
- 센서 이벤트에 빠진 현재 상태를 붙이는 방법: fluss-go 데이터 보강 — Fluss 테이블을 실시간 데이터 보강에 사용하는 예제를 다룹니다.