인프라

카프카 101

오늘의 나1 2023. 10. 2. 23:55

https://youtu.be/kBGR6cwVqv0?si=kdTN_o9dZeaSpeX0

 

카프카란 무엇이고, 왜 사용되는 지

카프카는 실시간 이벤트 스트리밍 플랫폼이다.
실시간으로 발생되는 대규모의 데이터를 스트리밍하고 처리하고 분석하는 데 특화되어 있다. 

라이브 스트리밍, 데이터 처리 및 분석과 관련된 특징들을 보면 다음과 같다. 

  • 메시지 큐를 사용해서 데이터를 배치 처리하고 순서를 보장  
  • 복제본을 운영하여 서버가 죽었을 때 다른 서버가 대응
  • 트래픽에 따라 스케일 아웃할 수 있음
  • 이벤트 자체를 저장하여 현재 상태에 이르기까지의 전체 과정을 볼 수 있음
  • 데이터를 영구적으로 저장하여 데이터를 언제든 다시 활용할 수 있게 합니다. 

이런 특징으로 인해 실시간, 대규모 데이터를 처리하고 분석해야 하는 곳에서는 카프카를 사용한다. 

 

카프카 서버 구성하기

카프카를 구성해서 서비스 한다고 하면 다음의 4가지 서비스를 띄워야 한다: 주키퍼, 브로커, 프로듀서, 컨슈머

https://www.splunk.com/en_us/blog/devops/monitoring-kafka-performance-with-splunk.html

먼저, 주키퍼 클러스터를 띄운다. 주키퍼는 브로커의 운영을 담당한다.
그 다음, 브로커를 띄워 메시지를 저장할 수 있는 상태로 만든다.
여기까지 하면 카프카 서버 구성을 끝낸 것이다.

이제 프로듀서를 띄워 브로커에 메시지를 보내고, 컨슈머를 띄워 브로커에서 메시지를 읽어올 수 있게 하면 
카프카를 이용해서 서비스를 할 수 있게 된다. 

즉, 프로듀서가 메시지를 발행 → 브로커가 메시지 저장 → 컨슈머가 메시지 구독 및 처리를 해서 서비스를 하게 된다. 

 

토픽은 메시지를 구분하는 무언가!

프로듀서에서 메시지를 보낼 때 꼭 토픽을 지정해야 하고, 브로커에도 토픽이 등록되어 있어야 발행된 메시지가 저장된다. 컨슈머가 메시지를 받기 위해서는 컨슈머가 토픽을 구독해야 한다. 

토픽을 생성할 때는 파티션 갯수와 레플리케이션 팩터를 지정한다. 
파티션 갯수는 한 번에 읽을 수 있는 처리량과 관련이 있고, 레플리케이션 팩터는 복제본을 수와 관련이 있다.

파티션 갯수가 1개일 때는 동시에 1개 읽고 쓰기가 가능한데, 파티션 갯수가 3개일 때는 컨슈머를 최대 3개까지 붙일 수 있어서 동시에 3개을 읽고 쓰기가 가능하다. 트래픽이 많아서 빠르게 읽고 써야할 때는 파티션 갯수를 늘리는 편이 좋다. 

레플리케이션 팩터는 원본까지 포함하는 갯수다. 레플리케이션 팩터가 1일 때는 원본만 있고, 레플리케이션 팩터가 3일 때는 원본1개 복사본 2개가 있다. 복제를 많이하면 안정적이지만 동기화하는 시간이 많이 든다. 그래서 메시지가 중간에 유실되면 안 되는 경우인지 생각해보고 레플리케이션 팩터를 조정한다. 

 

메시지는 브로커에 로그 파일인 세그먼트로 저장된다. 

메시지는 브로커에 물리적으로 어떻게 저장될까? 정답은 로그파일 안에 저장된다이다.
브로커의 로그 폴더 하위에 {토픽명}-{파티션번호}라는 폴더가 생기고, ~~~.log 파일이 생기는 데, 이 속에 메시지 데이터가 저장된다.

위 그림에서 토픽명이 일정일 때, 크리스마스라는 데이터가 파티션3에 저장되었다. 이 경우, "일정-3"이라는 폴더의 하위에 세그먼트가 저장된다. 

참고로, 로그폴더는 브로커 설정 파일에 설정되어 있다. 

메시지는 브로커에 세그먼트라는 로그파일로 저장된다. 브로커의 로그 폴더 위치에 토픽명과 파티션 명으로 로그 폴더가 생긴다. 이 로그 폴더 하위에 저장된 로그가 바로 그 토픽의 그 파티션에 저장된 데이터들이라고 보면된다. 

 

브로커는 동기화된 복제본들(ISR)을 구성할 수 있어서 안정적으로 서비스할 수 있다.

https://hoing.io/archives/57262

카프카는 파티션의 리플리카를 구성해놓으면 알아서 리더를 선출하고, 동기화하고, 장애가 나면 ISR 중에서 새 리더를 선출하는 등의 작업을 해준다. 그래서 안정적으로 서비스할 수 있다. 

프로듀서와 컨슈머는 리더랑만 커뮤니케이션 한다. 프로듀서는 리더에 메시지를 전송하고, 컨슈머는 동기화가 끝난 메시지를 리더로부터 읽어온다. 

 

프로듀서의 동작

https://www.confluent.io/resources/kafka-the-definitive-guide/

 

프로듀서의 동작은 다음과 같다. 

  • 토픽에 메시지를 전송해달라고 프로듀서에게 요청
  • 프로듀서는 설정된 키 시리얼라이저와 밸류 시리얼라이저로 키와 밸류를 시리얼라이즈
  • 파티셔너를 통해 파티션을 결정한다. 
    • 파티션값이 있다 → 그 파티션으로 
    • 키값이 있다 → 키값 해시함수돌려서 파티션 결정 (키값이 같으면 늘 같은 파티션)
    • 키값이 없다 → 파티셔너에 설정된 정책에 따라 파티션 결정
    • 참고로, 같은 파티션에 저장되어야 순서가 보장된다. 
  • 배치 메모리에 저장. 배치가 꽉 차거나 일정 시간이 지나야 전송된다
  • 브로커에 전송
  • 전송이 보장되어야 하는 경우 acks 옵션을 써서 전송 보장을 확인하고, 실패 시 몇 번 재시도 한다.
    • acks = 0 (에러뱉기), 1 (리더 전송 보장), -1 (리더와 팔로워 모두 전송 보장)

 

컨슈머의 동작1: 컨슈머 오프셋

https://velog.io/@tnqlsdl1300/consumerLag

컨슈머는 파티션의 데이터를 읽어간 후, 다음에 읽어야할 파티션의 오프셋 번호를 기록한다. 이를 오프셋을 커밋한다고 한다. 

컨슈머 랙은 파티션에 쓰여진 데이터와 컨슈머가 읽어간 데이터의 오프셋 차이를 말한다. 컨슈머가 데이터가 쓰여지는 속도를 감당하기 힘들면 컨슈머 랙이 커진다. 

처음에 파티션을 읽을 때는 오프셋 커밋이 없다. 이 때 뭐부터 읽을 지는 auto.offset.reset 옵션에 달려있다. 

  • earliest: 처음부터
  • latest: 최근 데이터부터
  • none: 에러 뱉기

오프셋 커밋을 자동으로할 지 enable.offset.commit 옵션을 설정할 수 있다. 커밋 여부를 조작하거나 읽고 나서 특정한 작업을 마쳐야 커밋한 것으로 치고 싶으면 enable.offset.commit=false로 설정하여 수동으로 커밋하면 된다.

 

컨슈머의 동작2: 컨슈머 그룹

컨슈머가 토픽을 구독할 때, 컨슈머 그룹 단위로 구독할 수 있다. 컨슈머 그룹은 컨슈머를 생성할 때 지정할 수 있다. 컨슈머 그룹에 속한 컨슈머들은 토픽의 파티션들을 골고루 나눠서 갖는다. 컨슈머 그룹 속 컨슈머는 변경될 수 있고, 그럼에도 파티션은 골고루 분산되어야 한다. 카프카에서는 브로커 중 하나에 컨슈머 코디네이터를 두어 컨슈머 그룹 내 컨슈머들이 잘 살아있는 지 확인하고, 변경이 있으면 컨슈머들의 파티션을 재분배한다. 이를 리밸런싱이라 부른다. 

 


참고

되게 많이 봐서 다 찾기는 힘들고, 이미지 출처만이라도 표시한다. 

 

 

마치며. 올해 목표로 했던 카프카 공부를 해내어 뿌듯하다 🦹‍♀️ 나도 할 수 있다!! 🫶🏻

'인프라' 카테고리의 다른 글

카프카 스키마 레지스트리 구성하기  (0) 2023.09.22
카프카 클러스터 구성하기  (0) 2023.09.17
13. 도커 스웜-1  (0) 2021.04.19
10. 도커 스토리지  (0) 2021.04.04
11. Docker Compose  (0) 2021.04.03