[Kafka]카프카의 특징-1


이 글은 카프카, 데이터 플랫폼의 최강자 고승범/공용준 님의 책을 공부하며
정리하는 글입니다.

[Kafka]카프카의 특징-1

분산시스템 / 데이터 모델(토픽, 파티션) / 오프셋 / 메시지 순서를 알아보자

분산시스템

  • 단일 시스템보다 더 높은 성능
    • 하나의 시스템이 초당 1000개의 메세지로 cpu 100% 사용한다면 초당 900은 90% CPU 사용량이다
    • 만약 서버 한대를 추가하면 CPU 사용량(대당)이 45% 수준이 된다.
    • 초당 처리 할 메시지양과 그에 따른 CPU 사용량을 고려해 브로커 수를 증감하면 된다.
  • 분산 시스템 중 하나의 서버 또는 노드 등이 장애가 발생하면 다른 서버 또는 노드가 대신처리
    • 카프카는 리플리케이션을 지원한다.
    • 토픽은 여러 개의 파티션으로 나뉘어 있고, 브로커에는 여러개의 파티션이 존재함
    • 각 파티션마다 리플리케이션이 동작(하나는 파티션의 리더, 나머지는 파티션의 팔로워)
    • 자세한 복구 매커니즘은 아래에서 설명.
  • 시스템 확장이 용이하다

  • 페이지 캐시
    • OS는 물리적 메모리에 애플리케이션 부분을 할당하고 남은 잔여 메모리를 페이지 캐시로 유지하여 성능을 높인다
    • 이런 잔여메모리를 디스크에 읽고 쓰기에 사용하지 않고, 페이지 캐시를 통해 읽고 쓰는 방식을 사용해 처리속도를 높였다.
  • 배치 전송 처리
    • 빈번한 I/O 발생은 속도 저하를 유발하는데, 배치 처리를 지원하여 오버헤드를 줄인다

카프카 데이터 모델의 이해

  • 토픽(topic)
    • 카프카 클러스터는 토픽(topic)이라는 곳에 데이터를 저장.
    • 비유하자면 메일센터에 메일을 보내는 것이 아니라 받을 유저의 메일주소로 보내는 것과 같음
    • 토픽 이름은 249자 미안으로 영문, 숫자, ‘ . ‘, ‘ _ ‘, ‘ - ‘의 조합으로 만든다
    • 토픽 이름은 나름 규칙을 가지는데 구분할 이름-카테고리
    • ex) sbs-news, kbs-video 등이다. 토픽 이름도 꽤나 직관적인 것이 좋겠다.
  • 파티션(partition)
    • 왜 하나의 토픽을 파티셔닝 할까?
      • a, b, c, b 메시지를 보내는데 각 1초가 걸린다고 보면, a완료 후 b완료 후 그리고 c, d가 전송되면 총 4초가 소요된다.
      • 만약 프로듀서를 4개로 변경하고 파티션을 1개로 하면 4배의 속도 향상을 기대할 수 있다.
      • 하지만 메시지 큐 시스템은 순서를 보장해야한다. 그렇기 때문에 이전 메시지가 처리된 후 다음 메시지를 전송한다.
      • 그렇기 때문에 카프카에서 속도를 높이려면 토픽의 파티션 수를 늘려줘야 한다.
      • 아래 그림을 참고하자

      • 같은 토픽으로 4개를 보낼 때, 병렬로 각 파티션에 보내면 개당 총 4초의 시간이 1초로 된다.
      • 결론 : 빠른 전송을 위해서는 프로듀서의 수 만큼 토픽의 파티션을 늘려주자.
    • 무조건 토픽의 파티션 수를 늘려야 하나?
      • 파일 핸들러의 낭비 (저장되는 데이터 마다 인덱스/실제데이터 가 있다.). 카프카는 모든 디렉토리 파일들에 대해 파일 핸들을 열게되는데 파티션의 수가 많아지면 리소스를 낭비함
      • 장애 복구 시간 증가


중요한 장애 복구에 대해서 알아보자

  • 카프카는 리플리케이션을 지원한다.

  • 토픽은 여러 개의 파티션으로 나뉘어 있고, 브로커에는 여러 개의 파티션이 존재한다.

  • 모든 장애 처리는 컨트롤러로 지정된 브로커 가 수행한다.

  • 컨트롤러가 아닌 브로커가 다운 된다면?
    • 브로커에 리더있는 파티션은 일시적으로 사용불가.
    • 사용불가 상태의 리더를 팔로워로 이동시켜서 처리함.
  • 컨트롤러가 있는 브로커가 다운 된다면?
    • 살아 있는 브로커 중 하나가 자동으로 컨트롤러 역할을 대신 수행한다.
    • 최악의 상황으로 새로운 컨트롤러가 선정될 때 까지, 새로운 파티션의 리더를 선출 할 수 없다.
    • 만약에 10,000개의 파티션이 있고 주키퍼에서 데이터를 읽는데 파티션당 2밀리초가 걸린다면
    • 20초가 넘는 시간이 소요된다.


그래서 내 토픽의 적절한 파티션 수는?

  • 목표 처리량의 기준을 잡는다
    • 프로듀서 4개, 각가 초당 10개 메시지를 보냄
    • 카프카 토픽에서는 초당 40개의 메시지를 받아야함
    • 그렇다면, 파티션을 4개로 늘린다
  • 컨슈머 입장도 고려한다
    • 컨슈머 8개, 초당 5개 메시지를 받음
    • 그렇다면 해당 토픽의 파티션수는 컨슈머 수와 동일하게 8개로 맞춘다
    • 그래야 컨슈머마다 각각의 파티션에 접근할 수 있게 해야한다.
  • 그래도 주의 할 사항이 있다.
    • 카프카에서 파티션 수 증가는 쉽다.
    • 카프카에서 줄이는 방법은 어렵다 = 토픽을 삭제하는 방법뿐이다.
    • 카프카에서는 브로커당 약 2000개 정도의 최대 파티션 수를 권장한다. 그러니까 그 이하로 하라는 것!
  • 결론
    • 프로듀서 수와 컨슈머 수가 동일한 경우와 메시지 전송 수가 딱 맞아떨어지면 좋겠지만
    • 현실은 그렇지 않기에, 적은 수의 파티션으로 시작해서 병목현상 발생 시 파티션을 늘려나가자


오프셋(offset), 메시지 순서

  • 오프셋: 각 파티션마다 메시지가 저장되는 위치를 오프셋이라고 부르며, 유일한 64비트 정수 형태로 되어있다

  • 위 그림에서 쓰기는 각 파티션 별로 분산되어 저장하는 상태를 말한다.
  • 위 그림에서 토픽 기준으로 오프셋이 0인 것을 보면 전부 3개(파티션 당 1개씩)가 있다.
  • 만약 컨슈머가 파티션 0에서 데이터를 가져 간다면, 오프셋 0,1,2,3,4…순서대로만 가져갈 수 있다.
  • 이렇게 오프셋을 이용해 메시지의 순서를 보장한다.(2를 가져갔다가 1을 가져가고 하는 것은 안된다)

용어정리
페이지 캐시: 리눅스는 파일 I/O 성능 향상을 위해 페이지 캐시 메모리 영역을 사용하는데, 그 이유는 느린 물리 디스크로 접근을 최대한 피하기 위함이다. 페이지 캐시는 한번 읽은 파일 내용을 페이지 캐시 영역에 저장하여 다시 한 번 동일한 파일에 대한 접근 시 디스크에서 가져오지 않고, 페이지 캐시에서 읽어서 제공한다. 만약 할당할 메모리가 부족할 때 자동으로 메모리 사용을 반환한다.