Kafka 애플리케이션에서 피해야 할 다섯 가지 확장성 함정

현대적인 사무실에서 노트북을 사용하고 있는 안경을 쓴 사업가

Apache Kafka는 확장성이 뛰어난 고성능 이벤트 스트리밍 플랫폼입니다. Kafka의 잠재력을 최대한 활용하려면 애플리케이션 설계를 신중하게 고려해야 합니다. Kafka 애플리케이션을 작성하다 보면 성능이 떨어지거나 결국 확장성의 한계에 부딪히는 일이 너무 쉽게 발생합니다. 2015년부터 IBM은 IBM Cloud에서 실행되는 완전 관리형 Apache Kafka 서비스인 IBM Event Streams 서비스를 제공하고 있습니다. 그 이후로 이 서비스는 IBM 내 팀뿐만 아니라 많은 고객들이 작성한 Kafka 애플리케이션의 확장성 및 성능 문제를 해결하는 데 도움을 주었습니다.

이 아티클에서는 Apache Kafka의 몇 가지 일반적인 문제를 설명하고 애플리케이션에서 확장성 문제가 발생하지 않도록 하는 방법에 대한 몇 가지 권장 사항을 제공합니다.

1. 네트워크 왕복 시간 최소화

특정 Kafka 작업은 클라이언트가 브로커에 데이터를 전송하고 응답을 기다리는 방식으로 작동합니다. 전체 왕복 시간은 10밀리초가 걸릴 수 있는데, 이는 빠른 것처럼 들리지만 최대 100번의 연산으로 제한됩니다. 따라서 이러한 종류의 작업은 가급적 피하는 것이 좋습니다. 다행히 Kafka 클라이언트는 이러한 왕복 시간을 기다리지 않아도 되는 방법을 제공합니다. 그 방법들을 제대로 활용하고 있는지 확인하기만 하면 됩니다.

처리량을 극대화하기 위한 팁

  1. 전송된 모든 메시지가 성공했는지 확인하지 마세요. Kafka의 API를 사용하면 메시지 전송과 브로커가 메시지를 성공적으로 수신했는지 확인하는 과정을 분리할 수 있습니다. 메시지 수신 확인을 기다리면 애플리케이션에 네트워크 왕복 지연 시간이 발생할 수 있으므로 가능한 한 이를 최소화하는 것이 좋습니다. 이는 메시지가 모두 수신되었는지 확인하기 전에 가능한 한 많은 메시지를 보내는 것을 의미할 수 있습니다. 또는 메시지 전송 성공 여부 확인을 애플리케이션 내 다른 실행 스레드에 위임해, 더 많은 메시지를 보내는 작업과 병렬로 실행할 수도 있습니다.
  2. 각 메시지를 처리할 때마다 오프셋을 커밋하지 마세요. 오프셋 커밋(동기식)은 서버와의 네트워크 왕복으로 구현됩니다. 오프셋 커밋 빈도를 낮추거나 비동기 오프셋 커밋 기능을 사용하여, 처리하는 모든 메시지에 대해 이 왕복 비용을 지불하지 않도록 하세요. 단, 오프셋 커밋 빈도를 낮추면 애플리케이션이 실패할 경우 더 많은 데이터를 다시 처리해야 할 수 있으니 주의하세요.

위 내용을 읽고 '이런, 이렇게 하면 애플리케이션이 더 복잡해지지 않을까?'라고 생각한다면 대답은 '그렇다'입니다. 사실 그럴 가능성이 높습니다. 처리량과 애플리케이션 복잡성 사이에는 상충 관계가 있습니다. 네트워크 왕복 시간이 특히 교묘한 함정인 이유는 이 한계에 도달하면 처리량을 더 개선하기 위해 애플리케이션을 광범위하게 수정해야 할 수도 있기 때문입니다.

2. 처리 시간이 길어지는 것을 컨슈머 실패로 오해하지 마세요.

Kafka의 유용한 기능 중 하나는 메시지를 처리하는 애플리케이션의 '활성 상태'를 모니터링하고, 실패한 애플리케이션의 연결을 끊는 것입니다. 이 기능은 브로커가 각 애플리케이션 클라이언트가 마지막으로 '폴(poll, 더 많은 메시지를 요청하는 Kafka 용어)'을 호출한 시간을 추적함으로써 작동합니다. 클라이언트가 충분히 자주 폴링하지 않으면, 연결된 브로커는 해당 클라이언트가 실패했다고 판단하고 연결을 끊습니다. 이 설계는 문제가 없는 다른 클라이언트가 개입하여 실패한 클라이언트의 작업을 이어받을 수 있도록 돕습니다.

안타깝게도 이 방식에서는 Kafka 브로커가 수신한 메시지를 처리하는 데 시간이 오래 걸리는 클라이언트와 실제로 실패한 클라이언트를 구분할 수 없습니다. 예를 들어, 다음과 같이 메시지를 반복 처리하는 애플리케이션을 생각해 보세요. 1) 폴을 호출하고 메시지 배치를 가져옵니다. 또는 2) 각 메시지를 배치에서 하나씩 처리하며, 메시지 하나당 처리 시간이 1초 걸립니다.

이 컨슈머가 10개의 메시지 배치를 수신하는 경우, 호출에서 폴까지 약 10초가 걸립니다. 기본적으로 Kafka는 클라이언트 연결을 끊기 전에 폴 사이에 최대 300초(5분)의 시간을 허용하므로 이 시나리오에서는 모든 것이 제대로 작동합니다. 그런데 애플리케이션이 처리하고 있는 토픽에 메시지 백로그가 쌓이기 시작하면, 정말 바쁜 날에는 어떻게 될까요? 애플리케이션은 각 폴 호출에서 10개의 메시지를 가져오는 대신, 500개의 메시지(기본적으로 폴 호출로 반환될 수 있는 최대 레코드 수)를 받게 됩니다. 이렇게 되면 Kafka가 애플리케이션 인스턴스가 실패했다고 판단하고 연결을 끊을 만큼 충분한 처리 시간이 소요됩니다. 이는 좋지 않은 상황입니다.

더 나빠질 수 있다는 사실을 알게 되면 놀라실 수도 있습니다. 일종의 피드백 루프가 발생할 수 있습니다. Kafka가 폴을 충분히 자주 호출하지 않는다는 이유로 클라이언트의 연결을 끊기 시작하면 메시지를 처리할 애플리케이션 인스턴스가 줄어듭니다. 토픽에 쌓이는 메시지 백로그가 증가하고, 더 많은 클라이언트가 대량의 메시지 배치를 받아 처리하는 데 시간이 너무 오래 걸릴 가능성이 높아집니다. 결국 애플리케이션의 모든 인스턴스가 재시작 루프에 빠지고 유용한 작업은 이루어지지 않게 됩니다.

이런 일이 일어나지 않도록 어떤 조치를 취할 수 있을까요?

  1. 폴 호출 간 최대 시간은 Kafka 컨슈머의 'max.poll.interval.ms' 설정으로 조정할 수 있습니다. 단일 poll에서 반환되는 최대 메시지 수는 'max.poll.records' 설정으로 조정할 수도 있습니다. 일반적인 권장 사항으로, 'max.poll.interval.ms'를 늘리는 대신 'max.poll.records'를 줄이는 것을 목표로 하는 것이 좋습니다. 최대 폴 간격을 크게 설정하면 Kafka가 실제로 실패한 컨슈머를 식별하는 데 시간이 더 오래 걸리기 때문입니다.
  2. Kafka 컨슈머는 메시지 흐름을 일시 중지하고 다시 시작하도록 지시할 수도 있습니다. 메시지 처리를 일시 중지하면 폴 메서드가 메시지를 반환하지 못하게 되지만, 클라이언트가 실패했는지 판단하는 타이머는 초기화됩니다. 일시 중지와 재개는 다음과 같은 경우에 유용한 방법입니다. a) 개별 메시지를 처리하는 데 시간이 오래 걸릴 것으로 예상되는 경우 b) Kafka가 개별 메시지를 처리하는 과정에서 클라이언트 실패를 감지할 수 있기를 원하는 경우
  3. Kafka 클라이언트 메트릭의 유용성을 간과해서는 안 됩니다. 메트릭 자체만으로 아티클 내용을 꽉 채울 수 있지만, 여기서는 컨슈머가 폴 사이의 평균 및 최대 시간에 대한 메트릭을 제공한다는 점에 집중하겠습니다. 이 메트릭을 모니터링하면 다운스트림 시스템 때문에 Kafka에서 수신한 각 메시지의 처리 시간이 예상보다 길어지는 상황을 파악하는 데 도움이 됩니다.

이 아티클의 후반부에서 다시 컨슈머 실패라는 주제로 돌아와, 컨슈머 그룹 리밸런싱을 유발할 수 있는 방식과 그로 인한 파괴적인 영향에 대해 살펴보겠습니다.

3. 유휴 컨슈머 비용 최소화

내부적으로 Kafka 컨슈머가 메시지를 수신하는 데 사용하는 프로토콜은 Kafka 브로커에 'fetch' 요청을 보내는 방식으로 작동합니다. 이 요청의 일부로 클라이언트는 브로커가 반환할 메시지가 없을 경우 어떤 동작을 해야 하는지 지정할 수 있으며, 여기에는 브로커가 빈 응답을 보내기 전에 얼마나 기다려야 하는지도 포함됩니다. 기본적으로 Kafka 컨슈머는 브로커에게 최소 1바이트('fetch.min.bytes' 설정으로 제어)의 메시지 데이터가 준비될 때까지 최대 500밀리초('fetch.max.wait.ms' 컨슈머 설정으로 제어) 동안 기다리도록 지시합니다.

500밀리초를 기다리는 것은 그리 무리한 요구처럼 보이지 않지만, 애플리케이션에 대부분 유휴 상태인 컨슈머가 있고 인스턴스 수가 5,000개까지 확장된다면, 아무 작업도 하지 않는 요청이 초당 약 2,500건에 달할 수 있습니다. 이러한 각 요청은 브로커의 CPU 시간을 소모하며, 극단적인 경우 유용한 작업을 수행하려는 Kafka 클라이언트의 성능과 안정성에도 영향을 줄 수 있습니다.

일반적으로 Kafka의 확장 방식은 브로커를 더 추가한 다음 기존 브로커와 신규 브로커 모두에서 토픽 파티션의 균형을 균등하게 재조정하는 것입니다. 하지만 클라이언트가 Kafka에 불필요한 fetch 요청을 과도하게 보내는 경우, 이 방법은 도움이 되지 않을 수 있습니다. 각 클라이언트는 자신이 메시지를 처리하고 있는 토픽 파티션을 담당하는 모든 브로커에 fetch 요청을 전송합니다. 따라서 Kafka 클러스터를 확장하고 파티션을 재배포한 후에도 대부분의 클라이언트가 대부분의 브로커에 fetch 요청을 보내는 상황이 발생할 수 있습니다.

그렇다면 어떻게 해야 할까요?

  1. Kafka 컨슈머 설정을 변경하면 이러한 영향을 줄이는 데 도움이 될 수 있습니다. 메시지가 도착하자마자 바로 수신하려면 'fetch.min.bytes'를 기본값인 1로 유지해야 합니다. 그러나 'fetch.max.wait.ms' 설정을 더 큰 값으로 늘리면, 유휴 컨슈머가 보내는 요청 수를 줄일 수 있습니다.
  2. 좀 더 큰 관점에서 볼 때, 애플리케이션에 잠재적으로 수천 개의 인스턴스가 필요하고 각 인스턴스가 Kafka에서 아주 드물게 메시지를 처리하는 구조가 정말 필요한가요? 물론 그럴 만한 타당한 이유가 있을 수도 있겠지만, Kafka를 더 효율적으로 활용할 수 있도록 설계할 수 있는 방법이 있을지도 모릅니다. 다음 섹션에서 이러한 고려 사항 몇 가지를 살펴보겠습니다.

4. 적절한 수의 토픽과 파티션 선택

다른 게시–구독 시스템(예: MQTT)을 사용해 본 배경에서 Kafka를 접하게 되면, Kafka 토픽이 매우 가볍고 거의 일시적이라고 예상할 수 있습니다. 하지만 실제로는 그렇지 않습니다. Kafka는 수천 개의 토픽을 다루는 데 더 적합하며, Kafka 토픽 또한 비교적 오래 지속될 것으로 예상됩니다. 단일 응답 메시지를 수신하기 위해 토픽을 만든 다음 바로 삭제하는 방식은 Kafka에서는 흔하지 않으며 Kafka의 강점을 제대로 발휘하지 못하는 방법입니다.

대신 오래 유지되는 토픽을 기반으로 설계하세요. 토픽은 애플리케이션이나 특정 활동의 수명과 함께할 수도 있습니다. 또한 토픽 수는 수백 개, 많아도 수천 개 이하로 제한하는 것이 좋습니다. 이를 위해서는 특정 토픽에 여러 메시지가 섞여 들어오는 방식에 대해 관점을 달리해야 할 수도 있습니다.

종종 "토픽에는 몇 개의 파티션이 있어야 할까요?"라는 질문이 제기됩니다. 전통적인 조언은 파티션 수를 넉넉히 잡는 것입니다. 토픽이 생성된 후 파티션을 추가해도, 토픽이 보유한 기존 데이터의 파티셔닝은 변경되지 않기 때문입니다(이로 인해 파티션 내 메시지 순서를 제공하기 위해 파티셔닝에 의존하는 컨슈머에게 영향을 줄 수 있음). 이는 좋은 조언이지만, 몇 가지 추가적인 고려 사항도 함께 살펴볼 필요가 있습니다.

  1. 초당 MB 단위의 처리량이 예상되거나, 애플리케이션 확장에 따라 처리량이 증가할 수 있는 토픽이라면 로드를 여러 브로커에 분산하기 위해 파티션을 두 개 이상 두는 것이 강력히 권장됩니다. Event Streams 서비스는 항상 브로커 수를 3의 배수로 구성해 Kafka를 실행합니다. 이 글을 작성하는 시점 기준으로는 최대 9개의 브로커까지 지원하지만, 향후 더 늘어날 수도 있습니다. 토픽의 파티션 수를 3의 배수로 설정하면 모든 브로커에 파티션을 고르게 분산할 수 있습니다.
  2. 토픽의 파티션 수는 Kafka 컨슈머 그룹을 통해 해당 토픽의 메시지를 효과적으로 소비할 수 있는 Kafka 컨슈머의 최대 수를 제한합니다(이에 대해서는 뒤에서 더 다룹니다). 토픽에 있는 파티션보다 더 많은 컨슈머를 컨슈머 그룹에 추가하면 일부 컨슈머는 메시지 데이터를 소비하지 못한 채 유휴 상태로 남게 됩니다.
  3. 토픽이 상당한 메시징 트래픽을 수신하지 않거나 토픽 내 순서에 의존하지 않고 나중에 파티션을 더 추가할 수 있다는 확신이 있다면, 단일 파티션 토픽을 사용하는 것이 본질적으로 잘못된 것은 아닙니다.

5. 컨슈머 그룹 리밸런싱은 예상보다 큰 혼란을 일으킬 수 있습니다

메시지를 소비하는 대부분의 Kafka 애플리케이션은 Kafka의 컨슈머 그룹 기능을 활용하여 어떤 클라이언트가 어떤 토픽 파티션에서 소비하는지 조정합니다. 컨슈머 그룹 개념이 조금 흐릿하신 분들을 위해 핵심만 빠르게 짚어 보겠습니다.

  • 컨슈머 그룹은 특정 시점에 한 클라이언트만 특정 토픽 파티션에서 메시지를 수신하도록 Kafka 클라이언트 그룹을 조정합니다. 이 기능은 애플리케이션의 여러 인스턴스 간에 토픽에 대한 메시지를 공유해야 하는 경우에 유용합니다.
  • Kafka 클라이언트가 컨슈머 그룹에 합류하거나 이전에 가입했던 컨슈머 그룹을 떠나면, 해당 컨슈머 그룹은 리밸런싱됩니다. 일반적으로 클라이언트는 자신이 속한 애플리케이션이 시작될 때 컨슈머 그룹에 합류하며, 애플리케이션이 종료, 재시작 또는 충돌할 경우 그룹을 떠납니다.
  • 그룹이 리밸런싱되면 그룹 멤버 간에 토픽 파티션이 다시 배포됩니다. 예를 들어, 클라이언트가 그룹에 합류하면 이미 그룹에 속한 일부 클라이언트로부터 토픽 파티션이 제거(Kafka 용어로는 'revoked')되어 새로 합류한 클라이언트에 할당될 수 있습니다. 반대로, 클라이언트가 그룹을 떠나면 해당 클라이언트에 할당된 토픽 파티션이 나머지 멤버들에게 재배분됩니다.

Kafka가 발전함에 따라 점점 더 정교한 리밸런싱 알고리즘이 고안되었으며, 이는 지금도 계속 개선되고 있습니다. Kafka의 초기 버전에서는 컨슈머 그룹이 리밸런싱될 때, 그룹 내 모든 클라이언트가 소비를 중단하고 토픽 파티션이 새 멤버들에게 재배분된 후, 모든 클라이언트가 다시 소비를 시작했습니다. 이 접근 방식에는 두 가지 단점이 있습니다(이후 개선되었으니 걱정하지 마세요).

  1. 리밸런싱이 진행되는 동안 그룹의 모든 클라이언트는 메시지 소비를 중지합니다. 이는 처리량에 뚜렷한 영향을 미칩니다.
  2. Kafka 클라이언트는 일반적으로 아직 애플리케이션에 전달되지 않은 메시지를 버퍼링하고, 버퍼가 소진되기 전에 브로커에서 추가 메시지를 가져옵니다. 이 방식의 목적은 Kafka 브로커에서 더 많은 메시지를 가져오는 동안 애플리케이션으로의 메시지 전송이 지연되지 않도록 하기 위함입니다(앞서 언급했듯이, Kafka 클라이언트는 네트워크 왕복 대기 시간을 최소화하려고 합니다). 하지만 리밸런싱으로 인해 클라이언트에서 파티션이 회수되면, 해당 파티션에 버퍼링된 모든 데이터는 삭제됩니다. 마찬가지로, 리밸런싱으로 클라이언트에 새 파티션이 할당되면, 클라이언트는 해당 파티션의 마지막 커밋 오프셋부터 데이터를 버퍼링하기 시작하게 되며, 이로 인해 브로커에서 클라이언트로의 네트워크 처리량이 급증할 수도 있습니다. 이 현상은 해당 파티션이 새로 할당된 클라이언트가, 이전에 파티션이 회수된 클라이언트가 버퍼링했던 메시지 데이터를 다시 읽기 때문에 발생합니다.

최근의 리밸런싱 알고리즘은 Kafka의 용어를 사용하자면 'stickiness(고착성)'과 'cooperation(협력성)'을 추가하여 크게 개선되었습니다.

  • 'Sticky(고착)' 알고리즘은 리밸런싱 이후에도 가능한 한 많은 그룹 멤버가 리밸런싱 이전에 갖고 있던 동일한 파티션을 유지하도록 합니다. 이렇게 하면 리밸런싱이 발생할 때 버퍼링된 메시지 데이터가 삭제되거나 Kafka에서 다시 읽히는 양을 최소화할 수 있습니다.
  • 'Cooperative(협력)' 알고리즘리은 밸런싱이 진행되는 동안 클라이언트가 계속 메시지를 소비할 수 있도록 합니다. 클라이언트가 리밸런싱 이전에 파티션을 할당받았고 리밸런싱 이후에도 해당 파티션을 유지한다면, 리밸런싱으로 중단되지 않은 파티션에서 계속 메시지를 소비할 수 있습니다. 이 방식은 동일한 클라이언트에 파티션을 계속 할당하는 역할을 하는 'stickiness(고착성)'와 함께 시너지 효과를 발휘합니다.

이러한 최신 리밸런싱 알고리즘의 개선에도 불구하고, 애플리케이션이 자주 컨슈머 그룹 리밸런싱을 겪는 경우에는 여전히 전체 메시징 처리량에 영향이 발생하고, 클라이언트가 버퍼링된 메시지 데이터를 삭제하고 다시 가져오면서 네트워크 대역폭이 낭비될 수 있습니다. 다음은 이러한 상황에서 취할 수 있는 몇 가지 권장 조치입니다.

  1. 리밸런싱이 언제 발생하는지 파악할 수 있어야 합니다. 규모가 큰 환경에서는 메트릭을 수집하고 시각화하는 것이 가장 좋은 방법입니다. 이런 경우, 다양한 메트릭 소스를 활용하면 전체 상황을 더 명확하게 이해하는 데 도움이 됩니다. Kafka 브로커는 클라이언트로 전송되는 데이터의 바이트 수와 리밸런싱 중인 컨슈머 그룹 수에 대한 메트릭을 제공합니다. 애플리케이션이나 해당 런타임에서 재시작이 발생하는 시점을 나타내는 메트릭을 수집하고 있다면, 이를 브로커 메트릭과 연관 지어 분석하면 리밸런싱이 문제임을 추가로 확인할 수 있습니다.
  2. 애플리케이션이 충돌하는 경우와 같이 불필요하게 애플리케이션을 재시작하지 않도록 합니다. 애플리케이션의 안정성 문제가 있다면, 예상보다 훨씬 더 자주 리밸런싱이 발생할 수 있습니다. 예를 들어, 애플리케이션 충돌 시 발생하는 일반적인 오류 메시지(예: 스택 트레이스)를 애플리케이션 로그에서 검색하면, 문제가 얼마나 자주 발생하는지 파악하고 근본 원인을 디버깅하는 데 도움이 되는 정보를 얻을 수 있습니다.
  3. 애플리케이션에 가장 적합한 리밸런싱 알고리즘을 사용하고 있나요? 이 글을 쓰는 시점을 기준으로 가장 뛰어난 표준은 'CooperativeStickyAssignor'입니다. 하지만 Kafka 3.0부터는 기본적으로 CooperativeStickyAssignor 대신 이전 할당 알고리즘인 RangeAssignor를 사용합니다. Kafka 문서에는 클라이언트가 CooperativeStickyAssignor를 선택하도록 마이그레이션하는 단계가 설명되어 있습니다. CooperativeStickyAssignor는 전반적으로 좋은 선택이지만, 특정 사용 사례에 맞춘 다른 어사이너도 있다는 점은 알아둘 필요가 있습니다.
  4. 컨슈머 그룹의 멤버는 고정되어 있나요? 예를 들어, 항상 가용성이 높고 서로 다른 애플리케이션 인스턴스 4개를 실행한다고 가정해 보겠습니다. 이 경우 Kafka의 정적 그룹 멤버십(static group membership) 기능을 활용할 수 있습니다. 정적 그룹 멤버십을 사용하면 애플리케이션의 각 인스턴스에 고유 ID를 할당하여, 리밸런싱 자체를 피할 수 있습니다.
  5. 애플리케이션 인스턴스에서 파티션이 해지될 때 현재 오프셋을 커밋하세요. Kafka 컨슈머 클라이언트는 리밸런싱 이벤트를 위한 리스너를 제공합니다. 애플리케이션 인스턴스에서 파티션이 해지되려 할 때, 리스너를 통해 해당 파티션의 오프셋을 커밋할 기회를 얻을 수 있습니다. 파티션이 해지되는 시점에 오프셋을 커밋하면, 해당 파티션이 할당된 그룹 멤버가 이 지점부터 이어서 처리할 수 있어, 파티션의 일부 메시지를 다시 처리하지 않아도 되는 장점이 있습니다.

전문가의 인사이트를 바탕으로 한 최신 기술 뉴스

Think 뉴스레터를 통해 AI, 자동화, 데이터 등 가장 중요하고 흥미로운 업계 동향에 대한 최신 소식을 받아보세요. IBM 개인정보 보호정책을 참조하세요.

감사합니다! 구독이 완료되었습니다.

구독한 뉴스레터는 영어로 제공됩니다. 모든 뉴스레터에는 구독 취소 링크가 있습니다. 여기에서 구독을 관리하거나 취소할 수 있습니다. 자세한 정보는 IBM 개인정보 보호정책을 참조하세요.

이 다음 단계는 무엇일까요?

이제 여러분은 Kafka 애플리케이션 스케일링의 전문가가 되셨습니다. 이제 이 지식을 실제로 적용해 보고, IBM Cloud에서 제공하는 완전 관리형 Kafka 서비스를 사용해 보세요. 설정과 관련하여 어려움이 있다면 시작하기 가이드 FAQ를 참고하세요.

 
관련 솔루션
IBM Event Streams

IBM® Event Streams는 오픈소스 Apache Kafka를 기반으로 구축된 이벤트 스트리밍 소프트웨어입니다. IBM Cloud 상의 완전 관리형 서비스 또는 자체 호스팅으로 사용할 수 있습니다.

Event Streams 살펴보기
통합 소프트웨어 및 솔루션

애플리케이션과 시스템을 연결하여 중요 데이터에 빠르고 안전하게 액세스할 수 있는 IBM 통합 솔루션을 활용해 비즈니스 잠재력을 실현하세요.

통합 솔루션 살펴보기
클라우드 컨설팅 서비스

IBM Cloud 컨설팅 서비스를 통해 새로운 역량을 개발하고 비즈니스 민첩성을 향상하세요.

클라우드 컨설팅 서비스 살펴보기
다음 단계 안내

IBM® Event Streams는 오픈소스 Apache Kafka를 기반으로 구축된 이벤트 스트리밍 소프트웨어입니다. IBM Cloud 상의 완전 관리형 서비스 또는 자체 호스팅으로 사용할 수 있습니다.

Event Streams 살펴보기 자세한 정보 보기