파생 데이터
11장: 스트림 처리
“복잡하지만 잘 작동하는 시스템은 예외 없이 간단하지만 잘 작동하는 시스템으로부터 발전한다.
이 명제는 역도 참이다. 처음부터 복잡하게 설계된 시스템은 절대 작동할 리도 없고 작동하게 만들지도 못한다.” 존갈, 체계론
일괄처리는 입력으로 파일 집합을 읽어 출력으로 새로운 파일 집합을 생성하는 기술 출력은 파생데이터 형태
일괄처리의 문제는 입력의 변화가 하루가 지나야 반영된다는것
이벤트가 발생할때 마다 처리하는것 - 스트림처리
이벤트 스트림 전송
스트림 처리에서 레코드 -> 이벤트
이벤트는 특정 시점에 일어난 사건에 대한 세부 사항을 포함하는 작고 독립된 불변 객체
이벤트는 일반적으로 일기준 시계를 따르는 이벤트 발생 타임스템프를 포함한다
일괄처리에서 파일은 한번 기록하면 여러 작업에서 읽을 수 있다 스트리밍에서도 비슷하다
폴링은 비용이 크다. 폴링이 잦을수록 새로운 이벤트를 반환하는 요청비율이 낮아지기 때문에 폴링을 수행하는 오버헤드가 커진다
- 메시징 시스템
- 발행,구독 모델
- 메시지 유실을 허용할지 말지는 애플리케이션에 따라서 틀리다
- 생산자에서 소비자로 메시지 직접 전달하기
- 생산자와 소비자가 항상 온라인이라고 가정한다
- 메시지 브로커(메시지 큐)
- 메시지 스트림을 처리하는 데 최적화된 데이터베이스의 일종
- 비동기식으로 작동
- 메시지 브로커와 데이터베이스의 비교
- 데이터 베이스는 명시적으로 데이터가 삭제될 때까지 데이터를 보관한다. 메시지 브로커는 소비자에게 메시지가 전달 되면 대부분 삭제한다
- 메시지 브로커는 대부분 메시지를 빨리 지우기 때문에 작업 집합이 상당히 작다고 가정한다
- 데이터 베이스는 보조색인을 지원하고 데이터 검색을 위한 다양한 방법을 지원하는 반면 메시지 브로커는 특정 패턴과 부합하는 토픽의 부분 집합을 구동하는 방식을 지원한다
- 데이터베이스에 질의 할때 그 결과는 질의 시점의 스냅숏을 기준으로 한다. 메시지 브로커는 데이터가 변하면 클라이언트에게 알려준다
- 복수 소비자
- 로드 밸런싱 : 메시지는 한 소비자에게 전달 된다
- 팬 아웃 : 메시지는 여러 소비자에게 전달 된다
- 확인 응답과 재전동
- 메시지 브로커는 확인 응답을 사용한다
- 메시지 순서는 메시지가 서로 독립적이라면 문제가 없지만 메시지간의 인과성이 있다면 매우 중요한 문제이다
- 파티셔닝된 로그
- 로그 기반의 메시지 브로커
- 로그를 사용한 메시지 저장소
- 로그는 단순히 디스크에 저장된 추가 전용 레코드의 연속이다
- 디스크 하나를 쓸때 처리량을 높이기 위해 확장하는 방법으로 로그를 파티셔닝 하는 방법이 있다
- 로그 방식과 전통적인 메시지 방식의 비교
- 메시지를 처리하는 비용이 비싸고 메시지 단위로 병렬화 처리하고 싶지만 메시지 순서는 구렇게 중요하지 않다면 JMS/AMQP 같은 메시징 시스템을 사용하는 것이 좋다
- 메시지 순서가 중요하고 메시지 처리량이 많으면 로그기반 접근법이 효과적이다
- 소비자 오프셋
- 메시지 오프셋은 로그 순차 번호와 상당히 유사
- 디스크 공간 사용
- 로그는 크기가 제한된 버퍼로 구현하고 버퍼가 가득 차면 오래된 메시지 순서대로 삭제한다
- 원형 버퍼 또는 링 버퍼라고 한다
- 소비자가 생산자를 따라갈 수 없을 때
- 메시지 버리기
- 버퍼링
- 배압 적용
- 오래된 메시지 재상
- 오프셋의 이동
- 일괄처리와 비슷
데이터베이스와 스트림
상태 기계 복제
- 시스템 동기화 유지하기
- 데이터 덤프는 너무 느려서 이중기록(dual write)의 방법도 있다
- 이중쓰기는 하나만 성공할수도 있다
- 데이터 덤프는 너무 느려서 이중기록(dual write)의 방법도 있다
- 변경 데이터 캡처
- CDC(Change Data Capture)는 데이터베이스의 변경 사항을 캡처하는 방법이다
- 변경 데이터 캡처의 구현
- 로그 기반의 CDC
- 트리거 기반의 CDC
- 스냅샷 기반의 CDC
- 초기 스냅숏
- 로그를 모두 플레이해서 재생하는것은 시간이 너무 오래 걸림
- 적당히 짤라서 처리해야함
- 로그 컴팩션
- log compaction
- 변경 스트림용 API 지원
- 이벤트 소싱
- 이벤트 소싱은 변경 데이터 캡처의 일종이다
- 데이터 모델링에 쓸수 있는 강력한 기법
- 이벤트 로그에서 현재 상태 파생하기
- 명령과 이벤트
- 명령은 시스템의 상태를 변경하는 요청
- 이벤트는 시스템에서 일어난 사건의 사실을 기록
- 상태와 스트림과 불변성
- 모든 변경로그(changelog)는 시간에 따라 변화하는 값
- 불변이벤트의 장점
- 문제 상황의 진단과 복구가 훨씬 쉽다
- 불변이벤트는 현재 상태보다 훨씬 많은 정보를 포함한다
- 동일한 이벤트 로그로 여러 가지 뷰 만들기
- CQRS(Command Query Responsibility Segregation)
- 동시성 제어
- 이벤트 소싱과 CDC의 단점은 비동기로 이루어진다는 것이다
- 불변성의 한계
- 데이터를 삭제하는것 - 이벤트를 추가해서 되는것이 아니다
- 데이토믹 : 적출(exicision)
- 포씰 : 셔닝(shunning)
- 데이터를 삭제하는것 - 이벤트를 추가해서 되는것이 아니다
스트림 처리
일괄처리랑 다른 점은 스트림은 끝나지 않는다
- 스트림 처리의 사용
- 사기 감사 시스템
- 거래 시스템
- 제조 시스템 공장 기계 상태 모니터링
- 군사 첩보 시스템
- 복잡한 이벤트 처리
- CEP(Complex Event Processing)
- 스트림 분석
- 구체화뷰 유지
- 스트림 상에서 검색하기
- 메시지 전달과 RPC
- 시간에 관한 추론
- 이벤트 시간 대 처리 시간
- 준비 여부 인식
- 낙오자 이벤트 처리 -> 무시, 수정 값 발행
- 어쨋든 어떤 시계를 사용할 것인가
- 시스템 시계
- 외부 시계
- 이벤트 시계
- 원도우 유형
- 덤블링 원도우(tumbling window) : 모든 이벤트는 정확히 한 원도우에 속한다
- 홉핑 원도우(hopping window) : 이벤트는 여러 원도우에 속할 수 있다
- 슬라이딩 원도우(sliding window) : 각 시간 간격 사이에서 발생한 모든 이벤트를 포함 한다
- 세션 윈도우(session window) : 고정된 기간이 없다
- 스트림 조인
- 스트림 스트림 조인(stream-stream join) - 원도우 조인
- 클릭 이벤트와 구매 이벤트를 조인 광고에서
- 스트림 테이블 조인(stream-table join) - 스트림 강화
- 데이터 베이스 정보로 이벤트 강화
- 테이블 테이블 조인(table-table join) - 구체화 뷰 유지
- 조인의 시간 의존성
- 천천히 변하는 차원(slowlly changing dimension)
- 조인의 시간 의존성
- 스트림 스트림 조인(stream-stream join) - 원도우 조인
- 내결함성
- 정확히 한 번 시맨틱
- 결과적으로 한 번 시맨틱
- 마이크로 일괄 처리와 체크포인트
- 원자적 커밋 재검토
- 멱등성
- 실패 후에 상태 재구축하기
정리
- amqp/jms 스타일 메시지 브로커
- 로그 기반 메시지 브로커
- 스트림 스트림 조인
- 스트림 테이블 조인
- 테이블 테이블 조인