728x90

CH 05. 빅데이터의 파이프라인

5-1. 워크플로 관리

정기적인 데이터 관리를 자동화하여 안정된 배치처리를 실행하기 위해 워크플로 관리 도구를 도입한다.

 

워크플로 관리

- 데이터의 흐름을 일원 관리하기

 

기본적으로 데이터가 흐르는 프로세스를 워크플로 관리라고 하며 이를 자동화 하여 안정된 배치처리를 하는 것이 우선적으로 필요하다. 

다수의 업무 시스템에 내장되어 있어서 매일매일의 태스크를 관리한다. 

주요역할은 정기적으로 태스크를 실행하고, 비정상적인 상태를 감지하여 그것에 대한 해결을 돕는 것이다. 

위의 역할에 더하여 데이터 처리에 활용되는 워크플로과닐 도구는 오류 발생시에 자동으로 재실행할 수 있도록 해야하는 역할도 추가된다. 

워크플로 관리 도구에는 선언형와 스크립트 형 두가지가 존재한다.

선언형에서는 미리 제공된 기능만 이용할 수 있는데, 그 대신 그 범위 안이라면 최소한의 기술로 태스크를 정의할 수 있는 특징이 있다. 따라서 안정적이고 유지 보수성이 크다.(XML, YAML 등..)

다른 유형으로는 스크립트형이 있다. 유연성이 가장 큰 장점이다. (airflow 등..)

일반적으로 데이터 수집과정에서는 스크립트 형으로 처리를 많이 하며, 데이터 수집 이후에 정형적인 처리만을 하는 경우 선언형 도구를 사용하는 식으로 혼합하여 사용하는 경우가 많다. 

 

오류로부터 복구 방법 먼저 생각하기

 

워크플로에서 중요한 것은 오류 확인및 복구 그리고 이에 따른 플로우 재실행이다. 이에 대하여 자주 발생하는 오류에 대해서는 재실행 플로우를 자동화하여 설정해두는 것도 중요하다. 

오류가 발생한 당시에 복구하기 위해 많은 시간을 소요하면 그 시간만큼의 데이터가 유실되기 때문이다. 

일련의 태스크를 플로우라고 한다. 각 플로우에는 실행 시에 고정 파라미터가 부여된다. 일별 배치처리라면 특정 날짜가 파라미터가 된다. 동일 플로우에 동일 파라미터를 건네면 완전히 동일한 태스크가 실행된다. 플로우가 도중에 실패해도 나중에 동일 파라미터로 재실행이 가능하기 때문이다. 

대부분의 워크플로 관리 도구는 과거에 실행한 플로우와 그 파라미터를 자동으로 데이터 베이스에 기록하게 되어있다. 실패한 플로우를 선택하여 재 실행하는 것만으로도 복구가 완료된다. 

 

태스크를 재시도 할때는 횟수에 주의해야한다. 재시도가 너무 적으면 장애복구전에 재시도가 종료해서 태스크 실행에 실패한다. 너무 많으면 태스크가 실패하지 않은 것 처럼 보여서 중대한 문제가 발생해도 눈치채지 못한다. 

 

이때 플로우를 복구하기 위해서 정해진 플로우 전체를 다시 실행하는 기능이 있는데 이것이 백필이다. 

백필 실행시에는 작은 데이터라도 여러개가 실행되므로 성능상의 주의롤 요한다. 이 때에는 자동적인 재시도는 모두 무효로 하고 오류는 모두 통지하도록 한다. 

 

멱등한 조작으로 태스크를 기술하기

- 동일 태스트를 여러번 실행해도 동일한 결과가 괸다. 

 

복구의 전제로 기억해야 할 것은 재실행의 안전성이다. 즉 태스크 도중에 실패했을 경우, 데이터가 중간까지만 남아있고 일부는 전달되지 않는 경우는 허용되지 않으며, 원칙적으로 마지막까지 다 성공이거나 실패하면 아무것도 남지않음/ 이 둘 중 하나만 존재해야 한다. 

일반적으로 각 태스크는 데이터를 추가(새로운 데이터만)하거나 치환(기존 데이터는)하는 작업을 실시해야 한다. 

그러나 이 과정 또한 비효율 적이다. 추가 혹은 치환은 즉, 기존의 데이터를 모두 삭제하고 새로운 데이터로 쓰거나, 아니면 기존 데이터를 덮어쓰는 것인데, 이는 성능 저하를 불러오기 때문이다. 따라서 테이블 파티셔닝 방식을 통한 치환을 활용해야 한다, 

즉 테이블을 시간 단위로 파티션으로 분할하고, 파티션 단위로 치환하는 것이다.

 

즉 이번 챕터에서 파이프라인의 워크플로 관리에서 핵심은 데이터의 멱등성! 즉 중복 방지이다.

 

워크플로 전체를 멱등으로 하기

 

태스크 큐

- 자원의 소비량 컨트롤 하기

 

그 다음 중요한 것이 태스크 처리에 있어 부하 컨트롤을 잘하는 것이다. 태스크큐/잡큐를 통해 엄청나게 들어오는 태스크를 큐에 저장하고 워커 프로세스에 따라서 차례대로 꺼내서 병렬작업을 하는 것이 대표적이다. 

그러나 결국 태스크 수가 너무 많으면 오류가 발생할 가능성이 높다. 이 때 무조건 파일 하나당 태스크 하나를 할당하기 보다는, 처리해야할 파일 혹은 데이터의 용량을 파악한 후, 여러개를 묶어서 하나의 태스크로 처리하는 방법도 고려할 수 있다. 

즉 태스크가 너무 클경우에는 나누고, 작을 경우에는 합쳐서 조정한다. 

 

5-2. 배치형의 데이터 플로우

DAG를 사용한 배치 형의 분산 데이터 처리의 사고방식에 대해 설명한다.

 

맵리듀스의 시대는 끝났다.

- 데이터 플로우와 워크플로

 

맵리듀스는 기본적으로 분산 스토리지에 저장되어있는 데이터를 처리하고(Map), 이를 모아서 집계하는(Reduce) 작업이 반복되는 것이다. 분산스토리지에 저장된 데이터를 처리하기 위해, 기존에는 하둡과 함께 Mapreduce가 많이 회자 되었다. 그러나 맵리듀스는 하나의 사이클이 끝날때까지 다음으로 넘어가지 않아서 복잡한 데이터를 처리하는 경우, 사이클을 여러번 반복하므로 속도면에서 비효율적이다. 

 

맵리듀스를 대신할 새로운 프레임워크

- DAG에 의한 내부표현

 

이를 대체하기 위해서 DAG라는 데이터 구조가 등장했다. 이는 시스템 내부적인 표현으로 각 태스크가 하나의 노드로써 하나의 화살표로 이어져 있으며 각 노드가 동시 병행적으로 실행되어서 맵리듀스에서 겪던 비효율도 해결할 수 있다. 

DAG는 실질적으로 시스템의 내부적인 표현이다. 즉 데이터 구조일 뿐이다. 가령 Spark나 Hive on Tez, Presto 등도 DAG 데이터 구조를 채택하였다. 

DAG의 핵심은 지연 평가(lazy evaluation)이다. 프로그램의 각 행(노드)는 데이터 구조를 조립하고 있을 뿐 특별한 처리를 하고 있지 않다가 실행결과를 요구할 때 데이터 처리가 시작된다. 맵리듀스가 각각의 맵이나 리듀스 단계에서 노드들이 실행되고 처리되는 것과는 다르다.

 

데이터 플로우와 워크플로 조합하기

* 데이터 플로우 : 다단계의 데이터처리를 그대로 분산 시스템의 내부에서 실행할 수 있다.
태스크를 정기적으로 실행하거나 실패한 태스크를 기록하여 복구하는 것이 불가능. 이로 인해 워크플로 관리도구가 필요하다
* 워크플로우 관리 도구 : 각 종 태스크의 스케줄 실행, 오류로부터의 복구 및 장애 알람 등의 역할을 한다. 

일반적으로 데이터소스에서 데이터를 읽는 것과 같이 외부 데이터 소스에 접근할 때는 워크플로를 쓰는 것이 효율적이다. 이후 데이터 처리 가공 등은 분산 시스템 내에서 데이터 플로우로 진행하면 된다. 그리고 이 데이터를 외부에 저장하기 위해서 다시 워크플로를 활용한다. 

외부의 데이터 소스에서 데이터를 읽어 들일때는 벌크형의 전송 도구로 태스크를 구현한다. 이러한 과정에서 워크플로 관리 도구를 활용하여 태스크를 관리한다. 외부 데이터 소스로부터 읽어 들일 때는 어떤 오류가 발생할 지 예측할수 없기 때문이다. 

이렇게 분산 스토리지로 데이터 복사가 완료되면 데이터 플로우의 전문분야이다. 분산스토리지 내에서 데이터 가공과 열지향 스토리지의 변환 등의 부하가 큰 처리를 진행한다. 이러한 데이터 플로우를 스크립트화 해두면 데이터의 구조화 등의 프로세스를 단순 태스크로 워크플로에서 호출할 수 있다. 

따라서 분산 스토리지에서 외부로 데이터를 보내는 경우에도 워크플로 관리 도구를 활용한다. 

 

데이터 플로우와 SQL을 나누어 사용하기

- 데이터웨어하우스의 파이프라인과 데이터 마트의 파이프라인

 

SQL을 MPP데이터베이스에서 실행하는 경우는 데이터 웨어하우스의 파이프라인이며, 분산 시스템상의 쿼리엔진에서 실행하는 경우는 데이터 마트의 파이프라인이다. 즉 데이터웨어 하우스 내에 저장된 데이터에 대한 여러가지 처리를 위해 SQL를 사용하는 건지, 

구조화된 데이터를 바탕으로 데이터 마트를 만들기 위해 쿼리엔진을 사용하는지로 구분 가능하다. 

물론 애드혹 분석을 위한 대화식 플로우도 존재하나, 안정적이지 못하다. 

 

5-3. 스트리밍 형의 데이터 플로우

배치처리와 스트림 처리로 경로 나누기

 

파이프라인 내에서 데이터 처리에는 크게 배치처리와 스트림처리 두가지로 나뉘어진다.

배치처리의 경우,  데이터 분석을 하기 위한 과정에서 시간이 걸린다. 열지향 스토리지를 만들려고 하면 데이터를 모아서 변환하는데 일정 시간이 필요하다. 이벤트가 생성하고 바로 볼 필요가 없는, 그리고 데이터 양이 정해져 있는 유한 데이터를 전달한다. 또한 열지향 스토리지로 변환하는 가공 처리 등으로 프로세스 시간도 소요된다.

그러나 스트림 처리는 실시간성 데이터 처리로, 이벤트 생성 거의 직후에 바로 결과를 알고 싶은 경우에 사용한다.

보통 이러한 실시간성 데이터를 분산스토리지를 거치지 않고 바로 처리를 계속 하거나, 분산 스토리지로 보낸 후 배치처리와 동일하게 처리 과정을 거치느 ㄴ경우 두가지로 나눌 수 있다. 후자는 장기적인 데이터 분석에 용이하며 전자는 실시간 모니터링에 적합하다. 

 

배치처리는 대체로 과거부터 현재까지의 데이터츨 분석하고 집계하는 것에 적합하지만 실시간 집계에는 적합하지 않다. 그러나 스트림 처리는 실시간성이 우수하나 과거의 데이터를 취급하는 데에 부적합하다. 과거보단 말그래도 현재부터 미래에 쌓일 데이터들을 집계하기에 좋다.

 

배치처리와 스트림 처리 통합하기

 

배치처리는 실행 시에 데이터 양이 정해진 유한데이터를 다루고, 스트림 처리는 제한이 없이 데이터가 보내져 무한데이터를 다룬다고 볼 수 있다. 둘다 특성은 다르지만 데이터를 작게 분할해서 DAG에서 실행할 수 있다. 

대표적인 예로 spark의 프로그래밍 모델에서 원래 배치처리를 위한 분산 시스템이었는데, spark 스트리밍이 통합됨으로써 스트림처리까지 취급하게 되었다. 

 

스트림 처리의 결과를 배치처리로 치환하기

- 스트림 처리의 두가지문제에 대한 대처 

 

스트림처리의 경우 문제점이 있는데, 한번 전달된 데이터는 수정할 수 없고(시간을 되돌릴 수 없기 때문에)/ 늦게 전송된 데이터가 잇는 경우 본질적으로 스트림 처리의 장점을 부정확하게 만든다.

 

이를 해결하기 위한 대표적인 두가지 아키텍쳐로는 람다 아키텍쳐와 카파 아키텍쳐가 있다.

람다 아키텍쳐는 배치처리와 스트림 처리를 복합적으로 사용 하는 것인데, 같은 데이터 이더라도 배치처리에서는 장기적으로 보관하고, 스트림 처리는 실시간으로 처리하되 정해진 단시간의 데이터만 일시적으로 전달하고 보여진다. 최종적으로는 스트림처리된 데이터와 배치처리된 데이터를 조합하는 작업을 진행한다. 

즉 과거의 데이터는 배치처리로 치환되고, 스트림 처리는 일시적으로만 실시간뷰를 위해서 사용된다. 

이는 개발이 효율적이지 않다는 문제를 불러온다. 

다른 방식으로는 카파 아키텍쳐가 있는데, 스트림처리만 진행하되, 메시지 브로커의 데이터 보관 기간을 충분히 길게하는 것이다.  오류 발생 시에 메시지 배송 시간을 과거로 다시 설정하는 것이다. 그러나 이는 부하를 높이는 문제를 발생시킨다.

 

아웃오브 오더의 데이터 처리

 

스트림처리로 올바른 집계결과를 얻기 위해서 문제가 되는 것은 늦게 도달하는 메시지 즉 프로세스 시간과 이벤트 시간의 차이이다. 

스트림 처리는 기본적으로 프로세스 시간에 의한 실시간 데이터 처리다. 데이터가 도달한 순간에 집계를 시작한다. 

아웃오브 오더 즉 늦게 도착한 데이터는 이벤트 시간으로 원래 데이터의 성질을 알수있다. 

 

728x90

+ Recent posts