실전 카프카 개발부터 운영까지
라는 책을 보고 정리한 내용을 바탕으로 하고 있습니다.
카프카는 브로커 클러스터 중 한두 대에서 장애가 발생하더라고 안정적인 서비스가 운영될 수 있도록 설계되었다. 이 때 안정성을 확보하기 위해서 카프카 내부에서는 리플리케이션
이라는 동작을 하게 된다. 카프카는 replication factor 라는 옵션을 이용해서 관리자가 지정한 수 N만큼의 리플리케이션을 가질 수 있기 때문에 N-1 대에서 장애가 발생해도 메세지 손실 없이 안정적으로 메세지를 주고 받을 수 있다.
카프카에서는 여러 리플리케이션들 중에서 리더와 팔로워가 존재하며 모든 읽기와 쓰기는 해당 리더를 통해서만 가능하다. 나머지 팔로워들은 장애 상황을 대비하고 있다. 이 대비하는 과정에서도 아무것도 하지 않는 것이 아니라 언제든 새로운 리더가 될 준비를 하고 있다. 즉, 리더가 메세지를 받았는지 확인하고 받았다면 새로운 메세지를 리더로부터 복사한다.
리더와 팔로워는 ISR(InSyncReplica)
이라는 논리적 그룹으로 묶여있다. 해당 그룹에서 리더는 읽기/쓰기 작업뿐만 아니라 팔로워들을 감시하며 특정 시간 이내에 새로운 메세지 복사가 일어나지 않을 경우 팔로워를 ISR 그룹에서 제거한다. ISR 내에서 모든 리더들의 복제가 완료되면 리더는 내부적으로 커밋 표시를 하며 마지막 커밋 오프셋 위치를 하이워터마크
라고 부른다.
또한 카프카는 리더와 팔로워 사이의 리플리케이션 과정이 일어날 때 ACK 과정을 생략해서 속도를 향상시켰다. 그렇다면 어떻게 메시지가 잘 복사됐다는 것을 신뢰할까? 리플리케이션 동작이 리더가 푸시하는 형식이 아닌, 팔로워가 풀해가는 형식이기 때문에 리플리케이션 요청의 오프셋을 보고 어느 위치까지 리플리케이션을 성공했는지 알 수 있다. 추가로 리더에게 과부하를 줄이는 역할도 한다.
리더에포크(leader epoch)
는 카프카의 파티션들이 복구 동작을 할 때 메시지의 일관성을 유지하기 위한 용도로 사용한다. 리더에포크는 컨트롤러에 의해 관리되며 새로운 리더 선출시에 전달되고 복구 동작 시에 하이워터마크를 대체하는 수단으로도 활용된다.
리더가 장애가 났다가 복구가 됐을 때의 동작을 살펴보자.
뉴리더가 자신이 팔로워일 때의 하이워터마크와 뉴리더일때의 하이워타마크를 알고 있다는 사실이 중요!
리더 선출을 맡고 있는 컨트롤러.
리더 선출을 위해서 ISR 정보는 가장 안전한 주키퍼에 저장되어 있다. 파티션의 리더가 다운 될 경우 카프카 클라이언트인 프로듀서나 컨슈머의 읽기/쓰기 작업이 일어나지 않으며 클라이언트에 설정되어 있는 재시도 숫자만큼 재시도를 하게 된다. 이 기간안에 컨트롤러는 빠르게 뉴리더를 선출하고 해당 정보를 다른 브로커들에게 알려야 한다.
이 때 제어된 종료와 급작스러운 종료에 따라서 선출 과정이 달라진다.
제어된 종료의 장점은 뭘까?
카프카의 토픽으로 들어오는 메시지는 로그 세그먼트라는 파일에 저장된다.
이 때 하나의 로그 세그먼트 크기가 너무 커져버리면 관리에 어려움이 생기기 때문에 1GB보다 커지는 경우에 롤링 전략
을 사용한다.
이 때 이런 로그 세그먼트들이 무제한으로 생기는 것을 막기 위해 두가지 방법을 사용한다.
로그 세그먼트 삭제
토픽마다 보관 주기를 조정
로그 세그먼트 컴팩션
로그를 컴팩션하여 저장
ex) _consumer_offset 토픽에서 키에 대한 마지막 밸류만 저장