본문 바로가기
Kafka

카프카 핵심 개념 및 도입 전 필수 점검 사항

by Jason95 2022. 12. 24.
  • 카프카에 전송하는 데이터 중 민감 정보가 있다면 전송해도 보안상 이슈는 없는지 검토합니다.
    • 구독해가는 주체가 외부 서버일 수도 있는지 체크 필요
  • 토픽
    • 토픽 이름은 한 번 정하면 영원히 바꿀 수 없으니, 신중히 결정해야 합니다.
    • 토픽은 local/alpha/qa/pre/live 각각 따로 만드는 것이 좋습니다.
  • 파티션
    • 한 토픽 안에는 여러 개의 파티션이 있습니다.
    • 카프카에서 파티션 개수는 늘릴 수만 있고, 영원히 줄일 수 없으니 신중히 결정해야 합니다.
  • 프로듀서
    • 프로듀서가 특정 토픽에 레코드들을 발행할 때, 해당 토픽 내 파티션들에 Round Robin으로 전송됩니다.
  • 컨슈머
    • 주요 설정값
      • max.poll.records : 한번에 Consume 해오는 레코드의 개수를 설정할 수 있습니다.
      • enable.auto.commit : 자동 커밋 여부를 설정할 수 있습니다. (자동 커밋 vs 수동 커밋)
        • 자동 커밋은 5초 간격으로 커밋합니다.
        • 수동 커밋은 커밋 메서드가 실행될 때 커밋합니다.
  • 중복 방지
    • 카프카는 여러 가지 엣지 케이스로 인해 중복이 발생할 수밖에 없습니다.
    • 따라서 데이터를 받는 쪽에서 ID를 통해 중복 제거 처리를 반드시 해주어야 합니다.
  • 유실 방지
    • 컨슈머에서 에러가 발생하거나 컨슈머가 죽으면, 아직 정상 처리되지 않은 레코드에 대해서는 커밋이 이루어지지 않으므로, 기본적으로 유실이 발생하진 않습니다.
    • 오히려 커밋되지 않은 레코드를 재차 Consume하면서 중복이 발생합니다.
    • Consumer가 요청한 외부 API에 대한 응답이 오기 전에 커밋을 먼저 해버리면 유실이 발생 가능하므로, 그런 일만 없도록 신경 쓰면 됩니다.
    • Kafka Command Line Tools로 cmd 창에서 consumer 프로세스를 띄울 수 있는데, 이때 절대로 live 토픽을 구독하면 안 됩니다.
      • consumer 프로세스가 live용 컨슈머 그룹에 합류되면서, 엄청난 양의 live 레코드들이 유실되는 불상사가 발생하기 때문입니다.
      • 물론, 컨슈머 그룹 이름을 live용과 다른 이름으로 주면 유실이 발생하지 않겠지만, 그래도 조심하시기 바랍니다.
      • 다만, local/alpha/qa 토픽은 테스트용이므로 Kafka Command Line Tools로 구독해도 괜찮습니다.
  • 지연 방지
    • 카프카에서는 Lag을 모니터링하는 것이 중요합니다. (Kafka Command Line Tools로 Lag 조회가 가능합니다)
      • 파티션 내에서 아직 Consume 해가지 않은 레코드의 개수를 Lag이라고 합니다.
      • Lag이 늘어나면 컨슈머 쪽에서 데이터를 처리하는 지연 시간이 점점 늘어납니다.
      • 라이브 배포 전에 미리 대량의 더미 데이터로 Lag이 증가 추세를 띠는지 유지 추세를 띠는지 모니터링해보는 것이 좋습니다.
      • 예상 되는 라이브 트래픽 만큼 들어왔을 때, Lag의 증가 추세가 오랫동안 유지되면 지연이 매우 심해질 것입니다.
      • 단, 늘어난 Lag으로 인해 컨슈머 쪽에서 부하가 늘어나서 종료될 가능성은 고려하지 않아도 됩니다.
      • 컨슈머는 Lag이 많든 적든 항상 본인의 페이스대로만 Consume해가기 때문입니다.
      • 성능 테스트는 평균 트래픽이 아닌, (이벤트 기간이나 오픈 시기 같은) 피크 트래픽을 기준으로 잡는 것이 좋습니다.
    • 특정 파티션에 대해 영원한 병목이 일어나지 않도록, 실패한 레코드는 영원히 재시도하지 말고, 로깅 또는 DLQ에 삽입한 뒤, 커밋을 시켜야 합니다.
    • 실패한 레코드를 같은 토픽에 다시 Produce하는 전략을 취하고 싶을 수 있습니다.
      • 그런데 이 전략의 문제점은, 재삽입한 레코드가 계속해서 실패를 할 수 있고
        그런 레코드들이 점점 많아지면 다른 정상 레코드들에 대한 지연도 점점 늘어날 것이고, 모니터링도 어려워진다는 것입니다.
      • 따라서 개인적으로 재삽입 전략보다 DLQ 삽입 전략을 좀 더 추천 드립니다.
    • 컨슈머 개수가 파티션 개수 만큼 있는데도 지연 문제가 있다면, 파티션 개수와 컨슈머 개수를 함께 늘려야 합니다.
      • 컨슈머의 EC2 사양을 늘리는 것은 효과가 미미할 수 있습니다.
      • 파티션과 컨슈머의 개수를 늘리는 것보다, 컨슈머의 로직을 최적화하거나 캐싱 등을 활용해서 성능을 개선하는 것이 더 효과적일 수도 있으니
        컨슈머 내부의 성능 개선 포인트들을 먼저 점검해보는 게 좋습니다.
  • 파티션과 컨슈머 간의 매핑 관계에 대한 이해
    • 배포 시 알고 있어야 할 개념입니다.
    • 가정
      • 컨슈머 그룹 A, B가 있다고 가정하겠습니다
      • 컨슈머 그룹 A 안에는 컨슈머 a, b, c, d, e, f, g가 있을 수 있다고 가정하겠습니다.
      • 컨슈머 그룹 B 안에는 컨슈머 1, 2, 3, 4, 5가 있을 수 있다고 가정하겠습니다.
      • 토픽이 1개 있다고 가정하겠습니다.
      • 이 토픽 내의 파티션은 처음에 2개가 있고 나중에 5개로 늘릴 예정이라고 가정하겠습니다 (1번/2번/3번/4번/5번 파티션이라고 부르겠습니다.)
      • 파티션과 컨슈머 간의 매핑 관계가 바뀌는 현상을 '컨슈머 그룹의 리밸런싱(Rebalancing)'이라고 표현하겠습니다.
        • 기존에 알고 계시던 '리밸런싱'의 개념과는 전혀 다른 의미로 쓰입니다.
    • 최초 배포 시나리오
      • 파티션 2개 + 컨슈머 없음
        • 컨슈머가 아직 없습니다.
      • 파티션 2개 + 컨슈머 그룹 A (컨슈머 a)
        • 컨슈머 a가 컨슈머 그룹 A에 합류하면서 리밸런싱이 일어납니다.
        • 컨슈머 a가 1번 파티션과 2번 파티션을 모두 구독합니다.
      • 파티션 2개 + 컨슈머 그룹 A (컨슈머 a + b)
        • 컨슈머 b가 컨슈머 그룹 A에 합류하면서 리밸런싱이 일어납니다.
        • 이제 컨슈머 a는 1번 파티션만 구독하고, 컨슈머 b는 2번 파티션만 구독하는 식의 형태가 되었습니다.
        • 이 상태가 된 뒤에 프로듀서를 최초 배포하는 것이 좋습니다.
    • 이후 배포 시나리오
      • 파티션 2개 + 컨슈머 그룹 A (컨슈머 a + b + c)
        • 컨슈머 c가 컨슈머 그룹 A에 합류하지만, 리밸런싱은 일어나지 않습니다.
        • 즉, 파티션 개수보다 컨슈머 개수가 더 많으면, 파티션과 컨슈머 간의 매핑 관계는 바뀌지 않습니다.
      • 파티션 2개 + 컨슈머 그룹 A (컨슈머 a + b + c + d)
        • 컨슈머 d가 컨슈머 그룹 A에 합류하지만, 리밸런싱은 일어나지 않습니다.
        • 즉, 파티션 개수보다 컨슈머 개수가 더 많으면, 파티션과 컨슈머 간의 매핑 관계는 바뀌지 않습니다.
      • 파티션 2개 + 컨슈머 그룹 A (컨슈머 b + c + d)
        • 컨슈머 a가 종료되어 컨슈머 그룹 A에서 제외되면서, 컨슈머 c가 컨슈머 그룹 A에 합류되므로, 리밸런싱이 일어납니다.
        • 컨슈머 c는 새로 붙은 파티션에서 '컨슈머 a에 의해 마지막으로 커밋된 오프셋'부터 구독해가기 시작합니다.
          • 참고로 각 파티션은 각자 자신에게 대응되는 오프셋이 있습니다.
      • 파티션 2개 + 컨슈머 그룹 A (컨슈머 c + d)
        • 컨슈머 b가 종료되어 컨슈머 그룹 A에서 제외되면서, 컨슈머 d가 컨슈머 그룹 A에 합류되므로, 리밸런싱이 일어납니다.
        • 컨슈머 d는 새로 붙은 파티션에서 '컨슈머 b에 의해 마지막으로 커밋된 오프셋'부터 구독해가기 시작합니다.
        • 이제 컨슈머 c는 1번 파티션만 구독하고, 컨슈머 d는 2번 파티션만 구독하는 식의 형태가 되었습니다.
    • 파티션 개수 증가 시나리오
      • 파티션 5개 + 컨슈머 그룹 A (컨슈머 c + d)
        • 파티션이 2개에서 5개로 증가하면서 리밸런싱이 일어납니다.
        • 1번/2번/3번 파티션은 컨슈머 c가 구독하고, 4번/5번 파티션은 컨슈머 d가 구독하는 식으로 매핑 관계가 바뀝니다.
      • 파티션 5개 + 컨슈머 그룹 A (컨슈머 c + d + e + f + g)
        • 컨슈머 e, f, g가 컨슈머 그룹 A에 합류하면서 리밸런싱이 일어납니다.
        • 이제 파티션과 컨슈머 간의 매핑이 1:1로 바뀌었습니다.
    • 새로운 컨슈머 그룹 추가 시나리오
      • 컨슈머 그룹 A가 구독 중인 토픽에 새로운 컨슈머 그룹 B가 붙게 되었습니다.
      • 컨슈머 그룹 B 내의 각 컨슈머들의 auto.offset.reset 설정 값은 default가 latest이므로, 각 파티션의 가장 마지막 오프셋부터 구독을 시작합니다.
      • 컨슈머 그룹 B가 붙는 것은 컨슈머 그룹 A의 동작에 아무런 영향을 주지 않습니다.
    • 참고하면 좋을 링크들

'Kafka' 카테고리의 다른 글

Kafka 주요 명령어 (window + git bash 기준)  (0) 2021.09.18