Apache Iggy, Rust로 다시 쓴 메시지 스트리밍의 새로운 가능성

|Platform Decision|20분 읽기

또 하나의 메시지 브로커가 필요할까?

메시지 스트리밍 분야는 사실상 Apache Kafka의 독점 시장입니다. 2011년 링크드인이 오픈소스로 공개한 이후 15년이 지난 지금까지도 흔들리지 않고 있죠. 금융권에서 OpenAPI나 결제 이벤트를 다룰 때도, 결국 큐나 스트리밍 얘기가 나오면 첫 후보는 늘 Kafka였습니다. 그만큼 안정적이고, 그만큼 무겁기도 합니다.

그래서 Apache Iggy라는 프로젝트 이름을 처음 봤을 때 솔직히 시큰둥했습니다. 또 하나의 메시지 브로커가 정말 필요한가 싶었거든요. 그런데 Rust로 처음부터 새로 짰고, 초당 수백만 개의 메시지를 처리한다는 이야기를 듣고 나니 한번 뜯어보지 않을 수 없더라고요.

이 프로젝트는 2023년 4월 Piotr Gankiewicz가 시작했습니다. 시작 배경이 개발자라면 공감할 만한데요. Piotr는 Rust를 제대로 배우고 싶었고, 무언가를 직접 만들어보는 게 가장 빠른 학습법이라고 봤습니다. RabbitMQ, ZeroMQ, Kafka, Aeron 같은 분산 시스템을 다뤄본 경험을 밑천 삼아 메시지 스트리밍 플랫폼을 짜기로 한 거죠. 도구를 쓰는 입장과 만드는 입장은 보이는 게 완전히 다릅니다. 직접 만들어본 사람은 브로커가 어디서 비용을 흘리는지 안에서부터 알게 되거든요.

단순한 학습 프로젝트로 출발한 것이 지금은 GitHub에서 거의 4,000개의 스타를 받았고, 2025년 2월에는 Apache Incubator에 찬성 21표, 반대 0표로 선정됐습니다. 만장일치라는 점이 흥미롭습니다. 참고로 프로젝트 이름 'Iggy'는 이탈리안 그레이하운드(Italian Greyhound)의 줄임말입니다. Piotr가 이 견종을 두 마리 키우는데, 작지만 엄청나게 빠른 개들이라고 하더군요. 작고 가볍고 빠르다. 프로젝트가 노리는 지점과 정확히 겹치는 이름입니다.

Iggy는 정확히 무엇인가?

Iggy는 메시지 브로커가 아니라 지속적인 메시지 스트리밍 플랫폼입니다. 이 구분이 중요한데요. 성격으로 보면 RabbitMQ보다 Kafka 쪽에 훨씬 가깝습니다. 스트림, 토픽, 파티션, 세그먼트라는 유사한 개념 모델을 쓰기 때문에, Kafka를 운영해본 사람이라면 머릿속 지도를 거의 그대로 옮겨올 수 있어요.

진짜 차이는 내부 아키텍처에 있습니다. Iggy는 코어당 스레드를 두고 공유 리소스를 없앤(shared-nothing) 아키텍처io_uring으로 I/O를 처리하는 Rust로 만들어졌습니다. 용어가 복잡하게 들리지만, 핵심만 추리면 이렇습니다. 코어 사이에서 락을 잡고 자원을 나눠 쓰느라 생기는 경합을 구조적으로 줄이고, 최신 Linux 커널의 비동기 I/O를 끝까지 활용해 성능을 짜내겠다는 설계입니다.

가비지 컬렉터도 없고, JVM도 없고, 리소스 사용량도 Kafka에 비해 훨씬 적습니다. Kafka를 운영해본 사람은 GC 스톱이나 힙 튜닝, JVM 메모리 산정에 들어간 시간을 기억할 겁니다. 그 층 자체가 없다는 건 운영 관점에서 꽤 큰 의미죠. 초기 사용자들은 TCP로 초당 2천만 개의 메시지를 처리했다고 보고했는데, 역사가 짧은 프로젝트치고는 눈에 띄는 수치입니다.

2025년 12월 출시된 0.6.0 버전은 중요한 분기점이었습니다. 개발팀이 서버를 완전히 재작성해서, Tokio 기반 비동기 런타임에서 io_uring과 compio를 쓰는 완료 기반(completion-based) 모델로 갈아탔거든요. 런타임 모델을 통째로 바꾸는 건 결코 가벼운 결정이 아닙니다. 이미 돌아가는 프로젝트의 심장을 들어내는 일이니까요. 그럼에도 벤치마크가 그 도박을 정당화합니다. 적절한 하드웨어에서 5,000MB/s를 넘는 처리량과 1밀리초 미만의 P99 지연시간을 달성했다고 합니다.

프로토콜의 유연성이 인상적이다

개인적으로 가장 눈여겨본 건 전송 프로토콜의 유연성입니다. Iggy는 QUIC, TCP, WebSocket, HTTP를 모두 TLS와 함께 지원합니다. 각각의 용도가 분명해서 상황에 맞게 고를 수 있어요.

  • TCP: 사용자 정의 바이너리 프로토콜에서 최고의 성능 제공
  • QUIC: 데이터 손실이 잦은 네트워크에서 지연시간 감소에 유리
  • WebSocket: 브라우저 연결이 필요할 때 활용
  • HTTP: 통합 및 디버깅을 위한 표준 REST API 제공

클라이언트가 붙는 방식에서 이 정도 선택지를 준다는 건 실제 운영에서 생각보다 큰 장점입니다. 내부 서비스 간에는 TCP로 성능을 짜내고, 브라우저나 외부 통합은 WebSocket과 HTTP로 받고, 디버깅은 REST로 찔러보는 식으로 한 플랫폼 안에서 경로를 나눌 수 있으니까요. 보통은 이런 걸 맞추려고 앞단에 게이트웨이를 한 겹 더 두게 되는데, 그 층이 줄어든다는 의미입니다.

여기에 더해 Iggy는 스키마를 강제하지 않고 바이너리 데이터를 그대로 다루는 제로 카피(zero-copy) 직렬화를 씁니다. 직렬화/역직렬화 과정에서 새는 오버헤드를 줄여 성능을 끌어올리는 방식이죠. 다만 이건 양날의 검이기도 합니다. 스키마 강제가 없다는 건 데이터 계약을 플랫폼이 지켜주지 않는다는 뜻이라, 포맷 관리 책임이 애플리케이션 쪽으로 넘어옵니다. 성능을 가져가는 대신 규율을 직접 세워야 하는 트레이드오프입니다.

실제로 써보기

시작은 생각보다 간단합니다. Docker 이미지를 받아 실행하거나, CLI 도구를 설치해 바로 테스트할 수 있어요. cargo install iggy-cli 후 터미널에서 iggy만 치면 됩니다.

시작 가이드는 Rust로 프로듀서와 컨슈머 애플리케이션을 만드는 과정을 단계별로 안내하는데, 문서 완성도가 꽤 괜찮습니다. 기본 자격 증명은 루트 사용자 기준 사용자 이름 iggy, 비밀번호 iggy이고, 루트는 모든 권한을 가집니다. 여기서 권한을 세분화한 추가 사용자를 만들 수 있어요. 당연한 얘기지만, 이 기본 계정은 테스트용입니다. 프로덕션에 그대로 올리면 안 됩니다.

간단한 시나리오를 따라가 보면 구조가 한눈에 들어옵니다. 한 "프로듀서"가 알림 메시지를 보내고, 다른 "컨슈머"가 그걸 받아 어떤 작업을 처리하는 흐름이죠. Docker에 들어 있는 CLI만으로 전체 과정을 5분이면 훑어볼 수 있습니다.

1단계: Iggy 서버 시작

git clone https://github.com/apache/iggy.git 
cd iggy 
# 간편 기본 로그인 설정
export IGGY_ROOT_USERNAME=iggy 
export IGGY_ROOT_PASSWORD=iggy   
# 서버를 백그라운드에서 시작
docker compose up -d

서버가 뜨면 데이터는 local_data 폴더에 저장되므로 재부팅 후에도 유지됩니다.

2단계: 스트림과 토픽 생성

새 터미널을 열고 다음 명령어를 실행합니다:

docker exec -it iggy-server /iggy --username iggy --password iggy stream create notifications  
docker exec -it iggy-server /iggy --username iggy --password iggy topic create notifications alerts 1 none

여기서 notifications는 전체 메일함(일련의 메시지), alerts는 그 안의 특정 채널("토픽")이라고 보면 됩니다.

3단계: 메시지 전송

docker exec -it iggy-server /iggy --username iggy --password iggy message send --partition-id 1 notifications alerts "Iggy에서 인사드립니다! 사용자가 오후 8시 6분에 로그인했습니다."

이 명령은 원하는 만큼 반복 실행할 수 있고, 실행할 때마다 새 메시지가 들어갑니다.

4단계: 메시지 수신

다른 터미널에서:

docker exec -it iggy-server /iggy --username iggy --password iggy message poll --consumer 1 --offset 0 --message-count 5 --auto-commit notifications alerts 1

메시지가 곧바로 출력됩니다. 컨슈머는 새 메시지를 "폴링"하며 루프 안에서 계속 돌 수 있어요.

10개도 안 되는 명령어로 프로듀서 → 스트리밍 서버 → 컨슈머 파이프라인을 세운 셈입니다. 개념을 손으로 확인하기에는 이 정도 진입장벽이 딱 좋습니다.

방금 일어난 일을 정리하면:

  • 데이터 프로듀서: 데이터를 밀어넣는 모든 주체(앱, 센서, 다른 서비스 등)
  • 스트림 + 토픽: 메시지가 섞이지 않게 정리된 폴더
  • 컨슈머: 데이터를 꺼내 쓰는 모든 주체(대시보드, 이메일 발송기, 분석 도구 등)
  • 메시지 지속성: 사용자가 지울 때까지 서버에 남음(보존 기간은 사용자가 제어)

SDK와 개발 생태계

Rust, C#, Java, Go, Python, Node.js용 SDK를 제공하고, C++과 Elixir용은 개발 중입니다. 예상대로 Rust SDK가 가장 잘 다듬어져 있어요. 프로듀서 생성 API는 깔끔합니다. 클라이언트를 설정하고, 스트림과 토픽을 지정하고, 배치와 파티셔닝을 구성한 뒤 전송을 시작하는 흐름입니다.

컨슈머 쪽도 비슷한 패턴이고, 메시지 순서 보장과 연결된 클라이언트 간 수평 확장을 처리하는 컨슈머 그룹을 지원합니다. 이 부분은 Kafka와 개념이 거의 같아서 기존 운영 감각을 그대로 끌어다 쓸 수 있어요. 새 플랫폼을 검토할 때 이런 '익숙한 모델'이 있느냐 없느냐는 도입 결정에서 의외로 큰 무게를 차지합니다. 팀이 처음부터 다시 배워야 하는 비용이 곧 도입 비용이니까요.

스트림, 토픽, 파티션 관리와 메시지 탐색을 위한 웹 UI가 별도 Docker 이미지로 제공됩니다(apache/iggy-web-ui). 개발 중에 데이터 흐름을 눈으로 확인할 수 있어서 디버깅이 한결 수월합니다.

최근에는 커넥터 프레임워크도 붙었습니다. Rust로 Source 또는 Sink 트레이트를 구현해 사용자 정의 데이터 파이프라인을 만들 수 있어요. 0.6.0에서는 Apache Iceberg, Elasticsearch, Apache Flink용 커넥터가 추가됐는데, 자기 안에서만 도는 플랫폼이 아니라 바깥 데이터 생태계와 붙으려 한다는 신호로 읽힙니다. 결국 메시징 인프라의 가치는 얼마나 빨리 보내느냐만이 아니라, 주변 시스템과 얼마나 매끄럽게 연결되느냐에서 갈리거든요.

흥미로운 건 MCP(모델 컨텍스트 프로토콜) 서버까지 포함돼 있다는 점입니다. LLM에 컨텍스트를 넘겨주는 용도인데, 지금 당장 핵심 기능은 아니어도 방향을 어디에 두고 있는지 보여주는 대목입니다.

현재의 한계와 향후 계획

솔직히 짚고 넘어가야 할 약점이 하나 있습니다. 아직 클러스터링이 없다는 점이죠. Iggy는 현재 단일 노드로만 돌고, Viewstamped Replication 기반 클러스터링은 향후 지원 예정입니다.

이건 가볍게 볼 문제가 아닙니다. 고가용성이 전제인 프로덕션, 특히 금융권처럼 단일 장애점을 용납하지 않는 환경에서는 단일 노드라는 사실 하나만으로 후보에서 빠질 수 있어요. 노드가 죽으면 그대로 멈추는 구조니까요. 개발팀도 이 점을 알고 로드맵에 올려뒀지만, 배포를 그리기 전에 반드시 셈에 넣어야 하는 변수입니다.

반대로 긍정적인 신호도 있습니다. Iggy는 최근 Thoughtworks Technology Radar에 실험해 볼 가치가 있는 항목으로 올랐습니다. 업계가 일단 지켜볼 만하다고 판단했다는 뜻이죠.

그리고 이 프로젝트는 20개에 가까운 저장소, 커넥터 런타임, MCP 서버, 여러 SDK, CLI, 웹 UI를 갖춘 생태계를 키워가고 있습니다. 클러스터링이 빠졌다는 점만 보면 미완성처럼 보이지만, 주변 도구의 면면을 보면 단순한 토이 프로젝트가 아니라 실제 운영을 염두에 둔 기반을 차근차근 쌓고 있다는 인상입니다.

메시지 스트리밍의 새로운 가능성

Iggy, Redpanda, WarpStream 같은 프로젝트를 한자리에 놓고 보면 하나의 흐름이 보입니다. 최신 하드웨어와 클라우드 환경에 맞춰 메시지 스트리밍 인프라를 다시 짜려는 시도들이죠. Kafka는 여전히 왕좌에 있고 당분간 흔들리지 않겠지만, 이 새 프로젝트들은 성능, 자원 효율, 운영 단순화 사이에서 저마다 다른 균형점을 찾고 있습니다.

각자의 노선도 다릅니다. WarpStream이 Kafka 호환성을 무기로 잡았다면, Apache Iggy는 그 길을 택하지 않았어요. 자체 프로토콜과 API를 들고, 처음부터 가장 빠르고 가볍게 만드는 데 베팅했습니다. 호환성을 버린 대신 설계의 자유를 챙긴 셈입니다. 이건 곧 Kafka에서 무료로 갈아탈 수는 없다는 비용이기도 하고요.

그래서 판단 기준은 비교적 분명합니다. 처리량과 지연시간이 사업의 핵심이고, 지금 단계에서 단일 노드라는 제약을 감수할 수 있다면, Iggy는 시간을 들여 검증해볼 만한 후보입니다. 반대로 고가용성이 양보 불가한 조건이라면 클러스터링 로드맵이 안착할 때까지는 곁눈질만 해두는 편이 맞고요. 개인적으로는 학습 프로젝트로 출발해 Apache Incubator까지 올라온 궤적 자체가 이 프로젝트를 한 번 더 들여다보게 만드는 이유라고 봅니다. 만든 사람이 브로커의 안쪽을 직접 갈아봤다는 건, 그 위에서 돌아갈 운영의 안쪽도 고민했을 가능성이 높다는 뜻이니까요.

#Apache Iggy#메시지스트리밍#Rust#Kafka대안#고성능