Search
Duplicate

아파치 카프카의 생태계

저자
최원영
점수
⭐️⭐️⭐️⭐️
완료일
2024/02/04
상태
완료
유형
인강

카프카 생태계

기본동작
프로듀서 → 카프카클러스터 → 컨슈머
프로듀서에서 카프카 클러스트로 들어온 값을 신규 토픽으로 만들려면 스트림즈를 사용하면 된다.
프로듀서 → 카프카 클러스터 → 스트림즈 → 토픽 순으로 변경하
커넥트 (소스) 와 커넥트 (싱크)는 소스는 프로듀서, 싱크는 컨슈머와 비슷한 역할을 한다.
일반 프로듀서와 컨슈머와 다른 가장큰 차이점은 클러스터 단위로 운영한다는 것이고, 반복 적으로 템플릿 단위로 여러번 생성해서 사용할 수 있다.

카프카 브로커와 클러스터

주키퍼 : 카프카 클러스트를 운영하기 위해 반드시 필요함
클러스터 : 여러대의 브로커를 의미한다.
브로커 : 하나의 서버에는 한개의 브로커 프로세스가 실행됨.
한개로 운영이 가능하나 데이터를 안전하게 보관하고 처리하기 위해 기본적으로 3대 이상으로 운영한다.
프로듀서가 데이터를 전송하게 되면, 3개의 브로커로 운영하게 될 시 브로커 0, 1, 2 모두 데이터를 저장하게 된다.
1개의 클러스터에는 여러개의 브로커가 존재할 수 있다.
일반적으로 3개로 운영하고, 데이터가 많다면 50 ~ 100개 까지 늘리는 경우가 있다.

여러개의 카프카 클러스터가 연결된 주키퍼

주키퍼 앙상블 : 하나의 주키퍼 앙상블에는 여러개의 주키퍼를 설정해놓고 여러개의 클러스터를 운영할 수 있다.
ex) 카프카 클러스터 0 : 주문, 카프카 클러스터 1 : 배송, 카프카 클러스터 3 : 결제
이렇게 하는 이유는? 클러스터를 운영하기 위해서는 하나의 주키퍼가 필수로 필요한데, 이렇게 될 경우 리소스 낭비가 발생되여 위와 같은 형태로도 운영한다.

브로커의 역할

컨트롤러
클러스트 안에 다수중 한 대의 브로커가 컨트롤러 역할은 한다.
컨트롤러는 다른 브로커들의 상태를 체크를 하며, 문제가 발생할 시 해당하는 브로커의 리더 파티션을 다른 브로커로 재분배 하게 해준다.
지속적으로 실시간 데이터를 운여하기 위해.
컨트롤러에 장애가 발생하면 → 다른 브로커가 컨트롤러 역할을 한다.
데이터 삭제
카프카는 컨슈머가 데이터를 가져가도 삭제되지 않는다, 오직 브로커만 데이터를 삭제가 가능하다.
데이터 삭제는 파일단위로 이루어지는데 이 단위를 로그세그먼트 라 부른다.
데이터 삭제의 기준은
용량 : 로그 세그먼트 단위로 지정 용량이 도래 되었을 때 삭제
시간 : 로그 세그먼트 단위가 지정 시간이 도래 되었을 때 삭제
특수한 상황일 때 : 최신 레코드 키를 제외하고 데이터를 삭제하고 싶을 때는 compact 옵션을 통해 삭제 할 수 있다.
컨슈머 오프셋 저장
컨슈머 그룹은 파티션의 어느 레코드까지 가져갔는지 확인하기 위해서 오프셋을 커밋한다.
그룹 코디네이터
컨슈머가 컨슈머 그룹에서 빠지면 매칭되지 않는 파티션을 정상 동작하게 컨슈머로 할당하여 끊임없이 데이터가 처리되게 도와준다.

브로커의 역할 - 데이터 저장

경로 : config/server.properties의 log.dir옵션에 저장한 디렉토리에 데이터를 저장

로그와 세그먼트

log.segment.byte : 바이트 단위의 최대 세그먼트 크기 지정. 기본 값은 1GB
log.roll.ms(hour) : 세그먼트가 신규 생성된 이후 다음 파일로 넘어가는 시간 주기. 기본 값은 7일
최초의 오프셋 번호가 파일의 이름이 된다. → 이는 로그파일이 몇번의 오프셋 까지 데이터가 저장됬는지 유추할 수 있게 해준다.
현재 쓰여지고 있는 세그먼트를 엑티브 세크먼트라고 한다.

세그먼트와 삭제 주기 (cleanup.policy = delete)

데이터 삭제 단위는 .log 파일 단위로 삭제가 가능하다, 레코드 별 오프셋은 삭제가 불가능하기 때문에 프로듀서, 컨슈머 각각에 대해 정말 유효한 데이터가 맞는지 확인하는 구문이 필요함.
retention.ms(minutes, hours) : 세그먼트를 보유할 최대 기간. 기본 값은 7일
너무 많은 기간을 선택하게 될 시, 내 디스크 용량을 체크해서 진행해야된다.
일반적으로 최대 기간을 3일로 지정한다. (토, 일)이 보통 휴무 이기 때문
retention.bytes : 파티션 로그 적재 바이트 값 기본 값은 -1
log.retention.check.interval.ms : 세그먼트가 삭제 영역에 들어 왔는지 확인하는 간격. 기본 값은 5분

cleanup.policy=compact

key-value 형태로 중복된 값을 삭제하여, 최신의 데이터를 사용한다.

테일/헤드 영역, 클린/더티 로그

테일 영역 : 압축 정책에 의해 압출이 완료된 레코드들, 클린(clean)로그 라고 부른다. 중복 메시지 키가 없다.
헤드 영역 : 압축 정책이 되기 전 레코드들 더티(dirty)로그 라고도 부른다. 중복된 메시지 키가 있다.

min.cleanable.dirty.ratio

데이터의 압축 시작 시점은 min.cleanable.dirty.ratio 옵션값을 따름
테일 영역의 레코드 개수와 헤드 영역의 레코드 개수의 비율을 뜻하며, 0.5로 설정한다면 테일 영역의 레코드 개수가 헤드 영역의 레코드 개수와 동일할 경우 압축이 진행된다.

브로커의 역할 - 복제 (Replication)

데이터 복제는 카프카를 장애 허용시스템으로 동작하도록 하는 원동력이다.
데이터 복제는 파티션 단위로 이루어진다.
토픽을 설정할 때 파티션 갯수도 설정한다. 이때 파티션 갯수 옵션을 설정하지 않으면 브로커 설정 기반으로 설정이 된다.
복제의 갯수는 최소값 1(복제 없음) 이고, 최대값은 브로커 갯수만큼 설정하여 사용할 수 있다.
팔로워 파티션은 리더의 파티션의 오프셋을 확인하여 자신이 가지고 있는 오프셋과 비교하고, 없는 데이터를 복제하여 가져온다.
보통 복제는 2~3으로 설정하여 동작시킨다.

ISR(In-Sync-Replicas)

리더 파티션과 팔로워 파티션이 모두 싱크가 된 상태
팔로워 파티션이 리더 파티션의 복제를 다 하지 못한 상태에서 리더 파티션이 장애가 발생하게 되면, 데이터가 유실 될 수 있다. 이때 유실된 데이터를 무시하고 계속 데이터를 진행하려면 옵션을 줘야 된다.
unclean.leader.election.enable = true : 유실을 감수, 복제가 안된 파티션 팔로워를 리더로 승급
unclean.leader.election.enable = false : 유실을 감수 하지 않음 , 해당 브로커가 복구될 때 까지 중단.

토픽과 파티션

토픽 : 카프카에서 데이터를 구분하기 위해 사용하는 단위
파티션 : 프로듀서가 보내 데이터들이 들어가 저장되는 곳 이 데이터를 레코드라 부른다.
파티션의 레코드는 컨슈머가 가져가는 거소가 별개로 관리, 이러한 특징 때문에 레코드는 다양한 목적을 가진 여러 컨슈머 그룹들이 토픽의 데이터를 여러번 가져갈 수 있다.

토픽 생성시 파티션이 배치되는 방법

파티션이 5개라고 가정하면 그림과 같으 0번 브로커 부터 시작하여 round-robin 방식으로 리더 파티션들이 생성 됨.
카프카 클라이언트는 리더 파티션이 있는 브로커와 통신하여 데이터를 주고 받으므로 여러 브로커에 골고루 네트워크 통신을 하게 된다. → 데이터가 특정 브로커에 집중되는 hot spot 현상을 방지

토픽 생성시 파티션이 배치되는 방법

위와 같이 리더 파티션이 만들어 지면 순차적으로 팔로워 파티션이 만들어짐.

특정 브로커에 파티션이 쏠린 현상

특정 브로커에 파티션이 몰리는 경우 kafka-reassing-partions.sh 명령으로 파티션을 재분배 한다.

파티션 개수와 컨슈머 개수의 처리량

파티션은 카프카의 병렬처리의 핵심으로써 그룹으로 묶인 컨슈머들이 레코드를 병렬로 처리 할 수 있도록 매칭된다.
컨슈머의 처리량이 한정된 상황에서 많은 레코드를 병렬로 처리하는 가장 좋은 방법은 컨슈머의 개수를 늘려 스케일 아웃하는 것
컨슈머 개수를 늘림과 동시에 파티션 개수도 늘리면 처리량이 증가하는 효과를 볼 수 있다.
현재 프로듀서가 데이터를 1초당 10개의 데이터를 보내고, 컨슈머는 초당 1개의 데이터를 처리한다고 가정하면, 컨슈머 렉이 발생이 되면서 지연이 발생한다.
이를 방지하기위해 파티션의 개수를 늘리고 컨슈머의 개수를 늘려 병목현상이 발생되는 부분을 풀어줘야된다.
중요한 것은 파티션 갯수를 늘리면 줄이수 없다는 것이다. 때문에 파티션을 늘릴때에는 신중할 필요가 있다.

레코드

레코드 구성
타임스템프
헤더
메세지 키
메세지 값
오프셋
프로듀서가 생성한 레코드가 → 브로커로 전송되면 오프셋과 타임스템프가 저장된다. 브로커에 한번 적재된 레코드는 수정할 수 없다. 로그 리텐션 기간 또는 용량에 의해 삭제된다.

토픽 작명의 템플릿과 예시

<환경>.<팀-명>.<애플리케이션-명>.<메시지-타입>
예시) prd.marketing-team.sms-platform.json
<프로젝트-명>.<서비스-명>.<환경>.<이벤트-명>
예시) commerce.payment.prd.notification
<환경>.<서비스-명>.<JIRA-번호>.<메시지-타입>
예시) dev.email-sender.jira-1234.email-vo-custom
<카프카-클러스터-명>.<환경>.<서비스-명>.<메시지-타입>
예시) aws-kafka.live.marketing-platform.json