본문 바로가기

Studying/Data System Design

스트림 처리 [데이터 중심 애플리케이션 설계 11장]

  1. 이벤트 스트림 전송: 생산자가 이벤트를 만들면 소비자가 처리한다. 토픽이나 스트림으로 관련 이벤트를 묶는다.
    1. 메시징 시스템: 생산자와 소비자 사이에 직접 통신 채널을 사용하는 방식을 기본으로 확장된다.
      1. 생산자에서 소비자로 메시지를 직접 전달: 설계 상황에서는 잘 작동하지만, 메시지 유실 가능성을 고려해서 애플리케이션 코드를 작성해야 한다. 오프라인 상태에 취약하다
      2. 메시지 브로커: 직접 방식의 대안으로 중간에 메시지 브로커를 통해 메시지를 보내는 방식이다. 메시지 브로커는 일종의 데이터베이스다. 브로커에 메시지가 모이기 때문에 클라이언트의 상태에 쉽게 대처가 가능하다. 비동기로 작동한다.
    2. 복수 소비자: 여러 소비자가 같은 토픽에서 메시지를 읽는 패턴
      1. 로드 밸런싱: 소비자 중 하나로 전달되고 소비자들끼리 메시지 처리를 공유한다. 병렬 처리에 유용하다.
      2. 팬 아웃: 메시지가 모든 소비자에게 전달된다. 같은 파일을 읽는 일괄 처리와 동일한 방식이다.
    3. 확인 응답과 재전송
      1. 소비자는 언제든지 장애가 발생할 수 있으므로 브로커는 메시지를 잃어버리지 않기 위해 클라이언트로부터 처리 여부를 확인 받고 메시지를 삭제한다.
      2. 재전송을 하다 보면 순서에 영향을 미친다.
    4. 로그를 사용한 메시지 저장소: 메시지를 로그 끝에 추가하고 생산자가 오프셋을 통해 오프셋 이후의 데이터를 읽는 방식 → 데이터베이스처럼 지속성 있는 저장 가능
    5. 디스크 공간 사용: 소비자 처리 속도가 느려서 생산되는 속도를 따라잡지 못 하면 메시지 일부를 잃을 수 있다. 이 때, 디스크 공간을 사용하면 시간을 늘릴 수 있다.
  2. 데이터베이스와 스트림
    1. 변경 데이터 캡처(Change data capture, CDC): 모든 데이터의 변화를 관찰해 다른 시스템으로 데이터를 복제할 수 있는 형태로 추출하는 과정
      1. 초기 스냅숏: 모든 걸 CDC로 하면 디스크 공간과 재생하는 작업하는 비용이 크다. 그래서 전체 데이터베이스 복사본이 필요한다.
      2. 로그 컴팩션: 기본키를 포함하여 해당 키의 최신 쓰기만 유지한다.
    2. 이벤트 소싱
      1. CDC와 다르게 갱신이나 삭제는 권장하지 않거나 금지한다. 애플리케이션 수준에서 동작한다.
      2. 결과만 저장하는 게 아니고 수정 히스토리도 저장하는 방식
      3. 로그 컴팩션이 불가능할 수 있다.
      4. 현재 상태보다 더 많은 정보를 포함하고 있다.
    3. 불변성의 한계: 성능이나 보안 등의 이유로 데이터 갱신과 삭제가 필요할 수도 있는데, 이 때 복제본 등의 이유로 달성하는 게 어렵다.
  3. 스트림 처리
    1. 모니터링 용도로 많이 사용됐다.
    2. 복잡한 이벤트 처리(Complex event processing, CEP): 특정 이벤트 패턴을 검색하는 데 사용한다. 데이터베이스와는 반대로 질의를 오랜 기간 저장하고, 입력 스트림으로부터 들어오는 이벤트를 지속적으로 질의하여 패턴을 찾는다.
    3. 스트림 분석: CEP와의 경계가 불분명하지만, 통계적 지표를 뽑는 것에 더 우선한다. 집계 시간 간격을 윈도우라고 한다.
  4. 시간에 관한 추론: 이벤트 생성 시간보다 이벤트 처리 시간이 늦어지면 문제가 발생한다.
    1. 3가지 타임스탬프: 이벤트가 발생한 시간, 이벤트를 서버로 보낸 시간, 서버에서 이벤트를 받은 시간을 기록한다.
  5. 윈도우
    1. 텀블링 윈도우: 크기가 고정으로 00초~59초 식으로 구현한다.
    2. 홉핑 윈도우: 고정 길이를 사용하나, 1분 크기의 홉을 사용하여 5분 윈도우를 만드는 형식으로 윈도우 끼리 겹치는 부분이 생긴다.
    3. 슬라이딩 윈도우: 시간 간격 사이의 모든 이벤트를 포함한다. 5분 슬라이딩 윈도우면 두 시간의 간격이 5분 이내에만 있다면 같은 윈도우에 있다. 새로운 이벤트가 생성되면 과거 이벤트를 제거하는 방식으로 구현한다.
    4. 세션 윈도우: 고정된 기간이 없고, 같은 사용자가 짧은 시간 동안 발생시킨 모든 이벤트를 그룹화하는 방식
  6. 스트림 조인
    1. 스트림 스트림 조인(윈도우 조인): 스트림끼리 지연이 발생할 수 있어 적절한 윈도우 선택이 필요하다. 스트림 처리가 상태를 유지해야 한다. 이전에 같은 세션으로 도착한 다른 이벤트가 있는 지 확인 필요
      1. 검색과 클릭 이벤트를 조인할 때, 단순히 클릭 이벤트에 검색에 대한 내용을 추가하는 것과 동일하지 않다. 클릭하지 않은 검색에 대한 내용이 없기 때문에
    2. 스트림 테이블 조인(스트림 강화): 특정 이벤트에 대한 정보를 추가하는 방식이다. 원격으로 데이터 베이스를 질의하게 할 수 있으나 속도가 느리다. 그래서 로컬에 테이터베이스의 사본을 적재하는 방식으로 구현할 수 있다. (데이터베이스의 크기가 작다면), 스트림 처리는 오랜 기간 수행하기 때문에 데이터베이스의 내용이 변할 수 있어서 데이터 베이스의 변경 로그를 구독하게 할 수 있다.
    3. 테이블 테이블 조인(구체화 뷰 유지): 이벤트를 구체화 뷰로 만들고 조인하는 방식
  7. 내결함성: 일괄 처리와 달리 결함이 생겼을 때 직관적인 해결책이 없다. (무한히 기다릴 수 없으므로)
    1. 마이크로 일괄 처리와 체크 포인트: 스트림을 작은 블록으로 나누고 각 블록을 일괄 처리하는 방식, 약 1초 정도 성능에 타협한다. 체크 포인트를 사용해서 장애 발생 시, 체크 포인트부터 재시작하는 방식도 있다.
    2. 원자적 커밋 재검토: 처리가 성공했을 때만 모든 출력과 부수효과가 발생하도록 해야 한다.
    3. 멱등성: 멱등 연산은 아니더라도 오프셋을 함께 전송한다면 처리 여부를 확인할 수 있어 멱등적으로 만들 수 있다.
    4. 실패 후에 상태 재구축하기
      1. 원격 데이터 저장소에 상태를 유지하고 복제하거나 로컬에 복제하기
      2. 입력 스트림을 사용해 재구축할 수도 있다.