데이터 중심 애플리케이션 설계 - 10장

공상현 (Kong Sang Hyean)·2024년 8월 12일
0

K DEVCON DDIA STUDY

목록 보기
10/12

😊 Go to Learn이란?

K-devcon에서 주최하는 멘토링 프로그래밍으로 각 분야에서 전문가이신 멘토분들의 멘토링을 통하여 약 2-3달간 진행하는 프로그램입니다.

Go to Learn 1기 같은 경우 Flutter, Back-end, Full-stack, Writing 등 여러가지 주제가 담긴 멘토링 프로그램이 있었습니다.

그 중 Back-end를 중심으로 진행하는 DDIA 프로그램 같은 경우 데이터 중심 애플리케이션 설계라는 책을 매주 1장 씩 정독하고 요약하면서 괸련된 이야기를 논의하면서 진행하고 있습니다.

K-devcon 이란? : IT 정보를 공유하거나 위에서 설명한 Go to Learn 스터디 및 밋업을 개최하는 활동을 하고있는 IT 커뮤니티입니다.
K-devcon 홈페이지 바로가기


📖 10장 요약 및 정리

Part 3 개요

Part 3에서는 데이터 모델도 다르고 최적화된 접근 양식도 다른 여러 데이터 시스템일관성 있는 하나의 애플리케이션 아키텍처로 통합하는 문제에 대해 검토한다.

실제로 복잡한 시스템에서 수행해야 하는 가장 중요한 일 중 하나가 서로 다른 시스템을 통합하는 작업이다.

레코드 시스템 : 믿을 수 있는 데이터 비전을 저장한다. (진실의 근원 / source of truth)

  • 사용자의 입력과 같은 새로운 데이터가 들어오면 먼저 저장된 뒤 정규화를 거친다.

파생 데이터 시스템 : 다른 시스템에 존재하는 데이터를 가져와 특정 방식으로 변환하고 처리하는 결과 - ex ) 캐시 등

  • 파생 데이터는 기존 데이터를 복제한다는 의미에서 중복으로 포함되어진다.
  • 파생 데이터는 대개 비정규화 과정을 통하여 생성되어진다.

일괄처리

일괄 처리 방식 데이터플로 시스템에 대해 살펴보고 대규모 데이터 시스템을 구축하기 위한 원리가 무엇인지 알아본다.

시스템의 종류

  • 서비스 (온라인 시스템) : 클라이언트로부터 요청이나 지시가 올 때까지 기다린다.
  • 일괄 처리 시스템 (오프라인 시스템) : 매우 큰 입력 데이터를 받아 데이터를 처리하는 작업을 수행하고 결과 데이터를 생산한다.
  • 스트림 처리 시스템 (준실시간 시스템) : 일괄 처리 시스템과 마찬가지로 요청에 대해 응답하지 않으며 입력 데이터를 소비하고 출력 데이터를 생상한다. 그러나 입력 이벤트가 발생한 직후 바로 작동한다.

유닉스 도구

배관 공사와 비슷한 점에 착안하여 유닉스를 파이프로 프로그램을 연결하려는 아이디어를 만들어냈고 위의 아이디어는 유닉스 철학의 일부가 되었다.

  • 청크로 나누어 처리하는 방법을 채택
  • 어떤 프로그램의 출력을 다른 프로그램의 입력으로 쓰고자 한다면 같은 데이터 형식을 사용해야한다. -> 호환 가능한 인터페이스를 사용해야한다.
  • 유닉스 도구는 표준 입력과 표준 출력을 사용한다는 것을 볼 수 있다. (stdin / stdout)
    • 프로그램은 입출력에 대해 신경 쓸 필요가 없다. (느슨한 결합 / 지연 바인딩 / 제어 반전)

유닉스 도구는 진행 사항을 파악하기 상당히 쉽다. 하지만 유닉스 도구는 단일 장비에만 실행되기 때문에 하둡이라는 도구가 필요하게 되었다.


맵리듀스와 분산 파일 시스템

맵리듀스

맵리듀스는 유닉스 도구와 비슷한 면이 있지만 수천 대의 장비로 분산해서 실행이 가능하다는 점에서 큰 차이가 있다.

  • 맵리듀스 작업은 분산 파일 시스템상의 파일을 입출력으로 사용한다.
    • 입출력으로 사용하는 파일 시스템을 HDFS라고 부른다.
    • HDFS는 비공유 원칙을 기반으로 하는데 공유 디스크 방식과는 반대의 방식이다.
  • 네임노드 : 특정 파일 블록이 어떤 장비에 저장되었는지 추적한다.
  • 삭제 코딩을 사용하여 손실된 데이터를 복구하는 방식이 있다.
    • RAID와 유사하나 평범한 데이터 센터 네트워크 상에서 이루어진다.

맵리듀스 작업 실행

  • 맵리듀스 작업 하나는 4가지 단계로 수행되어진다.
    • 입력 파일 읽기 -> 레코드마다 매퍼 함수를 호출하여 키와 값을 추출 -> 키를 기준으로 정렬 -> 쌍 전체를 대상으로 리듀스 함수를 호출
  • 맵리듀스 작업을 생성하려면 매퍼와 리듀스라는 콜백 함수를 구현해야한다.
    • 매퍼 : 모든 입력 레코드마다 한 번씩만 호출되어 입력 레코드로부터 키와 값을 추출하는 작업
    • 리듀스 : 매퍼가 생산한 키-값 쌍을 받아 같은 키를 가진 레코드를 모으고 해당 값의 집합을 반복하여 리듀스 함수를 호출한다.

맵리듀스 분산 실행

  • 유닉스 명령어 파이프라인과의 맵리듀스는 여러 장비에서 동시에 처리가 가능하다는 점이다.
    • 맵리듀스 프레임워크가 작업을 수행하기 적절한 장비로 코드를 복사한다.
    • 리듀서 측 연산도 파티셔닝되어진다. -> 사용자가 설정한다.
    • 키-값 쌍은 한 장비에서 정렬하는 대신 단계를 나뉘어서 정렬을 수행한다.
  • 서플 : 리듀서를 기준으로 파티셔닝하고 정렬한 뒤 매퍼로부터 데이터 파티션을 복사하는 과정

맵리듀스 워크플로

  • 맵리듀스 작업 하나로 해결할 수 있는 문제의 범위가 제한적이라서 보통 맵리듀스 작업을 연결하여 워크플로로 구성하는 방식은 일반적이다.
  • 프레임워크 관점에서 보면 두 작업은 완전히 독립적이다.

리듀스 사이드 조인과 그룹화

맵리듀스에서는 일반적으로 이야기하는 색인 개념이 존재하지 않는다.

  • 전체 테이블 스캔 : 파일 집합이 입력으로 주어진 맵리듀스 작업이 있다면 입력 파일 전체 내용을 읽는 방식의 스캔이다.
    • 소량으로 이러한 작업을 수행하면 비용이 많이 들으므로 대용량의 작업에서 수행되어진다.
  • 이벤트 로그를 데이터베이스에 조인하는 좋은 방법은 데이터베이스의 사본을 가져와 이벤트 로그가 저장된 분산 파일 시스템에 넣는 방법이다. -> 맵리듀스를 사용하여 연관된 레코드끼리 모두 같은 장소에 모으는 방법

정렬 병합 조인

  • 보조 정렬 : 항상 사용자 데이터베이스를 먼저 보고 활동 이벤트를 시간 순으로 작업 레코드를 재별하는 방식
  • 보조 정렬을 이용하여 특정 사용자 ID의 모든 레코드를 한 번에 처리하는 알고리즘을 정렬 병합 조인이라고 한다.
    • 한 명의 레코드만 메모리에 유지하면 되고 네트워크로 요청이 필요가 없다.

그룹화

  • 세션화 : 특정 사용자가 취한 일련의 활동을 찾기 위해 사용자 세션별 활동 이벤트를 수집할 때 그룹화를 사용하는 과정
    • 사용자 요청을 받는 웹 서버가 여러 개일 때 분산된 로그 파일의 이벤트를 한 곳에 모으면 세션화를 구현할 수 있다.

쏠림 다루기

  • 키 하나에 너무 많은 데이터가 연관된다면 패턴이 제대로 작동되지 않을 수도 있다. (린치핀 객체 / 핫 키)
  • 위 현상을 해결하기 위하여 쏠린 조인 알고리즘을 사용한다.
    • 어떤 키가 핫 키인지 결정하기 위해 샘플링 작업을 수행한다.
    • 위 방법은 핫 키를 여러 리듀서에 퍼뜨려서 처리하는 방법이므로 복제하는 비용이 들지만 병렬화 효과가 커진다.
  • 핫 키로 레코드를 그룹화하고 집계하는 작업은 두 단계로 수행한다.
    • 임의 리듀서로 내보내기 -> 일부를 그룹화하고 키별로 집계

맵 사이드 조인

맵 사이드 조인 : 입력 데이터에 대해 특정 가정이 가능하다면 조인을 더 빠르게 수행할 수 있는 방법이다.

  • 리듀스 사이드 조인은 리듀서로 복사 한 뒤 입력을 병합하는 과정에서 큰 비용이 발생한다는 단점이 있다.
  • 맵 사이드 조인은 리듀서 및 정렬 작업이 없다. 분산 파일 시스템에서 단순히 입력 파일 블럭 하나를 읽어 시스템으로 출력하는 방식이다.

브로드캐스트 해시 조인 : 맵 태스크에 조인할 큰 입력 파일 블록 중 하나랑 할당하여 작은 입력 전체를 메모리에 적재하는 방법이다.

  • 브로드캐스트 : 큰 입력의 파티션 하나를 담당하는 각 매퍼를 작은 입력 전체에 읽는다는 뜻
  • 작은 조인 입력을 해시 테이블로 적재하는 대신 로컬 디스크에 읽기 전용 색인으로 입력을 저장하는 방법도 있다.

파티션 해시 조인 : 맵 사이드 조인의 입력을 파티셔닝한다면 각 파티션에 독립적으로 적용할 수 있다.

  • 각 매퍼의 해시 테이블에 적재해야 할 데이터의 양을 줄일 수 있다.
  • 조인할 두 입력 모두를 같은 키와 같은 해시 함수를 기반으로 같은 수로 파티셔닝해야 작동되어진다.

맵 사이드 병합 조인 : 파티셔닝 되었을 뿐 아니라 같은 키를 기준으로 정렬되었다면 변형된 맵 사이드 조인을 적용할 수 있다.

  • 위 조인이 가능하다면 선행 작업이 이미 입력 데이터셋을 파티셔닝하고 정렬해 놓았다는 뜻이다.
  • 메모리가 적재 가능한지 고려할 필요가 없다.
  • 맵 사이드 조인을 수행하기 위해서 파티셔닝와 같은 제약 사항이 따른다. 따라서 저장된 데이터셋의 물리적 레이아웃 파악이 중요하다.

일괄 처리 워크플로의 출력

검색 색인 구축 : 정해진 문서 집합을 대상으로 전문 검색이 필요하다면 일괄 처리가 색인을 구축하는데 매우 효율적이다.

  • 리듀서가 해당 파티션에 대한 색인을 구축한 후 색인 파일을 분산 파일 시스템에 구축한다.

키-값 저장 : 머신러닝 시스템 및 추천 시스템을 구축할 때 일종의 데이터베이스로써 활용할 수 있다.

  • 위의 데이터베이스는 사용자의 요청을 받는 웹 애플리케이션에서 질의해야한다.
  • 직접 매퍼와 리듀서 내에 선호하는 데이터베이스 클라이언트 라이브러리를 사용해 하나 씩 데이터베이스 서버로 직접 요청을 보내는 방법이다.
  • 맵리듀스 방법으로 만들어진 데이터베이스는 읽기 전용이기 때문에 자료구조가 단순한 편이다.

하둡과 분산 데이터베이스의 비교

맵리듀스와 가장 큰 차이점은 분산 데이터베이스는 장비 클러스터에서 분석 SQL 질의를 병렬로 수행하는 것을 초점을 두지만 맵리듀스는 아무 프로그램이나 실행 할 수 있는 운영체제와 비슷한 속성을 제공한다는 점이다.

저장소의 다양성

  • 특정 모델에 떄하 데이터를 구조화해야하는 데이터베이스와는 달리 하둡은 데이터가 어떤 형태라도 상관없이 HDFS로 덤프할 수 있는 가능성이 있다.
    • 초밥 원리 : 하나의 이상적인 데이터 모델은 존재하지 않을지 몰라도 데이터에는 여러 목적에 적합한 다양한 관점이 존재한다. 따라서 원시 상태로 데이터를 덤프하는 것만으로도 여러 변환이 가능하다.

처리 모델의 다양성

  • 분산 데이터베이스는 일체식 구조로서 긴밀히 통합되지만 맵리듀스 같은 경우 구조 간 유연하게 이루어지기 때문에 모든 종류의 처리를 표현하지 목하는 분산 데이터베이스와는 달리 SQL 실행 엔진을 구축할 수 있다.

결함을 줄이는 설계

  • 실행 장비 중 한 장비만 죽어도 전체 질의가 중단되는 분산 데이터베이스와 달리 맵리듀스는 개별 테스크 수준에서 작업을 수행하기 때문에 각 실패를 견딜 수 있다.

맵리듀스를 넘어

중간 상태 구체화

맵리듀스를 사용할 때 대개 한 작업의 출력은 팀 내에서 유지보수하는 다른 특정 작업의 입력으로만 사용되어진다.

  • 중간 상태 : 분산 파일 시스템 상에 있는 파일들을 한 작업에서 다른 작업으로 데이터를 옮기는 수단을 뜻한다.
  • 구체화 : 중간 상태를 파일로 기록하는 과정
  • 파이프는 중간 상태를 완전히 구체화하는 대신 점진적으로 출력을 입력으로 스트리밍한다.

데이터플로 엔진

  • 중간 상태를 구체화시키는 접근법은 아래의 단점을 지니게 된다.
    • 장비들 사이에 부하가 한 쪽으로 쏠리게 된다면 워크플로 내 전체 수행 시간이 느려질 수 있다.
    • 매퍼가 종종 중복 될 수 있다.
    • 중간 상태의 파일들을 여러 장비에 복제되었다는 의미는 임시 데이터로써는 과잉 조치일 수 있다.
  • 이러한 단점을 해결하기 위해 데이터플로 엔진이 등장하게 되었다.
    • 여러 처리 단계를 통해 데이터 흐름을 명시적으로 모델링한다.
    • 연산자를 이용하여 유연한 방법을 통하여 함수들을 조합할 수 있다.
    • ex) 스파크, 드라이어드, 네펠레 등
  • 맵리듀스 워크플로와 같은 동일한 연산을 데이터플로 엔진을 사용하여 구현할 수 있다.
    • 최적화로 인하여 수행 속도가 데이터플로 엔진이 더 빠르다.

내결함성

  • 스파크와 플링크, 테즈 같은 경우 중간 상태를 쓰지 않기 때문에 내결함성 확보를 위해 다른 접근법을 사용한다. (데이터플로 엔진)
  • 중간 상태까지 잃게되면 아직 유효한 데이터로부터 계산을 다시하여 복구하는 방식을 사용
  • 데이터를 재연산할 때 해당 연산이 결정적인지 아닌지 파악하는 것이다. 따라서 연산자를 결정적으로 만드는 것이 중요하다.
    • 비결정적인 원인을 제거하는 방식을 사용 -> 의사 난수를 생성

그래프와 반복 처리

이행적 폐쇄 : 특정 정보를 전파하기 위하여 정점 하나와 인접한 정점을 조인하면서 특정 조건에 도달할 때 까지 반복하는 알고리즘

  • 머신러닝, 랭킹 시스템 분야에서의 그래프 처리에서 사용되어진다.
  • 하지만 완료될 때 까지 반복 되는 개념은 맵리듀스에서 표현할 수 없다. -> 일회성으로 처리되어지기 때문

프리글 처리 모델

  • 맵리듀스와 같은 메시지 전달을 이용하여 간선을 따라 메시지를 전달한다.
    • 반복할 때 마다 개별 정점에서 함수를 호출하여 그 정점으로 보내진 모든 메시지를 전달한다.
  • 아파치 지라프, 스파크 그래프 X API, 플링크 API 등의 BSP 구현체에서 사용되어진다.

내결함성

  • 메시지는 일괄 처리가 가능하기 때문에 통신 중 발생하지 않는다. 대기 시간은 반복과 다음 반복 시간 사이에서만 발생한다.
  • 프리글 프레임워크 차원에서 결함을 복구한다.
    • 모든 정점의 상태를 주기적으로 체크포인트로 저장함으로써 보장되어진다.

병렬실행

  • 정점은 단순히 다른 정점으로 메시지를 전달하는 일을 하기 때문에 그래프를 파티셔닝하는 일은 프리글 프레임워크가 담당한다.
    • 프로그래밍 모델은 한 번에 정점 한 개를 다루기 때문에 프리글이 임의의 방법으로 그래프를 파티셔닝 할 수 있다.
    • 그러나 최적화해서 분할하는 것이 어렵기 때문에 장비 간 통신 오버헤드가 많이 발생한다. -> 알고리즘이 심각하게 느려질 수 있다.

고수준 API와 언어

규모가 점점 커지면서 직접 맵리듀스 작업을 작성하는 일이 어려워졌기 때문에 고수준 언어 및 API가 인기를 끌었다.

  • 이러한 API는 일반적으로 관계형 스타일의 빌딩 블록을 사용하여 연산을 표현한다.
  • 코드를 적게 작성해도 될 뿐만 아니라 대화식 사용도 지원할 수 있다는 장점이 있다.

하이브, 스파크, 플링크 내에서 비용 기반의 질의 최적화기를 내장하고 있다.

  • 선언적인 방법으로 조인을 지정하면 가능하다. 하지만 어떤 면에서는 선언형 모델과는 다른 점이 있다.
    • 함수 콜백 개념으로 사용자 지정 함수를 호출한다. 위를 이용하여 출력을 결정하는 코드를 임의로 작성 할 수 있다.
  • 선언적인 기능을 통합하게 된다면 디스크에서 필요한 칼럼만 읽을 수 있어 오버헤드를 줄일 수 있는 장점이 있다.

😉 필자의 생각

이번 장은 일괄 처리 시스템에서 어떻게 데이터가 처리되는지를 주제로 알아보는 장이었다. 특히나 이번 10장에서는 맵리듀스에 대한 비중이 많은 비율을 차지하였는데 아무래도 단일 장비로 실행되고 있는 유닉스 도구보다 분산 데이터 처리가 가능 한 맵리듀스가 아마 현재 데이터 처리에 대한 강점을 지니고 있지 않았기 때문에 많은 비중을 차지 하지 않았나 생각이 든다.

또한 위 장을 읽어보면서 맵리듀스의 방식을 이용하여 그래프형 데이터 모델 처리 하는 방법이 기술되어있는 내용을 읽어보면서 전에 그래프형 데이터가 AI 활용에 많이 쓰인다는 것이 생각이 나서 한 번 논의한 적이 있었다. 논의 결과 위의 방법을 이용한 데이터 실시간 처리는 현재로써는 많이 어렵다고 하며 스냅샷으로 이루어진 그래프를 통하여 테이터 모델을 처리하는 방식으로 이루어진다고 한다. 예를 들어 어떤 사람들은 이러한 주제에 관심을 가지고 있는 식으로 테이터를 학습하는 사례를 꼽을 수 있다.

profile
개발자 같은 거 합니다. 1인분 하는 개발자로서 살아갈려고 노력 중입니다.

0개의 댓글