728x90

개발자로서 데이터 분야로 커리어를 쌓고 공부를 하면서 느낀 점은, 데이터분야에 대한 직무가 핫해지면서 다양한 툴들과 개념들에 대한 공부가 핫해지고 있으나 실질적으로 데이터에 대해 더 기본적이고 핵심적인 엔지니어링 분야에 대한 자료는 여기저기 흩어져있다는 것이다.

따라서 로그데이터나 데이터파이프라인 등에 대해 정리해둔 책이나 블로그 글들을 번역 및 정리하며 공부를 하려한다.

The Log: What every software engineer should know about real-time data's unifying abstraction(링크)

로그가 무엇인지, 그리고 이를 통해 실시간 데이터를 어떻게 통합하고 처리할 수 있는 지에 대해 링크드인에서 정리한 블로그글을 공부하며 요약해보려 한다.

 

what is a Log?

시간순으로 각 레코드들이 정렬된다. 로그는 레코드가 시간별로 정렬된 일종의 테이블 혹은 파일이다.

→ 여기서 시간은 물리적인 "시계"의 개념과는 다르다. 즉, 저장될 당시의 일과 시기를 기록하는 것이며 이 것이 로그의 특정한 목적이고 분산 데이터 시스템에서 핵심이 된다.

로그에도 여러 종류가 있는데, 우리에게 익숙한 로그는 syslog (응용 프로그램이 작동하면서 남기는 디버깅 메시지!)이며, "application log"라고 한다. 이 로그와 여기서 언급하는 로그는 다르다. 데이터 사이언스에서 주로 수집되고 분석하는 로그는 "data log"라고 한다.

 

syslog든, datalog든 log라는 큰 개념의 일부. 여러 종류 중 하나이다. 실제로 log analysis라는 분야가 있을 정도로 데이터 로그는 빅데이터에서 중요한 역할을 하고 있다.

데이터베이스에서의 로그

  • 트랜잭션 로그라고도 한다. → 트랜잭션 로그 관리
  • 핵심은 데이터를 일관된 상태로 관리하기 위함. 즉 데이터의 흐름에 대한 기록?!
  • 데이터베이스에서 별도의 파일 또는 파일 집합으로 구현.
  • 유지관리하는 모든 데이터에 변경 사항을 적용하기 전에, 변경할 레코드에 대한 정보를 기록하기 위해 로그를 사용 → 따라서, 데이터 변경 시, 충돌이 발생할 경우, 복원이 필요할 때 로그가 바로 중요한 역할을 하게 된다.
  • 시간이 지날수록, ACID(데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하는 것, 원자성, 일관성, 고립성, 지속성의 약자)를 더 세부적으로 구현함으로써 로그의 사용이 발전해갔다. → 데이터베이스 간에 데이터를 복제하면서 일련의 변화들와 그 결과들이 일치하기 위해서 로그가 중요한 역할을 한 것이다.
  • 변경 로그가 있는 경우 이러한 변경 사항을 적용하여 현재 상태를 캡처하는 테이블을 생성할 수 있습니다. 이 테이블은 각 키의 최신 상태를 기록합니다(특정 로그 시간 기준). 로그가 보다 기본적인 데이터 구조라는 의미가 있습니다.

분산 데이터 시스템에서의 로그

데이터 변경 순서를 정하거나 데이터 분산을 위해 로그는 분산 시스템에서 중요.

  • 분산 시스템에서 로그는 여러 서비스들이 같은 process input을 받는다면, 결과도 같을 수 있도록 함. → 로그가 각 분산 시스템에서 타임스탬프의 역할을 한다.
    Deterministic algorithm (결정론적 알고리즘) : 예측한 그대로 동작. 어떤 특정한 입력이 들어오면 언제나 똑같은 과정을 거쳐서 똑같은 결과를 내놓는다. VS algorithms non-deterministic(비결정론적 알고리즘) : 결과를 예측할 수 없는 알고리즘
  • 분산시스템에서 서비스 1과 3에서 동시에 reqest를 받았고 다른 서비스에 전달하여 일을 처리한다고 가정했을때 서비스 2에서는 log의 순서를 보장 할 수 없으며, 로그의 주인의 파악하기 힘들다. 이때 로그가 타임스탬프로서 인덱싱역할을 하는 것이다.
  • 기본적으로 두가지 접근 방식 존재

 

즉, 데이터 로그는 분산 데이터 시스템이 발전하고, 그 시스템이 점점 커지면서 일종의 서비스의 데이터 사용의 일관성을 보장하기 위해 필요하다고 볼 수 있는 것 같다.

이에 따라 분산 시스템에서 로깅과 로그데이터들에 대한 추적 필요 (이를 위해 대표적으로 Zipkin 사용)

→ Zipkin은 트위터에서 사용하는 분산환경추적 시스템 오픈소스이다.

실제로 빅데이터 시대가 다가오면서 통합로그관리를 위한 다양한 시스템을 필요로 하고 있으며 관련 기술에 대한 툴이나 솔루션 서비스들이 사용되고 있음. 관련 기사

 

Usefulness of Logs

1. Data Integration(데이터 통합)

  • 모든 서비스와 시스템에서 조직의 모든 데이터가 사용될 수 있도록 하는 것이 데이터 통합.
    → ETL (데이터 통합에 포함된 개념. 데이터를 추출하고 변형하고 적재한다.) 즉 저장된 데이터를 추출한 후, 요구사항에 맞게 변형하여 다른 곳에서 사용할 수 있도록 전달하는 것.
  • 실제로 데이터 양이 많아지면, 모든 데이터 시스템에서 문제없이 데이터를 잘 전달할 수 있는 안정적인 데이터 흐름을 구축할 수 있느냐에 대한 의문 발생?
  • 데이터 통합을 복잡하게 하는 요인
    -> 이벤트 데이터 : 기존 데이터 베이스 사용보다 수십배는 더 크다.
    -> 특수 데이터 시스템 : 검색, 일괄 처리 등 → 즉 더 많은 데이터가 등장하고, 이를 시스템으로 가지고 오려 함으로 인해, 기존과는 다른 데이터 통합 문제가 발생.

그렇다면 로그가 어떻게 이러한 상황에서 유용할 수 있다는 걸까?

위에서 언급한 대로 로그는 = 타임스탬프를 기준으로 인덱싱
⇒ 모든 데이터 소스들이 로그파일에 정리되고, 그 다음에 데이터 시스템이 이 로그파일을 읽고 측정함으로써, 데이터 양의 급격한 증가에도 손실없이 데이터 소스를 전달할 수 있다.

각 시스템이 "읽었을" 당시의 "시점"이 남아있기 때문에 서로 다른 데이터소스를 읽어서 다른 상태이더라도 그에 대한 추론이 가능하다.

링크드인의 사례

→ 중앙 집중식 관계형 데이터베이스에서 분산시스템 모음으로 이동하면서 데이터 통합 문제가 중요해짐. 기존의 Oracle 데이터 웨어하우스(데이터 웨어하우스는 분석을 지원하도록 구성된 깨끗하고 통합된 데이터의 저장소) 에서 데이터를 긁어모은 뒤, hadoop으로 전송하여 분석하고자함. 이 과정에서 단순하게 생각했던 데이터 복사/전달에서 문제점을 겪음 ( 느린속도/ 기존 웨어하우스와 hadoop에서 계획한 배치처리프로스세가 맞지 않음 )

Worse, any time there was a problem in any of the pipelines, the Hadoop system was largely useless—running fancy algorithms on bad data just produces more bad data.

여기서 hadoop이란 쉽게 말해서, 빅데이터 처리와 분석 플랫폼이다!

실제로 hadoop을 포함한 다양한 데이터 시스템에서 아래와 같이 양방향으로 데이터파이프라인이 생성

같은 데이터이지만 각 시스템과 파이프라인에 따라서 차이가 발생해 버림/ 하나의 단일 데이터 저장소 필요

잘 정의된 API와 함께 중앙 파이프라인인 로그를 사용하는 것. 분산된 데이터 시스템을 사용하면서 데이터 시스템을 하나씩 추가할 때 중요.

이처럼 정확한 데이터 활용 및 분석을 위해서는 모든 시스템에 동일하고 정확한 데이터 전달이 필요. 즉 "데이터 통합"이 중요. 전달하는 파이프라인 구축과 함께 단일 데이터 저장소가 필요했고 로그가 그 역할.

 

이를 위해 실제로 링크드인에서 개발한 kafka(분산 스트리밍 플랫폼)가 대표적이다.

(Line에서 kafka를 사용하는 방법 , 링크드인은 왜 kafka를 만들었는가?)

→ kafka의 특징

1. 메시징 모델/ 스케일 아웃형 아키텍처 2. 데이터 영속화 3. 이해하기 쉬운 API 제공 4. 정확한 데이터 전달

→ Line에서의 kafka 역할

1. 분산 큐잉 시스템으로 사용.  예를 들어, 어떤 서비스의 웹 애플리케이션 서버에서 처리하는 데 자원을 많이 사용해야 하는 업무가 발생했을 때, 이를 내부에서 처리하지 않고 다른 프로세스에서 작동 중인 백그라운드의 태스크 프로세서에 요청하기 위한 큐로 사용하는 경우를 들 수 있습니다.

2. 데이터 허브로 사용. 예를 들어LINE에서는 사용자의 친구 관계를 데이터로 저장하고 있습니다. 예를 들어 어떤 사용자 A가 다른 사용자 B를 친구로 추가했을 때, LINE 내부에서는 그에 따른 처리를 수행하고 업데이트된 관계를 Kafka의 topic에 이벤트로 입력. 이 이벤트는 관련된 다양한 서비스에서 사용됨.

로그가 지닌 데이터 통합이라는 역할은 실제로 데이터를 한 곳에서 다른 곳으로 복사해야 할 때, 즉 이동해야 할 때 필요한 기능이다.

 

2. 실시간 데이터 처리

  • log는 stream의 또 다른 단어이며, 로그는 스트림처리의 핵심이다.

스트림 처리란?

일반적으로 스트림처리르를 실시간 데이터 처리라고 생각한다. 그러나 이는 좁은 개념의 스트림이다.

더 넓은 개념으로 본다면 스트림처리는 지속적인 데이터 처리를 위해 필요한 인프라이다.

스트림 처리에 대한 개념은 추상적이며, 빅데이터기술에서 엄청난 양의 데이터를 처리하기 위한 기술/구조적인 기술인 것이다.

신규 데이터를 끊임없이 처리해 결과를 만들어내는 행위이다. "Hadoop과 같은 기술이지만 더 빠른 결과를 제공 할 수있는 기술"로 대중화.

 

해당 블로그 글을 참고하면, 스트림 처리는 RDS 데이터 베이스를 기반으로 하는 데이터 배치처리의 단점을 보완한 데이터 처리 방식이다.

⇒ 많은 데이터 전송 프로세스는 여전히 주기적인 덤프와 대량 전송 및 통합에 의존한다.

대량 덤프를 처리하는 유일한 자연스러운 방법은 일괄 처리를 사용하는 것.

그러나 이러한 프로세스가 연속 피드로 대체됨에 따라 필요한 처리 리소스를 원활하게 하고 대기 시간을 줄이기 위해 자연스럽게 연속 처리로 이동하기 시작했다.

⇒ 이벤트는 실시간으로 발생하는데 이를 주기적인 배치 지향적 방법으로 손실없이 수집하는 것은 어렵다.

스트림처리 작업은 로그에서 읽고 로그 또는 다른 시스템에 출력하는 모든 작업이다. 위와 같이 통합된 로그를 활용하면 모든 데이터 변환 및 흐름을 파악할 수 있다.

실제로 로그는 스트림 처리과정에서 두가지 역할을 한다.

  1. 로그는 각 dataset에 multi subscriber과 그 순서를 지정해준다. 데이터베이스로부터 두개이상의 업데이트가 있을 시에 정확한 output을 위해 로그가 그 역할을 한다.
  2. 로그는 스트림 처리 프로세스에 버퍼링을 제공한다. 스트림처리가 비동기방식으로 진행되면, 각 데이터 작업의 속도 차이로 인해 생성 및 소비되는 데이터 차이가 발생할 수 있다. 이러한 경우에 로그가 버퍼역할을 한다.

 

데이터 재처리: 람다 아키텍쳐와 그 대안

람다 아키텍쳐는 로그지향적 데이터 모델링의 한 부류

=> 람다 아키텍쳐란?

대량의 데이터를 실시간으로 분석하기 어려우니 batch로 미리 만든 데이터와 실시간 데이터를 혼합해서 사용

핵심은 "재처리". 입력 데이터로 결과를 다시 생성. 결과 데이터를 만들어내는 코드가 수정되면 결과 데이터를 다시 산출.

결과 데이터를 만들어내는 코드가 수정되면 결과 데이터를 다시 산출하여 코드 수정에 따른 영향도를 분석

=> 람다 아키텍쳐의 단점 : 배치 시스템과 실시간 처리 이 두곳에서 같은 결과를 산출. 따라서 batch layer에서 만든 배치 뷰 데이터와 speed layer에서 만든 실시간 뷰의 데이터가 중복되지 않게 관리하는 것이 중요하다. 그러나 단순히 데이터 중복 처리 뿐 아니라 코드를 관리하는 데 있어서도 복잡하다. 각 시스템을 지원하는 환경이 다르기 때문이다.

⇒ 대안 : 스트림처리 시스템에 람다 아키텍쳐처럼 서로 다른 두 시스템을 붙이는 것이 아니라, 스트림 처리 시스템에서 실시간처리를 하면서 재처리를 하는 방식으로 병렬성을 늘리는 방안.

 

상태적 실시간 처리(참고 블로그)

재처리뿐 아니라 상태저장(stateful) 또한 중요.

특정 이벤트 스트림, 가령 클릭 이벤트에 대해 이를 실행한 유저의 DB와 조인한다면 스트림의 내용을 더 강화할 수 있다.

이를 가능하게 하려면 스트림처리를 진행 중인 프로세서에 상태를 저장해야 한다.

이를 로컬테이블이나 인덱스에 보관하는 것이다. 이들 저장소에 입력스트림으로 저장되며 후에, 상태 복원용으로 로컬 인덱스의 변경로그를 활용할 수 있다.

 

Log compaction(로그 압축)

항시 모든 로그를 저장하면 좋겠지만, 공간에도 한계가 있다.

카프카를 예로 들자면 데이터를 순수 이벤트 데이터인지 키별 업데이트 데이터 인지 구분한다. 그리고 순수 이벤트 데이터는 데이터 윈도를 지원함에따라 지정한 일자동안 데이터를 유지한다.

그렇다면 키별 업데이트의 경우는? 키별 업데이트는 어떤 키에 의해 식별 가능한 엔티티의 상태 변화를 구체적으로 기록한 것이며, 이 데이터를 통해 로그의 장점을 그대로 활용할 수있다. 즉 테이블을 그대로 복구하는 것도 가능하다.

그러나 이것이 가능하다는 것 자체가 많은 저장공간을 필요로 한다는 것이다.

따라서 해당 데이터의 경우, 기존 로그를 삭제하는 것이 아니라, 로그에서 기본키에 최신 업데이트한 레코드가 있다면 해당 레코드의 그 직전 레코드는 삭제한다. (아래 그림에서 K2, K5 키 레코드의 경우)

 

3. Distributed system design (분산 시스템 설계)

a. 기존의 중앙 집중식 데이터 시스템에서 여러 데이터 시스템을 만들어서 연결. 이런 경우에는 데이터 통합이 가장 중요.

b. 단일 시스템으로 다른 기능들을 새로운 단일 시스템으로 병합하는 식으로 재통합.

c. 오픈 소스 활용. 즉 서비스 처리 데이터 시스템과 이러한 데이터 시스템을 연계하는 시스템 API로 데이터 인프라를 나누는 것이다.

 

시스템 아키텍처로서 로그의 중요성

  • 노드에 대한 동시 업데이트를 시퀀싱하여 데이터 일관성(최종 또는 즉각적인) 처리
  • 노드 간 데이터 복제 제공
  • 작성자에게 "커밋" 의미를 제공합니다(즉, 쓰기가 손실되지 않도록 보장된 경우에만 확인).
  • 시스템에서 외부 데이터 구독 피드 제공
  • 데이터가 손실된 실패한 복제본을 복구하거나 새 복제본을 부트스트랩하는 기능 제공
  • 노드 간의 데이터 재조정

로그 중심적 시스템은 그 자체로 다른 시스템에서 처리와 적재를 하기위한 데이터 스트림의 공급자.

꼭 카프카가 필요조건은 아니다. 다이나모 같은 데이터 베이스를 활용할 수도 있다.

로그는 아주 효율적인 저장장치이다. 기본적으로 데이터를 효과적으로 서비스하기 위해서는 더 많은 메모리가 필요하게되기 때문이다.

 

 

Reference

 

스트림 처리란?

스트림처리의 개념과 활용 사례

 

 

728x90

+ Recent posts