ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • kafka는 왜 속도가 빠를까?
    프로젝트/kafka 2023. 7. 29. 00:01

    개요

    메시지큐에는 Kafka, RabbitMQ, ActiveMQ 등 다양한 선택지들이 있습니다.

    보통 Kafka를 처리량이 많은 분산 메시징 시스템에서 사용하며 확장성, 고성능 및 높은 처리량이 항상 키워드로 따라옵니다.

     

    Kafka vs ActiveMQ, RabbitMQ 성능차이

    https://notes.stephenholiday.com/Kafka.pdf

    Kafka의 특징 중 하나로 메시지를 메모리에 저장하는 Rabbit MQ, Active MQ와 다르게 파일에 저장합니다.

    파일에 저장한다는것은 Disk에 저장하고 읽는다는 것인데 어떻게 빠르게 동작할 수 있을까요?

     

    https://www.confluent.io/blog/kafka-fastest-messaging-system/

     

    물론 처리량이 낮은 30MB/s이하에서는 RabbitMQ 가 조금 더 낮은 레이턴시를 보여줍니다.

    하지만 30MB/s 이상 처리해야한다면? 카프카를 사용해야 할 것 같습니다.

    카프카가 빠른 이유에 대해서 알아보도록 하겠습니다.

     

    Sequential I/O

    Source: wikipedia

    일반적으로 RAM은 랜덤 엑세스를 지원하지만, 디스크는 그렇지 않습니다.

    디스크는 원하는 데이터의 위치한 블록을 찾기 위한 시간, 블록을 메모리에 카피하는 시간등의 오버헤드가 존재합니다.

    데이터가 캐시가 램에 이미 존재하면 이 과정은 생략되지만, 그렇지 않다면 page fault 가 발생하여 디스크는 일반적으로 느리다가 인식됩니다.

     

    하지만 대용량 데이터를 처리하는데 그 모든 데이터를 RAM에 올리기도 현실적으로 어려울 수 있습니다.

    이에 따라 카프카는 디스크를 저장소로 사용하는 대신 시퀀셜 I/O를 통해 탐색시간을 최소화시킵니다.

     

    카프카의 데이터가 컨슈머가 읽어도 지워지지 않으며, 데이터는 오로지 맨 끝에 추가만 됩니다.

    이로 인해 카프카의 데이터는 디스크에 조각으로 나뉘어 저장되지 않고, 연속적인 블록에 저장됩니다.

    이런 특성으로 카프카는 원하는 데이터에 순차적으로 접근할 수 있게 되고 탐색시간이 최소화됩니다.

     Random Access와 Sequential Access의 성능은 100배 차이가 납니다.

     

    하지만 항상 시퀀셜 액세스가 보장되진 않습니다.

    카프카의 데이터가 위치하는 파일 시스템을 다른 애플리케이션이 함께 사용하면 디스크 단편화가 발생할 수 있습니다.

    따라서 카프카의 데이터를 가급적 독립된 파일시스템에 유지하는 것이 권장됩니다.

     

    Zero Copy

    https://developer.ibm.com/articles/j-zerocopy/

    위의 그림은 전통적인 copy 기법으로 아래와 같은 절차를 가집니다.

    데이터를 디스크로 읽어 네트워크로 전송하는 작업은 4번의 카피와 4번의 컨텍스트 스위칭이 요구됩니다.

     

    1. 디스크에서 read buffer

    2. read buffer에서 application buffer

    3. application buffer에서 socket buffer

    4. socket buffer에서 nic buffer로

     

    데이터를 네트워크를 통해 다른장소로 보낼 때 하드웨어를 관리하는 운영체제, 커널영역과 데이터를 조작하는 사용자 애플리케이션 영역을 오고 가야 하지만 애플리케이션 영역을 커널영역에 접근할 수 없기 때문에 이런 데이터 복사과정이 발생합니다.

     

    https://developer.ibm.com/articles/j-zerocopy/

     

    위의 그림은 zero-copy 방식입니다.

    하지만 굳이 애플리케이션 통해 보내야할까? 라는곳에서 시작되었고 socker buffer를 사용해야 할까? 에서

    read buffer에서 nic buffer로 보내고 데이터가 전송되고 trasnferTo() 메서드를 리턴합니다.

    이로 인해 복사획수를 3번으로 줄이고 컨텍스트 스위칭도 2회로 줄여 성능을 개선했습니다.

     

    Data Batch & Compression

    Batching과 Compression을 지원하여 네트워킹 횟수를 대폭 줄여 성능을 향상합니다.

     

     

    Topic Partitioning

    카프카의 데이터는 로그 세그먼트로 저장되는데, 이 데이터를 순차적이기 때문에 다수의 쓰레드가 동시에 접근하는 일은 의미가 없습니다. 데이터는 최근의 것만 한 번 읽으면 되기 때문에 아무리 많은 쓰레드가 있어도 경합이 발생할뿐 이득은 없을 수 있습니다.

     

    하지만 같은 토픽이라도 데이터를 파티셔닝을 통해 나누고 각 파티션에는 독립된 쓰레드가 붙어 작업할 수 있도록 함으로써 하나의 토픽을 여러 쓰레드가 나누어 처리할 수 있도록 병렬성을 구현했습니다.

     

     

     

     

     

    참고자료

    https://notes.stephenholiday.com/Kafka.pdf

    https://www.confluent.io/blog/kafka-fastest-messaging-system/

    https://www.youtube.com/watch?v=UNUz1-msbOM 

    https://parkcheolu.tistory.com/261

     

    댓글

Designed by Tistory.