카프카 토픽과 파티션 그리고 레코드

토픽과 파티션 그리고 레코드

Featured image

토픽과 파티션

토픽은 카프카에서 데이터를 구분하기 위해 사용하는 단위

토픽은 1개 이상의 파티션을 소유하고 있고, 파티션에는 프로듀서가 보낸 데이터, 즉 레코드가 저장된다.

파티션은 그룹으로 묶인 컨슈머들이 레코드를 병렬로 처리할 수 있도록 매칭된다.

처리량 증가를 위한 가장 효과적인 방법으로는 컨슈머의 개수를 늘리고 이에 맞춰 파티션의 개수도 늘리는 것이다.

토픽 이름 제약 조건

추천되는 토픽 작명법으로는 스네이크 표기법을 추천한다.

<환경>.<팀명>.<애플리케이션명>.<메시지타입> (ex. release.partner.advert.json)

적정 파티션 개수

파티션의 개수가 곧 카프카의 성능을 좌우한다.

토픽 생성 시 파티션 개수 고려사항

데이터 처리량

데이터 처리 속도를 높이려면 컨슈머 서버를 스케일업, 혹은 GC튜닝을 통해 처리량을 높이거나, 컨슈머 서버를 스케일 아웃함으로써 높일 수 있다. 여기서 스케일 아웃을 하게되면 이에 따라 파티션의 개수도 늘려야 효과를 볼 수 있는데, 파티션의 적정 개수는 아래와 같이 구해볼 수 있다.

프로듀서 전송 처리량 < 컨슈머 데이터 처리량 * 파티션 개수

예를 들어, 프로듀서에서 초당 1000레코드로 데이터를 보내고 컨슈머에서 초당 100레코드를 처리할 수 있다면 적정 파티션 개수는 10개이다

컨슈머 그룹 처리량이 프로듀서 처리량에 미치지 못하면 컨슈머 랙이 생기고 처리 지연이 발생하게 된다.

메시지 키 사용

메시지 키 사용 여부는 데이터 처리 순서와 밀접관 연관이 있다. 메시키 키가 없었다면 어차피 순서 상관 없이 라운드 로빈 형태로 파티션에 메시지가 할당됏지만, 메시지 키를 사용하면 해당 메시지 키에 해당하는 특정 파티션에 매칭이 되게 되고, 이 때 파티션 개수가 달라지게 되면 매칭됬던 파티션과 메시지 키의 매칭이 깨지게 되고 전혀 다른 파티션에 다시 데이터가 할당된다. 이 순간 데이터 처리 순서가 달라질 수 있게 된다.

메시지 키를 사용하고 컨슈머에서 메시지 처리순서가 보장되어야 한다면 최대한 파티션의 개수는 변화가 없어야 한다.(안그럼 커스텀 파티셔너를 개발해서 처리해야됨)

브로커, 컨슈머 영향도

운영체제에서는 프로세스당 열 수 있는 파일의 최대 개수를 제한하고 있기 때문에 브로커 당 파티션 개수를 파악해둬야 한다.

토픽 정리 정책

토픽의 데이터는 시간 또는 용량에 따라 삭제 규칙을 적용할 수 있다. 또는 삭제되지 않게 설정할 수도 있다.

데이터 처리 설정 옵션으로 cleanup.policy 옵션을 사용할 수 있다. 2가지 삭제 옵션을 설정 할 수 있는데 완전 삭제의 delete, compact로 동일 메세지 키의 가장 오래된 데이터를 삭제할 수 있다.

옵션 설명
`cleanup.policy=delete` `retention.ms` 옵션을 통해 일정 주기마다 세그먼트 마지막 파일 수정 시간과 `retention.ms`를 비교하여 마지막 수정시간이 넘어가면 세그먼트는 완전 삭제
`cleanup.policy=compact` 가장 마지막으로 업데이트된 메시지 키의 데이터가 중요할 경우 가장 최신의 데이터를 제외한 나머지 데이터부터 삭제

토픽 삭제 정책(delete)

cleanup.policy=delete

일반적인 설정 방법으로, 토픽의 데이터 삭제 시 세그먼트 단위로 삭제된다. 세그먼트는 파티션 마다 생성되며 파일명은 가장 작은 오프셋이 된다. segment.bytes 옵션으로 세그먼트 크기를 설정할 수 있다.

삭제 정책이 실행되는 시점은 시간 또는 용량이다. retention.ms 옵션을 통해 일정 주기마다 세그먼트 마지막 파일 수정 시간과 retention.ms를 비교하여 마지막 수정시간이 넘어가면 세그먼트는 삭제된다.

retention.bytes 옵션은 토픽의 최대 데이터 크기를 제어 한다. retention.bytes 옵션 값을 넘어간 세그먼트 파일은 삭제된다.

토픽 압축 정책(compact)

cleanup.policy=compact

토픽의 압축 개념은 메시지 키 별로 해당 메시지 키의 레코드 중 오래된 데이터를 삭제하는 정책을 의미한다.

토픽 압축 정책은 가장 마지막으로 업데이트된 메시지 키의 데이터가 중요할 경우 가장 최신의 데이터를 제외한 나머지 데이터부터 삭제할 수 있게 동작되기 때문에 카프카 스트림즈의 KTable과 같이 메시지 키를 기반으로 데이터를 처리하는 경우 유용하다.

ISR(In-Sync-Replicas)

ISR은 리더 파티션과 팔로워 파티션이 모두 싱크 된 상태를 말한다.

팔로워 파티션이 리더 파티션으로부터 데이터를 복제하는 데에는 시간이 걸린다. 이 시간차 때문에 리더 파티션과 팔로워 파티션 간에 오프셋 차이가 발생하게 된다. 이런 차이를 모니터링하기 위해 리더 파티션은 replica.lag.time.max.ms 옵션에 설정된 시간만큼(default: 10초)의 주기를 갖고 팔로워 파티션이 데이터를 복제하는지 확인한다. 만약 위 옵션 값보다 더 긴 시간동안 데이터 복제가 이뤄지지 않았을 경우 해당 팔로워 파티션에 문제가 발생한 것으로 판단하여 ISR 그룹에서 제외된다.

ISR그룹에서 제외된 파티션은 복제가 모두 이뤄지지 못한 파티션이기 때문에 새로운 리더 파티션 선출 후보에서 제외된다. 이 과정에서 잠시 서비스가 중단될 수 있다.

데이터 유실되어도 상관이 없다면 ISR그룹에서 제외된 파티션도 리더 파티션 선출 자격을 주기위해 unclean.leader.election.enable=true 옵션을 설정하면 된다.

옵션 특징 장점 단점
unclean.leader.election.enable=true 리더 파티션 선출 후보에서 제외되지 않음 서비스가 중단되지 않음. 데이터 복제에 실패하여 리더 파티션을 다시 선출하는 과정에서 데이터 유실될 수 있음.
unclean.leader.election.enable=false 리더 파티션 선출 후보에서 제외됨. 데이터 유실되지 않음. 서비스가 중단됨.

unclean.leader.election.enable 설정은 서비스 운영 정책에 따라 결정한다. 이 옵션은 토픽별로 다르게 설정이 가능하다.

레코드

레코드는 타임스탬프, 메시지 키, 메시지 값, 오프셋, 헤더로 구성된다.

오프셋과 타임스탬프는 프로듀서가 생성한 레코드가 브로커로 전송되어 저장될 때 생성된다. 저장된 레코드는 수정할 수 없다.

메시지 키는 메시지 값을 순서대로 처리해야 하거나 메시지 값의 종류를 구분해야 할 때 사용한다. 메시지 키가 생성되면 키 값별로 파티션이 지정된다.

메시지 값은 직렬화, 역직렬화 과정을 거친다.