programming/Flink

02. Flink 아키텍처

yhsim98 2023. 3. 8. 14:28

Flink DataStream

  • 데이터의 스트림을 나타낸다
  • 플링크에서 데이터를 처리하는데 사용하는 주요 추상화 개념
  • source
    • kafka, rabbit mq 등과 같은 외부 시스템의 데이터를 Flink Jobs로 수집합니다
  • sink
    • DataStream을 외부 시스템에 쓰는 역할을 한다
    • Kafka, Cassandra 등등
  • 데이터 스트림도, 배치도 가능
  • Flink의 철학
    • 배치는 데이터가 유한한 스트림이다
    • 초저지연을 목표로 하는 실시간 처리
    • 상태가 있는 스트림 처리
  • 스트림 데이터 처리에서 주의해야 할 점

Flink 시간 시멘틱

  • 데이터의 처리 시간은 데이터 발생 시간 뿐만 아니라 네트워크, 처리 속도 등 여러 요소가 영향을 미친다
    • 그래서 데이터 처리 시간이 아닌 데이터 자체의 실제 시간을 이용해야 한다

처리 시간

  • 스트림 처리 연산자가 실행 중인 장비의 시계에서 측정한 로컬 시간
  • 로컬 시간을 기준으로 일정 시간 동안 윈도우 연산자에 도달한 모든 이벤트는 처리 시간 윈도우 안으로 들어간다
  • 처리 시간 윈도우는 데이터의 실제 시간과 상관없이 계속 흘러간다
    • 네트워크 문제로 이벤트가 도달하지 못해도 계속 흘러감

이벤트 시간

  • 이벤트가 실제 발생한 시간
  • 이벤트 시간은 이벤트 내용 안에 포함된 타임스탬프를 기반으로 한다
  • 이벤트 시간 윈도우는 이벤트의 일부가 지연되더라도 발생했던 일을 제대로 반영한다
  • 이를 통해 이벤트 순서가 뒤바뀌더라도 결과의 정확성을 보장할 수 있다

워터마크

  • 이벤트 시간 윈도우에서 윈도우가 모든 이벤트가 도착했다는 것을 확신하기까지 얼마나 많은 시간을 기다려야 할까? 데이터가 지연되리라는 것을 어떻게 알 수 있을까?
  • 워터마크는 이벤트가 더 지연되지 않고 도착할 것이라고 확신할 수 있는 시점
    • 이벤트 전체 진행 시간
    • 스트리밍 시스템에 현재 이벤트 시간을 알려주는 논리적인 시계를 제공한다
  • 어떤 연산자가 T 값의 워터마크를 받았을 때 이 연산자는 T보다 늦은 시간의 이벤트를 더 받지 않는다고 가정할 수 있다
  • 연산자가 워터마크를 수신하면 일정 기간 발생한 모든 이벤트의 시간이 감지됐다는 것을 알 수 있고, 수신한 이벤트를 대상으로 계산을 시작하거나 이벤트를 정리한다
  • 워터마크를 짧게 혹은 길게 설정하는 방식에 따른 장단점이 있다
    • 짧게 하면 짧은 지연 낮은 신뢰
    • 길게 하면 긴 지연 높은 신뢰
  • 물론 스트림 시스템은 워터마크보다 늦게 도착한 이벤트를 처리할 수 있는 방법도 제공한다
    • 무시하거나 이전 결과를 보정하는 등

정리

  • 처리 시간은 짧은 지연을 제공하지만 결과는 처리 속도에 따라 다르다 → 비결정적
  • 이벤트 시간은 늦게 도착하거나 순서가 바뀐 이벤트도 처리할 수 있게 해준다 → 결정적
  • 각자 상황에 맞는 것을 사용하면 된다

상태 관리

  • 상태가 있는 연산자는 지속적으로 상태를 읽고 갱신한다
  • 상태 예로는
    • 윈도우로 수집된 레코드
    • 입력 소스의 읽기 위치
    • 머싱러닝 모델 등 사용자 정의나 애플리케이션에 특화된 상태
    • 등이 있다
  • Flink는 기본 연산이든 사용자 정의 연산자이건 모든 상태를 동일하게 취급한다
  • 태스크의 상태는 태스크의 연산 로직에서 바로 접근 가능한 로컬 변수나 인스턴스 변수로 생각할 수 있다
  • 애플리케이션은 상태를 신뢰성 있게 관리해야 한다
    • 메모리를 넘어사는 상태 처리
    • 장애 시 상태가 유실되지 않도록 저장
  • 플링크의 상태는 항상 특정 연산자와 연관돼 있다
    • 애플리케이션을 실행할 때 플링크가 연산자의 상태를 알 수 있게 하려면 연산자는 자신이 사용할 상태를 등록해야 한다
    • 상태의 종류에는 연산자 상태, 키 상태 두 종류가 있다
    • 또한 이러한 상태는 스코프에 따라 접근이 제한된다

연산자 상태

  • 연산자 상태의 스코프는 연산자 태스크 하나다
    • 한 태스크가 처리하는 모든 레코드가 동일 상태에 접근할 수 있다는 의미
  • 플링크는 세 종류의 기본 연산자 상태를 제공한다
    • 리스트 상태
      • 리스트의 요소들로 상태를 표현한다
    • 유니온 리스트 상태
      • 같은 리스트 상태지만 장애 복구나 애플리케이션을 세이브포인트에서 시작할 때 리스트 상태와 차이가 있다
    • 브로드캐스트 상태
      • 연산자의 모든 태스크 상태가 동일한 경우에 사용하는 연산자 상태

키 상태

  • 레코드의 각 키 값별로 유지하고 접근할 수 있는 상태
  • 플링크는 각 키 값별로 하나의 상태 인스턴스를 유지하고, 이 키 상태를 관리하는 연산자 태스크로 동일 키의 모든 레코드를 전송한다
    • 따라서 태스크는 현재 처리 중인 레코드의 키와 일치하는 키 상태만 접근할 수 있다
    • 동일 키를 가진 모든 레코드는 같은 상태에 접근한다
  • 키 상태의 기본 값 종류
    • 값 상태
      • 임의 타입의 값을 키별로 저장
      • 복잡한 데이터 구조도 값 상태로 저장할 수 있다
    • 리스트 상태
      • 각 키별로 값 리스트를 저장
    • 맵 상태
      • 키-밸류 맵을 저장

상태 백엔드

  • 연산자 태스크는 들어오는 레코드마다 상태를 읽고 저장하기 때문에 짧은 지연을 위해서는 효율적인 상태 접근이 매우 중요하다
  • 따라서 연산자 태스크는 상태를 로컬에 유지해 고속의 상태 접근을 보장한다
  • 상태의 정확한 저장, 접근 유지는 상태 백엔드라 불리는 플러그인 가능한 컴포넌트가 결정한다
    • 상태 백엔드는 로컬 상태 관리,
    • 원격 저장소에 상태를 체크포인팅
    • 이렇게 두 가지 책임을 지고 있다
  • 플링크는 분산 시스템이지만 상태 백엔드를 로컬에 관리하기 떄문에 상태 체크포인트가 중요하다
    • 태스크매니저는 언제든 장애가 발생할 수 있기 때문에 태스크의 상태를 영구적인 저장소에 체크포인팅하는 것이 중요
    • 상태 백엔드는 상태를 어떻게 체크포인팅하는지에 따라 다르다

상태가 있는 연산자의 수평 확장

체크포인트, 세이브포인트, 상태 복구

  • 플링크는 분산 데이터 처리 시스템이기 때문에 장비 고장, 네트워크 등 여러 장애를 해결할 수 있어야 한다
  • 또한 태스크는 로컬에 상태를 유지하기 때문에 플링크는 장애 시에도 이 상태가 유실되거나 일관성을 잃지 않게 보장해야 한다

일관성 체크포인트

  • 플링크의 복구 방식은 애플리케이션 상태의 일관성 체크포인트에 기반을 두고 있다
  • 일관성 체크포인트란 모든 태스크가 정확히 동일한 시점에 각 태스크의 상태를 복사하는 것
  • 예시
    • 입력을 받는 소스 태스크와 연산 태스크가 있다
    • 소스 태스크는 현재 입력 스트림의 오프셋을 상태로 저장한다
    • 연산 태스크는 현재 연산 값을 상태로 저장한다
    • 이런 상태들을 원격 저장소에 저장하는 체크포인팅 한다

일관성 체크포인트에서 복구

  • 플링크는 주기적으로 일관성 체크포인팅을 수행해 상태를 원격 저장소에 저장한다
  • 장애가 발생하면 가장 최신 체크포이트를 사용해 일관성 있게 애플리케이션 상태를 복구하고 레코드 처리를 재시작한다
  • 애플리케이션은 다음 세 단계로 복구한다
    • 전체 애플리케이션 시작
    • 상태가 있는 모든 태스크 상태를 가장 최신의 체크포인트로 설정
    • 모든 태스크 처리 재시작
  • 모든 연산자가 체크포인팅을 수행하고 모든 상태를 복구한 후 모든 입력 스트림의 위치가 체크포인트 수행 당시 마지막으로 소비했던 위치로 재설정된다면 이 체크포인트와 복구 방식으로 애플리케이션 상태의 정확히 한 번 일관성을 제공할 수 있다
  • 데이터 소스의 입력 스트림 재설정 여부는 카프카 같은 데이터 소스의 구현과 외부 시스템에 달려있다
  • 플링크는 일부 저장 시스템에 대해 체크포인팅 시점에 레코드를 모두 저장하는 방식으로 정확히 한 번 출력이 가능한 싱크 함수를 제공한다

윈도우 연산

  • 스트림 조인이나 평균 함수와 같은 집계 연산은 일정량의 이벤트를 모아 보관하고 있어야 한다
    • 무한 스트림에서 각 연산은 자신의 상태에 보관 가능한 수준으로 데이터양을 제한할 필요가 있다
  • 윈도우 연산은 무한 이벤트 스트림에서 버킷이라 불리는 이벤트의 유한 집합을 지속적으로 생성하고, 이 유한 집합에서 어떤 연산을 수행할 수 있게 해준다
    • 윈도우 연산은 데이터의 속성이나 시간을 기준으로 버킷에 이벤트를 할당한다
  • 윈도우를 사용할 때는 윈도우 정책을 정의해야 한다
    • 얼마나 많은 이벤트를 버킷에 넣고
    • 윈도우가 얼마나 자주 결과를 만들어낼 것인지 등

윈도우 종류

  • 텀블링 윈도우
    • 고정 길이의 겹치지 않는 윈도우
    • 개수나 시간 기반
  • 슬라이딩 윈도우
    • 겹치는 고정 길이 윈도우
    • 길이는 윈도우 크기, 슬라이드는 새로운 버킷이 생성될 때까지의 간격
  • 세션 윈도우
    • 인접 시간 동안 발생한 연속 이벤트(세션)로 구성
    • 세션 갭이라는 기간동안 비활동인 경우 세션을 그룹화
  • 병렬 윈도우
    • 스트림을 식별자로 그룹핑해서 윈도우 계산을 적용하고 싶을 수 있다
      • 키가 같은 이벤트가 모인 크기가 2인 윈도우 등
      • 이럴 때 병렬 윈도우를 사용한다
    • 병렬 윈도우의 각 파티션별로 다른 윈도우 정책을 적용할 수 있다