실전 카프카 개발부터 운영까지 - 4.카프카의 내부 동작 원리와 구현 (4)

서영민·2022년 8월 30일
0
post-thumbnail

카프카의 내부 동작 원리와 구현

로그 (로그 세그먼트)

  • 카프카의 토픽으로 들어오는 메세지는 세그먼트라는 파일에 저장된다
  • 메세지는 정해진 형식에 맞추어 순차적으로 로그 세그먼트 파일에 저장된다
  • 로그 세그먼트메세지 내용뿐만 아니라 메세지의 키, 벨류, 오프셋, 메세지 크기 같은 정보도 함께 저장된다
  • 로그 세그먼트 파일들은 브로커의 로컬 디스크에 보관된다
  • 로그 세그먼트의 최대 크기는 1GB가 기본값으로 설정되어있다
  • 로그 세그먼트가 1GB보다 커지게 되는 경우에는 기본적으로 롤링 전략을 적용한다
  • 하나의 로그 세그먼트에 메세지를 덧붙이다가, 로그 세그먼트의 크키가 1GB에 도달하면 해당 세그먼트 파일을 클로즈 하고, 새로운 로그 세그먼트를 생성하는 방식으로 진행된다
  • 롤링 전략이 있지만, 카프카 관리자는 1GB 크기의 로그 세그먼트 파일이 무한히 늘어날 경우를 대비해 로그 세그먼트에 대한 관리 계획을 수립해둬야 한다
  • 로그 세그먼트를 관리하는 방법은 크게 로그 세그먼트 삭제컴팩션으로 구분할 수 있다

로그 세그먼트 삭제

  • 로그 세그먼트 삭제 옵션은 브로커의 설정 파일인 server.properties에서 log.cleanup.policy가 delete로 명시되어야 한다
  • 해당 값은 기본값으로 delete를 가지며, 따로 옵션을 명시하지 않았다면 로그 세그먼트는 삭제 정책이 적용된다

로그 세그먼트 삭제 실습 환경 구성

  1. 토픽생성

    • kafka-topics --bootstrap-server kafka1:9091 --create --topic chaptor4-topic04 --partitions 1 --replication-factor 3
  2. chator4-topic04 토픽에 메세지 log1 전송

  3. 컨슈머를 이용해 chaptor4-topic04 토픽의 메세지를 가져온다. --from-beginning 옵션을 추가해서 강제로 peter-test03 토픽의 처음부터 메세지를 가져올 수 있게 한다

    • kafka-console-consumer --bootstrap-server kafka1:9091 --topic chaptor4-topic04 --from-beginning
  4. chaptor4-topic04 토픽에 retention.ms 옵션을 조정해서 메세지를 삭제해 보도록 한다

  5. kafka-config 명령어를 이용

  6. 콘솔 프로듀서와 콘솔 컨슈머가 실행되어 있다면, ctrl + X 또는 ctrl + C 버튼을 입력해 종료한다

  7. kafka-configs --bootstrap-server kafka1:9091 --topic chaptor4-topic04 --add-config retention.ms=0 --alter

    • 로그 보관 시간이 0보다 클 수 없으므로, 현재 저장된 log1 메세지는 삭제될 것이다
    • 설정이 적용 됐는지 describe로 확인
    • 로그 세그먼트 삭제 주기의 기본값은 5분이므로, 최대 5분후 삭제 작업이 일어난다
    • 5분정도 후에 세그먼트 파일을 확인해보면 0000...000.xx 였던 파일들은 삭제가 되고 0000...001.xx 파일들이 생성된 것을 확인할 수 있다
  8. chaptor4-topic04 토픽에 추가했던 retention.ms 옵션 삭제

    • kafka-configs --bootstrap-server kafka1:9091 --topic chaptor4-topic04 --delete-config retention.ms --alter
  9. 별도의 reteontion.ms 옵션을 설정하지 않으면, server.properties의 옵션 값이 적용된다.

    • 기본값은 7일이므로, 모든 세그먼트 파일은 7일이 지남과 동시에 전부 삭제된다
    • retention.bytes 옵션을 이용해서 지정된 크기 기준으로도 로그 세그먼트를 삭제할 수 있다


로그 세그먼트 컴팩션

  • 컴팩션은 로그를 삭제하지 않고 컴팩션하여 보관할 수 있다
  • 로그 컴팩션은 기본적으로 로컬 디스크에 저장되어 있는 세그먼트를 대상으로 실행한다
  • 현재 활성화된 세그먼트는 제외하고 나머지 세그먼트들을 대상으로 컴팩션이 실행된다

컴팩션 할지라도 카프카의 로컬 디스크에 로그를 무기한 보관한다면, 로그의 용량은 감당할 수 없이 커져서 디스크가 저장할 수 있는 용량의 한계에 도달하게 된다. 카프카에서는 단순하게 메세지를 컴팩션하게 보관하기보다는 좀 더 효율적인 방법으로 컴팩션 한다. 카프카에서 로그세그먼틀를 컴팩션하면 메세지의 키 값을 기준으로 마지막의 데이터만 보관하게 된다

  • 메세지의 키 값을 기준으로 컴팩션하는 방법은 다소 생소할 수 있다
  • 로그 컴팩션 기능을 이용하는 대표적인 사례로는 카프카의 _consumer_offset 토픽이 있다
  • _consumer_offset 토픽은 카프카의 내부 토픽으로, 컨슈머 그룹의 정보를 저장하는 토픽이다
  • 컨슈머 그룹의 중요한 정보는 해당 컨슈머 그룹이 어디까지 읽었는지 나타내는 오프셋 커밋정보인데, _consumer_offset 키(컨슈머 그룹명, 토픽명)밸류(오프셋 커밋 정보) 형태로 메세지가 저장된다
  1. 예를들어 CG01 컨슈머 그룹T01 토픽을 컨슘하고, 첫 번째 메세지를 읽고 커밋했다고 가정
  2. 이 정보는 밸류 형태 메세지로 _consumer_offset 토픽에 저장되어야 한다
  3. 따라서 키는 CG01(컨슈머 그룹), T01(토픽명) 이고 밸류는 1(오프셋)인 메세지가 _consumer_offset 토픽에 저장된다
  4. 약 한 시간 후 CG01 컨슈머 그룹이 T01 토픽을 컨슘하고 나서 두 번째 메세지를 읽고 커밋한다
  5. 그러면 키가 (CG01, T01) 이고 밸류는 2인 메세지가 _consumer_offset 토픽에 저장된다
  6. 또 한 시간이 지나 세 번째 메세지를 읽고 커밋하면, 키가 (CG01, T01)이고 밸류는 3인 메세지가 _consumer_offset 토픽에 저장된다
  7. 현재 _consumer_offset 토픽에 저장된 메세지는 총 3개이고, 키 (CG01, T01)을 기준으로 밸류가 1, 2, 3인 메세지입니다
  8. 이후 로그 컴팩션 동작이 일어나면 키값이 (CG01, T01)메세지의 마지막 데이터인 3만남게 된다
  9. 컨슈머 그룹은 항상 마지막으로 커밋된 오프셋 정보가 중요하므로, 과거에 커밋된 정보들은 삭제돼도 무방하다
  • 위와같이 로그 컴팩션은 메시지의 키값을 기준으로 과거 정보는 중요하지 않고 가장 마지막 값이 필요한 경우에 사용한다
  • 또 다른 예시로는, 현재 구매 현황 상태를 보여주는 시스템에서도 로그 컴팩션을 이용할 수 있다
    - 이때는 고유한 사용자 아이디가 메세지의 키값이고, 현재의 구매 상태 정보가 메세지의 밸류값이 된다
    • 구매한 사용자의 아이디(메세지 키)를 기준으로 최종 상태(메세지의 밸류)만 사용자에게 노출하면 되므로, 카프카의 로그 컴팩션 기능을 활용할 수 있다

프로듀서가 카프카로 메세지를 전송할 때, 메세지에는 메세지의 키와 밸류를 같이 전송하게 된다. 밸류는 필숫값이지만 키는 필숫값이 아니다. 따라서 로그 컴팩션 기능을 사용하고자 한다면, 카프카로 메세지를 전송할 때 키도 필숫값으로 전송해야 한다.

  • K1의 밸류 V1,V3,V4
    - 컴팩션 후 밸류 V4
  • K2의 밸류 V2,V6,V10
    - 컴팩션 후 밸류 V10
  • K3의 밸류 V5
    - 컴팩션 후 밸류 V5
  • K4의 밸류 V7
    - 컴팩션 후 밸류 V7
  • K5의 밸류 V8,V9
    - 컴팩션 후 밸류 V9
  • K6의 밸류 V11
    - 컴팩션 후 밸류 V11

컴팩션의 장/단점

  • 빠른 장애 복구
    - 장애복구시 전체 로그를 복구하지 않고, 키를 기준으로 최신의 상태만 복구한다
  • 빠른 재처리라는 장점이 있다고 해서 모든 토픽에 로그 컴팩션을 적용하는 것은 좋지 않다
  • 키 값을 기준으로 최종값만 필요한 워크로드에만 적용하는 것이 바람직하다
  • 로그 컴팩션 작업이 실행되는 동안 브로커의 과도한 입출력 부하가 발생할 수 있으니 유의해야 한다
  • 반드시 브로커의 리소스 모니터링도 병행하여 로그 컴팩션을 사용해야 한다

로그 컴팩션 관련 옵션

옵션옵션 값적용 범위설명
cleanup.policycompact토픽의 옵션으로 적용토픽 레벨에서 로그 컴팩션을 설정할 때 적용하는 옵션
log.cleanup.policycompact브로커의 설정 파일에 적용브로커 레벨에서 로그 컴팩션을 설정할 때 적용하는 옵션
log.cleaner.min.compaction.lag.ms0브로커의 설정 파일에 적용메세지가 기록된 후 컴팩션하기 전 경과되어야 할 최소 시간을 지정한다. 만약 이 옵션을 설정하지 않으면, 마지막 세그먼트를 제외하고 모든 세그먼트를 컴팩션할 수 있습니다
log.cleaner.max.compaction.lag.ms9223372036854775807브로커의 설정 파일에 적용메세지가 기록된 후 컴팩션하기 전 경과되어야 할 최대 시간을 지정한다
log.cleaner.min.cleanable.ratio0.5브로커의 설정 파일에 적용로그에서 압축이 되지 않은 부분을 더티라고 표현한다. 저체 로그 대비 더티의 비율이 50%가 넘으면 로그 컴팩션이 실행된다
profile
우렁총각

0개의 댓글