home

1. 카프카 기본 개념 설명

  • 커밋: 컨슈머가 파티션에 어디까지 데이터를 가져갔냐를 알 수 있다.
  • 프로듀서는 메시지를 모든 파티션에 넣는게 아니라, 하나의 파티션에 넣는다.

빅데이터 파이프라인에 적합한 카프카 특징

높은 처리량

  • 카프카 배치로 네트워크 비용 줄임
  • 파티션 개수 만큼 컨슈머 개수를 늘려서 병렬처리 가능. 즉, 스케일 아웃 가능

확장성

  • 한 개의 클러스터는 여러 개의 브로커로 이루어짐
  • 데이터 량이 많아질 때, 브로커를 늘려서 처리 가능
  • 프로듀서에서 예측하기 어렵더라도 브로커를 늘려서 활용 가능

영속성

  • 카프카는 파일 시스템에 메시지를 저장한다.
  • 페이지 캐시 메모리 영역을 사용해서 한번 읽은 건 메모리에 저장한다.
  • 장애가 발생하면 복구 가능

고가용성

  • 3개 이상의 서버들로 카프카 클러스터로 운행된다.
  • 전송된 데이터들을 하나에 저장하면 클러스터 내에 복제되어 저장된다.

데이터 레이크 아키텍처

  • 원천 데이터 → 파생 데이터 → 서빙 데이터
    • 히스토리 파악 어려움, 파편화, 유연하지 않음

람다 아키텍처

  • 배치 레이어, 배치 데이터를 얻음
  • 스피드 레이어, 서비스에서 생성되는 원천 데이터를 실시간으로 빠르게 분석, 여기에 카프카
  • 이 두개의 레이어를 서빙 레이어로 만든다
  • 한계: 레이어가 두가지로 나눠져있어서 단점이 생김, 두 개를 융합하기에 어려움

카파 아키텍처

  • 모든 배치 데이터를 스피드 레이어에서 해결함
  • 배치 데이터를 스트림으로 표기 할 수 있고, 이를 위해서는 로그에 timestamp가 필요하다

  • 그것을 뷰형식으로 가져와서 배치 데이터로 사용한다

카프카 생태계

  • 토픽에 저장된 데이터를 stateless, stateful하게 처리해서 다시 토픽에 넣을 때는 카프카 스트림즈를 쓴다
  • 커넥트
    • 소스 커넥트: 프로듀서
    • 싱크 커넥트: 컨슈머
  • 미러메이커: 카프카에 있는 데이터를 복제하기 위해서 필요한 것

카프카 클러스터와 브로커

  • 주키퍼: 클러스트를 위한 애플리케이션
  • 하나의 브로커는 하나의 컴퓨터, 인스턴스이다.
    • 상용에서는 세 개의 브로커로 운영한다
  • 하나의 주키퍼 앙상블로 여러 개의 클러스터를 운영

브로커의 역할

  • 컨트롤러: 다른 브로커의 상태를 체크한다.
  • 데이터 삭제: 토픽의 데이터를 지운다. ‘로그 세그먼트’ 단위로 데이터를 삭제한다. RDB처럼 특정 로우만 삭제하지 못한다.
  • 컨슈머 오프셋 저장: 특정 컨슈머가 어디까지 처리했는지의 나타내는 commit을 __consumer_offsets 토픽에 저장한다.
  • 그룹 코디네이터: 컨슈머 그룹의 상태를 체크하고, 파티션을 컨슈머와 매칭되도록 분배, 문제가 있는 컨슈머를 삭제하고 파티션을 재할당 하는 것을 ‘리밸런스’ 라고 한다.

  • 데이터의 저장: config/server.properties의 log.dir에 옵션에 정의한 디렉토리에 데이터를 저장
  • log에는 메시지와 메타데이터, index는 메시지의 오프셋을 인덱싱한 정보, timeindex는 timestamp 값을 기준으로 인덱싱한 정보

  • log.segment.bytes: 최대 세그먼트 크기를 지정한다. 꽉차면 다음 세그먼트로 넘어감. 기본은 1GB
  • log.roll.ms: 세그먼트가 생성된 이후에 다음 파일로 넘어가는 시간 주기
  • 액티브 세그먼트는 브로커가 삭제하지 않는다
  • 나머지 세그먼트는 retention 옵션에 따라서 삭제가 된다.
    • retention.ms: 세그먼트 보유할 최대 기간, 일반적으로 3일로 지정한다
    • retention.bytes: 파티션당 로그 적재 바이트 값
    • log.retention.check.interval.ms: 세그먼트가 삭제 영역에 들어왔는지 확인하는 간격, 기본 값은 5분
  • cleanup.policy = compact
    • delete는 세그먼트를 단위로 삭제한다
    • compact는 가장 최근의 메시지 키만 남긴다.
    • 테일 영역: 중복된 메시지 키를 삭제한 후 영역, 여기에 있는 것들이 클린 로그
    • 헤드 영역: 압축 정책이 되기 전 레코드, 더티 로그
    • min.cleanable.dirty.ratio: 두 영역의 비율에 따라서 압축을 자동으로 수행한다.

복제

  • 카프카의 장애 허용 시스템으로 동작하는 원동력
  • 레플리케이션 factor를 지정한 개수만큼 복제된다. 최대 값은 브로커의 개수 만큼 설정
  • 리더 파티션에 적재되고, 나머지 브로커는 따라간다
  • 팔로워 파티션은 리더 파티션의 offset을 확인하고 복제한다
  • 파티션 복제를 하면 용량은 증가하지만 데이터를 안전하게 사용하기 때문에, 2 이상의 복제 개수를 정하는 것이 중요하다
  • 프로듀서는 리더 파티션과의 네트워크 통신을 하게 된다. 팔로우 파티션과 통신을 하는 것이 아니다. 그래서 특정 파티션은 리더 파티션이 존재해야 한다.
  • 일부 토픽은 1로 할 수 있고(네비의 gps 정보 같은), 2~3으로 한다. 보통 토픽마다 다르다.

ISR(In Sync Replicas)

  • 리더 파티션과 팔로워 파티션이 모두 싱크가 된 상태
  • unclean.leader.election.enable=True: 유실을 감수, 싱크가 안된 파티션을 리더로 승급 → 서비스 기업
  • unclean.leader.election.enable=False: 브로커가 복구될 때 까지 중단 → 금융 기관

토픽과 파티션

  • 토픽은 한 개 이상의 파티션을 가지고 있다.
  • 레코드를 파티션 큐에 넣는다

  • 파티션은 라운드 로빈으로 리더 파티션으로 만들어진다.
  • 특정 브로커에 파티션이 몰리면 kafka-reassign-partitions.sh 명령으로 파티션을 재 분배 할 수 있다.
  • 파티션은 최대 한 개의 컨슈머를 연결, 즉, 컨슈머 개수를 늘림과 동시에 파티션도 늘리면 처리량 증가
  • 그러나 파티션 개수를 줄이지는 못한다. 파티션 늘리는데 신중해야함

레코드

  • 타임스탬프, 헤더, 메시지키, 메시지 값, 오프셋
  • 프로듀서 → 브로커에 저장될 때 오프셋이 생기고, 옵션에 따라 타임스탬프가 지정된다.
  • 타임스탬프: 스트림 프로세싱에서 활용하기 위한 시간을 저장
  • 오프셋: 브로커에 적재될 때 지정된다. 0부터 시작하고 1씩 증가
  • 헤더: key/value 데이터를 저장 가능, 데이터 처리할 때 참고할 만한 용도의 정보가 담겨있음
  • 메시지 키: 데이터 분류를 위해서 사용, 파티셔닝이라고 부른다. 파티셔너에 따라서 파티션 번혹 정해진다. 기본은 null이고 이 때는 라운드 로빈으로 들어간다. null이 아닌 메시지는 해쉬값에 의해서 특정 파티션에 매핑된다.
  • 메시지 값: 다양한 형태로 지정 가능, 실질적으로 처리할 데이터로 담기는 공간. 컨슈머에서는 미리 역직렬화 포맷을 알고 있어야 한다. 일반적으로는 string으로 한다. json 으로 ㅇㅇ

토픽 이름

  • 빈 문자열 토픽 이름은 지원 X
  • 영어 대소문자, 0 ~ 9, __, - 조합
  • 토픽 이름에 마침표와 언더바가 동시에 들어가면 안된다.
  • 토픽 = 데이터의 얼굴, 유지 보수에 중요하다
  • 토픽 이름 변경을 지원하지 않는다.
  • 끝에 데이터 타입을 넣어주는게 좋은데 직렬화 → 역직렬화 하여 컨슈머가 처리할 때 유용하다

클라이언트 메타데이터

  • 클라이언트(프로듀서, 컨슈머)는 리더 파티션 등의 메타데이터를 요청하고 카프카 클러스터에 응답을 받는다.
  • 만약 리더 파티션이 아닌 잘못된 파티션으로 요청이 되면(LEADER_NOT_AVALIABLE) 거의 리프레시 이슈임. 이럴 때는 메타데이터 리프레시 간격을 확인한다.

카프카 클러스터를 운영하는 방법

  • 기업용 카프카는 유료이다. 여러 부분에서 튜닝이 되어있음.
    • ex) 커넥터, 모니터링 툴 같은 것을 제공한다.
  • 많은 기업에서는 IaaS를 더 많이 사용한다
  • 오픈 소스 카프카는 고성능 하드웨어가 필요하다