본문 바로가기
Dev/Kafka

Kafka retention 옵션 - log 보관 주기 설정

by 돈코츠라멘 2020. 12. 2.

Kafka log(Message Data)의 보관은 크게 시간단위, 용량단위로 지정할 수 있다. 만약 아무런 옵션을 수정하지 않고 Kafka를 실행하였다면 기본적으로 7일로 지정된 상태이다. - 저장한지 7일이 지난 로그는 삭제된다.

log 보관주기에 대한 설정은 $KAFKA_HOME/config/server.properties에 있으며 아래와 같은 기본값을 가진다.

############################# Log Retention Policy #############################

# The following configurations control the disposal of log segments. The policy can
# be set to delete segments after a period of time, or after a given size has accumulated.
# A segment will be deleted whenever *either* of these criteria are met. Deletion always happens
# from the end of the log.

# The minimum age of a log file to be eligible for deletion due to age
log.retention.hours=168

# A size-based retention policy for logs. Segments are pruned from the log unless the remaining
# segments drop below log.retention.bytes. Functions independently of log.retention.hours.
#log.retention.bytes=1073741824

# The maximum size of a log segment file. When this size is reached a new log segment will be created.
log.segment.bytes=1073741824

# The interval at which log segments are checked to see if they can be deleted according
# to the retention policies
log.retention.check.interval.ms=300000

여기서 우리는 log.retention.{ms|minutes|hours} 또는 log.retention.bytes 설정을 수정하여 보관주기를 변경할 수 있다.

  • log.retension.{ms|minutes|hours} : log 파일의 최소 사용 기간(default: 168시간;7일)
  • log.retention.bytes : log 파일의 최소 용량(default: -1; 제한없음)

log.retension.{ms|minutes|hours}

  • log 파일의 최소 사용 기간
  • log.retension.ms: 초 단위로 지정
  • log.retension.minutes: 분 단위로 지정
  • log.retension.hours: 시간 단위로 지정
  • (주의) log.retention.check.interval.ms 설정은 삭제할 대상을 확인하는 시간주기 값으로, default 5분이다. 만약 설정한 log.retension.{ms|minutes|hours} 값이 이 값보다 짧으면 원하는 시간주기대로 log를 삭제하지 못할 수 있다.

Test!

  1. 설정 변경

1분이 지난 로그는 삭제하도록 설정(+ log.retention.check.interval.ms도 10초 단위로 변경)

# config/server.properties
log.retention.ms=60000 # 1min
#log.retention.bytes=1073741824
log.segment.bytes=1073741824
log.retention.check.interval.ms=10000 # 10sec
  1. 30초 단위로 logs.dir 용량 watch
$ watch -n 30 'du -h'

현재 12KB

Every 30.0s: du -h 
Tue Dec  1 11:17:51 2020

12K     ./fds.t-0
  1. 100TPS로 Produce (Consumer는 동작하지 않음)

용량이 점차 증가함

Every 30.0s: du -h
Tue Dec  1 11:19:21 2020

1.4M    ./fds.t-0
Every 30.0s: du -h
Tue Dec  1 11:20:51 2020

4.7M    ./fds.t-0
  1. Produce 종료
Every 30.0s: du -h
Tue Dec  1 11:21:51 2020

4.7M    ./fds.t-0
Every 30.0s: du -h
Tue Dec  1 11:22:51 2020

12K     ./fds.t-0

1분이 지난 후 Partition 용량이 처음과 같아짐

log.retension.bytes

  • log 파일의 최소 용량
  • 파티션당 용량이므로 Topic의 수, Partition의 수를 고려해서 설정해야 함(ex. 물리서버 3대 + Partition 3개 + Replication 2로 설정된 환경에서는 각 물리서버당 2개의 Partition이 저장됨 → log.retension.bytes를 1G로 설정하면 디스크는 2G까지 차지함)
  • (주의) log.retension.bytes 옵션은 Segment 단위로 log 파일을 삭제함 → Segment가 하나밖에 없는 경우는 정상적으로 삭제되지 않을 수 있음
  • 따라서, log.segment.bytes 설정을 log.retention.bytes 이하의 값으로 지정하여 Segment를 분리해줘야 정상적으로 동작

Test!

단일 Segment

  1. 설정 변경

1MB 넘으면 로그 삭제 (+ log.retention.check.interval.ms도 1초 단위로 변경)

# config/server.properties
log.retention.hours=24
log.retention.bytes=1048576 # 1MB
log.segment.bytes=1073741824 # 1GB
log.retention.check.interval.ms=1000 # 1sec

하지만 log.segment.bytes는 default 설정인 1GB를 그대로 사용하여 단일 Segment에만 계속 write하는 상황으로 테스트

$ cd /tmp/kafka-logs/fds.t-0
$ ll
  total 1872
       4096 12월  1 11:29 ./
       4096 12월  1 11:39 ../
   10485760 12월  1 11:38 00000000000000008300.index
    1889948 12월  1 11:39 00000000000000008300.log
   10485756 12월  1 11:38 00000000000000008300.timeindex
         11 12월  1 11:29 leader-epoch-checkpoint
  1. 5초 단위로 용량 watch

현재 8KB

Every 5.0s: du -h
Tue Dec  1 11:33:28 2020

8.0K     ./fds.t-0
  1. 10TPS로 Produce (Consumer는 동작하지 않음)

용량이 점차 증가함

Every 5.0s: du -h
Tue Dec  1 11:33:38 2020

48K     ./fds.t-0
Every 5.0s: du -h
Tue Dec  1 11:36:49 2020

1.1M    ./fds.t-0
  1. 1MB 초과

설정된 용량인 1MB를 넘어도 계속해서 logs.dir 용량이 증가 - log 파일이 삭제되지 않음

Every 5.0s: du -h
Tue Dec  1 11:39:23 2020

1.9M    ./fds.t-0

Segment 분리

위 테스트 환경에서 offset을 reset하지 않고 그대로 segment 설정만 바꿔서 테스트 진행

  1. 설정 변경

log.segment.bytes 설정을 512KB로 설정 - 512KB 단위로 log 파일이 분리됨

# config/server.properties
log.retention.hours=24
log.retention.bytes=1048576 # 1MB
# log.segment.bytes=1073741824
log.segment.bytes=524288 # 512KB
log.retention.check.interval.ms=1000 # 1sec
  1. Kafka 재기동
    설정을 변경한 후 kafka를 재기동해도 기존 log 파일에는 변화가 없음
Every 5.0s: du -h
Tue Dec  1 13:53:58 2020

2.1M    ./fds.t-0
$ ll
  total 2088
       4096 12월  1 13:52 ./
       4096 12월  1 13:53 ../
   10485760 12월  1 13:52 00000000000000008300.index
    2107831 12월  1 11:39 00000000000000008300.log
   10485756 12월  1 13:52 00000000000000008300.timeindex
         10 12월  1 13:52 00000000000000011889.snapshot
         11 12월  1 13:52 leader-epoch-checkpoint
  1. 10TPS로 Produce (Consumer는 동작하지 않음)
$ ll
  total 2172
       4096 12월  1 13:54 ./
       4096 12월  1 13:54 ../
       4096 12월  1 13:54 00000000000000008300.index
    2107831 12월  1 11:39 00000000000000008300.log
       6156 12월  1 13:54 00000000000000008300.timeindex
   10485760 12월  1 13:54 00000000000000011889.index
      74608 12월  1 13:54 00000000000000011889.log
         10 12월  1 13:52 00000000000000011889.snapshot
   10485756 12월  1 13:54 00000000000000011889.timeindex
         11 12월  1 13:52 leader-epoch-checkpoint

Segemnt가 분리되고 새로 생긴 segment의 용량만 점차 증가

$ ll
  total 2656
       4096 12월  1 13:56 ./
       4096 12월  1 13:56 ../
       4096 12월  1 13:54 00000000000000008300.index
    2107831 12월  1 11:39 00000000000000008300.log
       6156 12월  1 13:54 00000000000000008300.timeindex
       1016 12월  1 13:56 00000000000000011889.index
     523905 12월  1 13:56 00000000000000011889.log
         10 12월  1 13:52 00000000000000011889.snapshot
       1536 12월  1 13:56 00000000000000011889.timeindex
   10485760 12월  1 13:56 00000000000000012781.index
      34629 12월  1 13:56 00000000000000012781.log
         10 12월  1 13:56 00000000000000012781.snapshot
   10485756 12월  1 13:56 00000000000000012781.timeindex
         11 12월  1 13:52 leader-epoch-checkpoint

512KB에 도달하면 새로운 segment를 생성

$ ll
  total 3200
       4096 12월  1 13:57 ./
       4096 12월  1 13:57 ../
       4096 12월  1 13:54 00000000000000008300.index.deleted
    2107831 12월  1 11:39 00000000000000008300.log.deleted
       6156 12월  1 13:54 00000000000000008300.timeindex.deleted
       1016 12월  1 13:56 00000000000000011889.index
     523905 12월  1 13:56 00000000000000011889.log
         10 12월  1 13:52 00000000000000011889.snapshot
       1536 12월  1 13:56 00000000000000011889.timeindex
       1016 12월  1 13:57 00000000000000012781.index
     523838 12월  1 13:57 00000000000000012781.log
         10 12월  1 13:56 00000000000000012781.snapshot
       1536 12월  1 13:57 00000000000000012781.timeindex
   10485760 12월  1 13:57 00000000000000013673.index
      53443 12월  1 13:57 00000000000000013673.log
         10 12월  1 13:57 00000000000000013673.snapshot
   10485756 12월  1 13:57 00000000000000013673.timeindex
         12 12월  1 13:57 leader-epoch-checkpoint

생성된 segment들이 1MB에 도달하면 가장 오래된 segment에 deleted로 mark가 생김

$ ll
  total 1480
       4096 12월  1 13:58 ./
       4096 12월  1 13:58 ../
       1016 12월  1 13:56 00000000000000011889.index
     523905 12월  1 13:56 00000000000000011889.log
       1536 12월  1 13:56 00000000000000011889.timeindex
       1016 12월  1 13:57 00000000000000012781.index
     523838 12월  1 13:57 00000000000000012781.log
         10 12월  1 13:56 00000000000000012781.snapshot
       1536 12월  1 13:57 00000000000000012781.timeindex
   10485760 12월  1 13:58 00000000000000013673.index
     419884 12월  1 13:58 00000000000000013673.log
         10 12월  1 13:57 00000000000000013673.snapshot
   10485756 12월  1 13:58 00000000000000013673.timeindex
         12 12월  1 13:57 leader-epoch-checkpoint

잠시 시간이 지난 후 deleted로 표시된 파일이 삭제됨

  1. 이후
Every 5.0s: du -h
Tue Dec  1 13:59:00 2020

1.5M    ./fds.t-0
$ ll
  total 1808
       4096 12월  1 13:59 ./
       4096 12월  1 13:59 ../
       1016 12월  1 13:56 00000000000000011889.index.deleted
     523905 12월  1 13:56 00000000000000011889.log.deleted
       1536 12월  1 13:56 00000000000000011889.timeindex.deleted
       1016 12월  1 13:57 00000000000000012781.index
     523838 12월  1 13:57 00000000000000012781.log
       1536 12월  1 13:57 00000000000000012781.timeindex
       1016 12월  1 13:59 00000000000000013673.index
     523881 12월  1 13:59 00000000000000013673.log
         10 12월  1 13:57 00000000000000013673.snapshot
       1536 12월  1 13:59 00000000000000013673.timeindex
   10485760 12월  1 13:59 00000000000000014565.index
     222580 12월  1 13:59 00000000000000014565.log
         10 12월  1 13:59 00000000000000014565.snapshot
   10485756 12월  1 13:59 00000000000000014565.timeindex

512KB 단위의 segment들이 계속해서 생성되고 3개 이상의 segment 파일이 생성된 시점에서 가장 오래된 segment에 delete 표시, 삭제가 진행됨

즉, 파일이 지워졌다고 표시되는 시간과 실제 물리적으로 지워지는 시간사이의 갭이 존재 → 디스크 용량이 최소한 log.retention.bytes * (partition 수 + 1) + log.segment.bytes 이상은 있어야 Disk full을 예방할 수 있을것으로 예상

댓글