Kafka

[Kafka] 파티션이 증가할수록 commit_offset log file 리소스도 증가할까?

Hyung1 2025. 4. 6. 21:11
728x90
반응형

안녕하세요. 이전에 파티션 증가 없이 동시 처리량을 늘리기 위해 Parallel Consumer에 관해 살펴보고 PoC를 진행해보았습니다. 파티션이 증가하게 되면 아래와 같은 문제들이 발생합니다 

  • 브로커 파일 시스템 리소스 증가
  • 장애에 더 취약한 구조
  • 복제 비용 증가

저는 이러한 문제들을 해결하기 위해 파티션 증가 없이 동시 처리량을 늘려보고자 하였고 이에 대한 글도 작성하였습니다.

저는 기존 카프카에서 파티션이 증가할 수록 브로커 파일 시스템 리소스가 증가할 것이라고 생각했습니다. 왜냐하면 동시 처리량을 늘리기 위해서는 파티션과 컨슈머를 늘려야합니다. 컨슈머 수가 늘어난 만큼 오프셋 커밋도 늘어나서 comit_offset log file에 기록되는 리소스 또한 증가할 것이라고 생각했기 떄문입니다.

오프셋 커밋은 consumer가 요청하고, 그 요청을 broker의 group coordinator가 받아서
__consumer_offsets라는 내부 topic에 기록하는 구조입니다. consumer마다 발생합니다.

 

하지만, 테스트 결과 제 생각은 틀렸다는 것을 확인할 수 있었습니다.

파티션이 증가할수록 commit_offset log file 리소스도 증가할까?

저는 Kafka에서 토픽 파티션 수(1 vs 3)에 따라__consumer_offsets log 파일 시스템 리소스 용량 차이가 발생하는지 직접 확인해보았습니다. 파티션 수를 1과 3으로 각각 설정하고 메시지를 십만 건 발행, 컨슘, 오프셋 커밋하여  파일 시스템 리소스 용창 차이를 확인해보았습니다. 

 

아래의 명령어로 파일 시스템 리소스 용량 차이를 확인해보았습니다.

# 커밋 로그가 기록된 __consumer_offsets 파티션 확인
find .data -name '*.log' | grep __consumer_offsets

# 각 offsets 파티션별 log 파일 크기 확인
du -ch .data/kafka*/__consumer_offsets-*/*.log

# 전체 __consumer_offsets log 파일 총합 확인
du -ch $(find .data -name '*.log' | grep __consumer_offsets) | tail -n1

 

또한 동일한 consumer group ID를 유지한 채, 메시지 key를 각각 다르게 설정해보았고, key에 % 2 연산을 적용하여 일부러 분산되도록 구성해보기도 했습니다.

실험 결과

  • 파티션 1개 / 파티션 3개 모두 특정 __consumer_offsets-N 디렉토리 하위의 .log file 하나만 리소스 증가
    • 파티션 수 변경시 로그 파일은 초기화하고 다시 테스트하였습니다.
  • 파일 사이즈도 두 경우 모두 64KB로 동일
  • 즉, 파티션 수가 늘어나도 파일 시스템 사용량에는 차이 없음
// find .data -name '*.log' | grep __consumer_offsets
// du -ch .data/kafka*/__consumer_offsets-*/*.log

  
0B	.data/kafka1/__consumer_offsets-11/00000000000000000000.log
0B	.data/kafka1/__consumer_offsets-14/00000000000000000000.log
896K	.data/kafka1/__consumer_offsets-29/00000000000000000000.log
.. 생략
0B	.data/kafka3/__consumer_offsets-7/00000000000000000000.log

 

두 경우 모두 파일 사이즈가 64KB로 동일한 이유가 무엇일까요?

  • 파티션이나 컨슈머 수가 많아도 메시지 단위로 오프셋 커밋하면 커밋 횟수가 같기 때문입니다.
  • 메시지 단위를 배치로 커밋해도 결국 <groupId, topic, partition> 단위의 최신 오프셋만 유지되므로, 메모리 사용량은 크게 달라지지 않습니다.
  • Kafka는 compacted topic 구조를 사용해 offset을 <groupId, topic, partition> 기준으로 덮어쓰기 때문에, 메시지 key가 다르든 같든, 배치 커밋이든 메시지당 커밋이든 관계없이 각 key별로 최신 오프셋만 유지되며, 그 결과 디스크 사용량이 최적화됩니다.
  • Kafka가 offset 커밋을 compacted topic에 덮어쓰는 이유는, “어디까지 읽었는가”만 중요하고, 과거에 뭐까지 읽었는지는 중요하지 않기 때문입니다.

두 경우 모두 특정 __consumer_offsets-N 디렉토리 하위의 .log file 하나만 리소스가 증가한 이유가 무엇일까요?

  • Kafka는 offset commit을 groupId 기준으로 해싱하여 __consumer_offsets 파티션 중 하나에만 기록하기 때문입니다.
  • 따라서 같은 groupId를 사용하면, 모든 커밋이 같은 offsets 로그 파일에만 몰리게 됩니다.

Reference

728x90
반응형