Kafka 데이터에 대한 SQL은 스트리밍 엔진이 필요하지 않다

발행: (2026년 1월 14일 오후 04:55 GMT+9)
10 min read
원문: Dev.to

Source: Dev.to

위에 제공된 Source 링크만 포함되어 있으며 번역할 실제 텍스트가 제공되지 않았습니다. 번역이 필요한 전체 내용(마크다운 형식 포함)을 알려주시면 한국어로 번역해 드리겠습니다.

소개

스트림 처리 엔진은 실제 문제를 해결했습니다: 무한한 데이터에 대한 지속적인 계산. Flink, ksqlDB, 그리고 Kafka Streams는 팀에게 커스텀 컨슈머를 작성하지 않고도 이벤트 스트림에 대해 SQL‑과 유사한 쿼리를 실행할 수 있는 방법을 제공했습니다.

그 솔루션의 운영 비용은 널리 인정받고 있습니다. Confluent의 공식 문서에서는 Flink가 “성능 튜닝이나 체크포인트 실패 해결과 같은 배포 및 클러스터 운영에 어려움을 초래한다”고 언급하고, “Flink를 사용하는 조직은 이를 개발하고 유지 관리하는 전담 전문가 팀이 필요할 가능성이 높다”고 설명합니다.

팀이 Kafka 데이터에 대해 묻는 질문의 상당 부분에 대해 더 간단한 아키텍처가 존재합니다: 객체 스토리지의 불변 세그먼트에 대한 SQL.

일반적인 Kafka 쿼리

운영 디버깅 세션 및 운영 검토에서 질문이 반복됩니다:

  • 현재 이 토픽에 무엇이 있나요?
  • 사고 발생 기간에 무슨 일이 있었나요?
  • 이 키를 가진 메시지는 어디에 있나요?
  • 모든 파티션이 여전히 데이터를 생산하고 있나요?

이것들은 스트리밍 문제가 아닙니다. 과거 데이터에 대한 제한된 조회이며, 한 번 실행되고 종료되며, 윈도우, 워터마크, 체크포인트 또는 상태 복구가 필요하지 않습니다.

Kafka의 저장 모델

  • Kafka는 레코드를 개별적으로 영구 저장하지 않습니다. 레코드를 로그 세그먼트에 추가하고, 해당 세그먼트를 크기나 시간에 따라 롤링합니다.
  • 각 파티션은 순서가 보장된, 불변의 레코드 시퀀스입니다. 세그먼트가 닫히면 더 이상 변경할 수 없습니다.
  • Kafka는 희소 인덱스를 유지하여 독자가 오프셋과 타임스탬프를 효율적으로 탐색할 수 있게 합니다. 각 세그먼트 파일에는 가벼운 오프셋 및 타임스탬프 인덱스가 함께 제공되어, 소비자가 전체 파일을 스캔하지 않고도 특정 메시지 위치로 바로 이동할 수 있습니다.
  • 보존 정책은 전체 세그먼트를 삭제하고, 컴팩션은 세그먼트를 재작성합니다. 이는 Kafka 데이터가 이미 SQL‑on‑files 데이터셋처럼 정리되어 있음을 의미합니다. 차이점은 파일이 어디에 저장되는가뿐입니다.

Kafka 3.6.0부터 티어드 스토리지를 통해 이러한 세그먼트를 객체 스토리지(예: S3)에 저장할 수 있습니다. Kafka 3.9.0에서는 이 기능이 프로덕션 수준으로 준비되어, 데이터 모델을 변경하지 않고도 내구성을 컴퓨팅과 분리할 수 있습니다.

스트리밍 엔진의 오버헤드

스트리밍 엔진은 대부분의 쿼리가 절대 사용하지 않는 기능에 비용을 지불합니다:

  • 분산 상태 백엔드
  • 조정된 체크포인트
  • 워터마크 추적
  • 장기 클러스터 작업

이 비용은 연속 집계, 조인, 실시간 추론에는 정당하지만 “마지막 10개의 메시지를 보여줘”와 같은 경우에는 낭비됩니다.

운영 경험

Riskified는 ksqlDB에서 Flink로 마이그레이션하면서, ksqlDB의 스키마 진화에 대한 엄격한 제한 때문에 실제 프로덕션 사용 사례에 비현실적이며, 운영 복잡성 때문에 시스템과 협력하기보다 시스템과 싸워야 했다고 언급했습니다.

Confluent와 Redpanda의 벤더 설문조사에 따르면 전체 Kafka 클러스터의 약 56 %가 1 MB/s 이하로 실행됩니다. 대부분의 Kafka 사용은 소규모 데이터이지만, 팀은 대규모 데이터 운영 비용을 지불하고 있습니다.

불변 세그먼트에 대한 쿼리 플래닝

Kafka 데이터가 희소 인덱스를 가진 불변 세그먼트로 존재한다면, 이를 쿼리하는 방식은 다른 SQL‑on‑files 워크로드와 동일합니다.

쿼리 플래너 단계

  1. 토픽을 세그먼트 파일로 매핑합니다.
  2. 타임스탬프 또는 오프셋 메타데이터로 필터링합니다.
  3. 관련 세그먼트만 읽습니다.
  4. 프레디케이트를 적용하고 결과를 반환합니다.

소비자 그룹도 없고, 오프셋 커밋도 없으며, 스트리밍 작업 라이프사이클도 없습니다.

예시 쿼리

-- Last 10 messages
SELECT * FROM orders TAIL 10;
-- Time‑bounded scan
SELECT * FROM orders
WHERE ts BETWEEN '2026-01-08 09:00' AND '2026-01-08 09:05';
-- Key lookup with recent window
SELECT * FROM orders
WHERE key = 'order-12345'
  AND ts >= now() - interval '24 hours';

이것들은 스트림 처리와는 달리 SQL 의미를 갖는 인덱싱된 파일 접근입니다.

Performance Considerations

Object storage is slower than broker‑local disk; remote storage typically has higher latency than local block storage. For most debugging and ops workflows, a one‑ or two‑second latency is acceptable, whereas waiting minutes to deploy or restart a streaming job is not.

If you need sub‑second continuous results, use a streaming engine. That boundary is clear.

비용 관리

SQL을 객체 스토리지에서 사용할 때 주요 위험은 무제한 스캔입니다. 객체 스토리지 요금은 저장된 데이터 양과 발생한 API 호출 수에 따라 결정됩니다.

책임 있는 시스템은 각 쿼리가 다음을 보고하도록 해야 합니다:

  • 읽히게 될 세그먼트 수
  • 스캔될 바이트 수
  • 예상 요청 비용

시간 제한이 없는 쿼리는 명시적인 옵트‑인(opt‑in)이 필요하도록 하여, 비용이 예상치 못한 것이 아니라 의식적인 선택이 되도록 해야 합니다.

스트리밍 엔진을 사용해야 할 때

스트리밍 엔진은 다음과 같은 경우에 적합한 도구입니다:

  • 연속 집계
  • 실시간 스트림 조인
  • 실시간 스코어링
  • 정확히 한 번 출력

대부분의 Kafka 상호작용은 위에 해당하지 않습니다. 이는 더 나은 인터페이스가 없어서 조회 및 검사를 스트리밍 인프라에 강제로 넣은 경우입니다.

결론

Kafka 데이터가 불변 세그먼트로 영구화되면, SQL이 더 간단한 도구가 됩니다. 대부분의 팀은 Kafka 질문에 답하기 위해 스트리밍 엔진이 필요하지 않으며, 불변 데이터를 쿼리할 수 있는 깔끔하고 제한된 방법이 필요합니다. Kafka 세그먼트에 대한 SQL이 바로 그것을 제공합니다.

보다 깊이 있는 글은 에서 읽어보세요.

Back to Blog

관련 글

더 보기 »

기술은 구원자가 아니라 촉진자다

왜 사고의 명확성이 사용하는 도구보다 더 중요한가? Technology는 종종 마법 스위치처럼 취급된다—켜기만 하면 모든 것이 개선된다. 새로운 software, ...

에이전틱 코딩에 입문하기

Copilot Agent와의 경험 나는 주로 GitHub Copilot을 사용해 인라인 편집과 PR 리뷰를 수행했으며, 대부분의 사고는 내 머리로 했습니다. 최근 나는 t...