728x90

하둡 완벽가이드를 읽으며 정리한 내용입니다.


1.1 데이터

빅데이터의 등장, 즉 활용할 수 있는 데이터가 점차 늘어나고 중요해지고 있으며, 이에 대한 저장과 분석 즉 다루는 기술의 어려움에 대해서 언급하고 있다.

즉 "하둡"이라는 기술이 사용되어야 하는 이유를 설명하고 있다.

 

1.2 데이터 저장소와 분석

디스크의 용량과 성능이 아무리 좋아진다고해도, 하나의 디스크에서 모든 데이터를 읽기보다 여러 디스크에서 분산되어 병렬로 작업하는 것이 훨씬빠르다.

책에서의 예시에서는 1테라바이트를 읽는데, 하나의 디스크는 전체 데이터를 읽는데 두시간 반이 걸린다. 그러나 여러 디스크, 가령 10개의 디스크에서 데이터를 읽는다면 약 18분이 걸릴 것이다.

→ 1테라 바이트 : 1개 : 180분 ⇒ 1,024 기가 바이트 : 180분 ⇒ 102.4 기가 바이트 : 18분 : 10개

→ 1테라 바이트를 10개의 그룹으로 쪼개서 각 디스크에 분산

 

이러한 이유로 주어진 데이터를 분산하여 저장할 수 있는 HDFS가 활용된다.

 

그러나 분산이 무조건 좋지는 않다.

  1. 하드웨어 장애 고려
    • 이를 통한 데이터 손실을 막기 위해 데이터를 여러 곳에 복제해야한다.
  2. 분할된 데이터를 어떻게든 결합해야 분석이 가능해짐
    • 이 과정에서 병합자체가 어렵다기 보다는 정합성을 맞추는 작업이 어렵다.

즉 분산하여 데이터를 저장하는 것도 중요하지만, 이를 최소한의 손실로 저장해야 하며(이를 위해 분산 복제)

분산 저장된 데이터를 분석하고 활용할 수 있어야 하는데 이를 위해 맵리듀스를 활용한다.

 

1.3 전체 데이터에 질의하기

맵리듀스의 전제가 한 번의 쿼리로 전체나 상당한 규모의 데이터셋을 처리하는 것이다.

이것이 바로 맵리듀스의 장점이다.

맵리듀스는 일괄 질의 처리기이며, 전체 데이터셋을 대상으로 비정형 쿼리를 수행하고 합리적인 시간내에 그 결과를 보여준다.

 

1.4 일괄 처리를 넘어서

맵리듀스는 일괄처리로, 대화형 분석에는 적절하지 않다보니 빠른 시간 내에 결과를 받기가 힘들다.

애초에 하둡도 일괄처리를 전제로 등장하였다. 그러나 최근에는 하둡 에코 시스템 내에 여러 기술들이 생겨나면서 여러 분석이 가능하다.

 

여기서 하둡 에코 시스템은 분산 컴퓨팅과 대규모 데이터 처리를 위한 기반 시설들의 모음을 의미한다.

 

1.5 다른 시스템과의 비교

1.5.1 관계형 데이터베이스 관리 시스템

하둡이 필요한 이유는? 그냥 여러 개의 디스크를 가진 데이터베이스를 이용하여 대규모 분석을 하면 되지 않을까?

답은 ‘탐색 시간(데이터를 읽거나 쓰는 작업)은 전송속도보다 발전이 더디다'는 디스크 드라이브의 또 다른 특성에서 찾을 수 있다.

 

탐색은 데이터를 읽거나 쓸 때 디스크의 헤더를 디스크의 특정 위치로 이동시키는 조작이며 이것이 바로 디스크 조작의 지연과 관계된 특징이다. 전송 속도는 디스크의 대역폭과 관련되어 있다.

 

데이터 접근 패턴이 탐색 위주라면 데이터 셋의 커다란 부분을 읽거나 쓰는 작업은 전송 속도에 좌우되는 스트리밍 조작보다 더 오래 걸릴 것이다.

 

데이터베이스의 탐색 작업에 대해서, 일부 레코드를 읽고 쓰는(변경) 작업은 전통적인 B-트리를 사용하는 것이 적합할 수 있다.

그러나 상당 부분, 즉 많은 레코드를 읽고 쓰는 작업을 할 때는 B-트리는 데이터베이스를 재구성하기 위해 sort/merge를 사용해야 하므로 맵리듀스 보다 비효율적이다. 

 

위의 설명을 토대로 보면 맵리듀스는 RDBMS를 보완하는 것 처럼 보인다. 맵리듀스는 일괄 처리 방식으로 전체 데이터 셋을 분석할 필요가 있는 문제에 적합하다. 

-> 즉 빅데이터 처리에 적합하다.

 

RDBMS는 상대적으로 작은 양의 데이터를 낮은 지연 시간에 추출하고 변경하기 위해 데이터 셋을 색인하기때문에 특정 쿼리와 데이터 변경에 적합하다. 기본적으로 맵리듀스는 한번 쓰고 여러번 읽는 데이터 변경 방식이고 읽기 기준 스키마라면, RDBMS는 여러번 읽고 쓰는 방식이며 쓰기 기준 스키마이다.

→ 이러한 기준에서의 두 시스템의 차이는 점점 줄어들고 있다.

→ RDBMS은 하둡의 개념을 포함하고 있으며 하둡 시스템의 하이브는 대화형으로 발전하고 있으며 색인이나 트랜잭션과 같은 기능을 추가하고 있기도 하다.

 

이 둘의 또 다른 차이점은 데이터셋 내부에서 치리되는 구조의 양이다. RDBMS의 영역은 정형 데이터까지이다.

하둡은 별도로 스키마가 없는(대표적으로 이미지, 일반 텍스트) 비정형, 반정형 데이터도 처리할 수 있다.

→ 읽기 기준 스키마라는 특징 덕분에

 

여기서 쓰기 기준 스키마란, 데이터를 변경하기 전에 스키마가 정해져 있어야 한다고 생각하면 된다.
반대로 읽기 기준 스키마는 데이터를 읽는 순간 스키마를 적용해서 읽기 때문에 사전에 스키마를 적용하지 않아도 된다. 따라서 맵리듀스가 RDBMS와 달리 비정형 데이터를 다룰 수 있는 것이다. 

1.5.2 그리드 컴퓨팅

수년간 대규모 데이터를 처리하고 있는 컴퓨팅이다. 보통 클러스터 머신 여러대에 작업을 분산하는데, 계산 노드들이 대용량 데이터에 접근해야 할때는 네트워크 대역폭때문에 병목현상이 생기고 계산노드가 빈둥거리게 되는 문제가 발생한다.

 

하둡은 계산노드에 데이터를 함께 배치한다 → 바로 데이터 지역성

→ 하둡은 이를 통해 중요한 자원 중 하나인 네트워크 대역폭을 보존한다.

 

대규모 분산 컴퓨팅에서 수많은 프로세스를 조율하는 것은 엄청난 과제다. 가장 어려운 것은 원격 프로세스가 실패했는지 정상인지 알수 없을 때와 같은 부분 실패에 현명하게 대처하는 것과 전체적인 계산의 진행을 이어가는 것이다.

 

맵리듀스와 같은 분산 처리 프레임 워크는 실패한 테스크를 자동으로 감지하여 장애가 없는 머신에 다시 배치하도록 구현되어 있기 때문에 개발자는 실패에 크게 고민하지 않아도 된다.

이것이 가능한 이유는 맵리듀스가 태스크 간의 상호 의존성이 없는 비공유 아키텍쳐이기 때문이다.

비공유 분산 아키텍쳐이므로 여러 대의 서버로 클러스터를 만들고, 서버를 추가하면 연산 기능와 저장 기능이 서버의 대수에 비례하여 증가한다. 왜냐면 각 서버 간은 자원을 공유하지 않기 때문이다. 

즉, 상호의존이 없는 다른 서버에 실패한 서버에 대한 영향을 받지 않고 재실행할 수 있다는 것이다. 

→ 그러나 의존성이 없다고 보는 것은 지나치게 단순화 한것이다. 왜냐면 매퍼의 출력이 리듀서로 전송되기 때문이다.

 

1.5.3 자발적 컴퓨팅

해당 프로젝트는 청크라는 작업 단위로 해결할 문제들을 분리하고 이를 분석하기 위해 전세계의 컴퓨터로 보낸다.

어떤 점에서는(분산) 맵리듀스와 유사해보이지만 큰 차이가 있다.

해당 프로그램은 CPU 중심적이고 작업단위를 전송하는 시간이 계산하는 시간보다 빠르기 때문에 전 세계 수십만 대의 컴퓨터에서 실행하는데 적합하다. 자발적 컴퓨팅은 연결 속도가 가변적이고 데이터 지역성이 없는 신뢰할 수 없는 머신에서 오랜 시간이 걸리는 계산을 실행한다.

맵리듀스는 매우 높은 네트워크 대역폭을 가진 단일 데이터 센터에 있는 신뢰성 높은 전용 하드웨어에서 수 분 또는 수시간내에 잡을 실행할 수 있도록 설계 되었다.

 

1.6 아파치 하둡의 간략한 역사

시초는 검색 라이브러리, 웹 검색 엔진에서 시작했다고 볼 수 있다.

→ 그만큼 수많은 데이터들 사이에서 원하는 것을 빠르게 탐색/검색해서 추출해내는 것이 중요했기 때문일까?

그러나 시스템만으로는 수십억 웹 페이지로 확장할 수 없었고, 2003년에 구글에서 실제로 운영되는 GFS라는 구글 분산 파일 시스템의 아키텍쳐를 설명한 논문이 발표되었고 큰 도움을 얻을 수 있었다.

매우 큰 파일에 대한 저장 문제를 해결할 수 있을 뿐만 아니라, 관리 작업에도 신경 쓸 필요가 없는 시스템이었다.

 

2005년 초에 너치 개발자들은 너치 내부에 맵리듀스를 구현했고, 2005년 중반까지 모든 주요 너치 알고리즘이 맵리듀스와 NDFS로 수행되도록 코드를 변경했다. 이는 원래 목적인 검색 외에도 다른 분야에서도 활용 가능했다.

2006년에 하둡 이라는 이름의 독립된 서브 프로젝트가 탄생했다.

이후 더그 커팅(창시자)가 야후에 합류하여 2008년 2월에 하둡 클러스터에서 검색 색인을 만들었다는사실을 발표한다.

 


맵리듀스는 태생 자체가 병행성/분산 병렬성을 고려하여 설계되었고 누구든지 충분한 장비만 갖추고 있다면 대규모 데이터 분석을 할 수 있다. 

2.1 기상 데이터 셋

매시간 기상센서들로 인해서 모이는 대량의 로그데이터를 맵리듀스를 활용하여 저장 및 분석할 수 있는 사례로 언급했다. 

이러한 로그 데이터는 반구조적이면서도 레코드 지향적이라서 맵리듀스를 이용한 데이터 분석에 적합하다. 

 

2.2 유닉스 도구로 데이터 분석하기

하둡을 사용하지 않고 연도별로 분류된 데이터들을 각각 분석하기 위해서 awk라는 행기반 데이터 처리를 위한 유닉스 도구를 사용할 수 있다. 이론적으로는 한대의 머신에 있는 모든 하드웨어 스레드를 활용하여 연도별 파일을 서로 다른 프로세스에 할당하여 처리하면 된다.

그러나 문제가 발생할 수 있다.

  1. 실제로 각 파일의 크기가 달라서 프로세스에 균등하게 리소스가 분배되지 않을 것이다.
    • 대안 중 하나는 전체 입력 파일을 고정 길이의 데이터 청크로 나누고 각 청크를 하나의 프로세스에 할당하는 것이다.
  2. 독립적인 프로세스의 결과를 모두 합치는 데 더 많은 처리가 필요할 수도 있다.
  3. 단일 머신의 처리 능력은 여전히 한계가 있다.

 

2.3 하둡으로 데이터 분석하기

2.3.1 맵과 리듀스

맵과 리듀스는 각각 데이터의 입력과 출력이라 생각하면 된다.

2.3.2 자바 맵리듀스

하둡은 네트워크 직렬화를 위해 (내장 자바 타임 대신) 자체적으로 기본 타입 셋을 제공한다. 

직렬화란 객체에 저장된 데이터를 I/O스트림에 쓰기(출력)위해 연속적인 데이터로 변환하는 것이다. 
즉 컴포넌트 간 데이터 통신을 위해서는 프로그래밍 언어나 플랫폼에 독립적인 표준화된 포맷이 필요하다. 

입력과 출력경로를 지정하게되는데, 출령 경로는 리듀스 함수가 출력 파일을 저장할 디렉터리다. 이때 잡을 수행하는 시점에 지정한 디렉터리가 존재하면 절대 안된다. 만약 존재하면 하둡은 에러 메시지를 출력하고 잡을 실행하지 않는다. 이는 데이터 손실을 방지하기 위해서다. (오랜시간에 걸쳐서 얻은 결과물을 다른 잡의 결과물이 덮어써버리는 것을 방지하기 위해)

테스트 수행

작은 데이터 셋으로 테스트를 권장. 독립 모드(standalone)로 하둡을 설치한다.

→ 독립모드를 사용하면 하둡은 로컬 파일 시스템과 로컬 잡 수행자로 맵 리듀스 잡을 실행한다.

  1. 하둡 명령을 쉘에서 호출하면 해당 클래스를 실행하기위해 먼저 자바가상 머신이 구동된다.
  2. 의존성있는 모든 하둡 라이브러리를 클래스 경로에 추가하고 하둡 환경 설정을 불러온다.
  3. 실행하고 나오면 나오는 로깅 메시지에서 잡과 각 태스크의 식별자는 아주 중요하다

 

2.4 분산형으로 확장하기

2.4.1 데이터 흐름

MapReduce Job : 클라이언트가 수행하는 작업의 기본단위

  •  map task , reduce task
  • 각 태스크는 YARN을 이용하여 스케줄링 되고 클러스터의 여러 노드에서 실행된다. 
    • 즉 맵리듀스 잡을 입력 스플릿 또는 스플릿이라고 부르는 고정크기 조각으로 분리한다. 각 스플릿마다 하나의 맵 태스크를 생성하고 각 레코드를 사용자 정의 맵 함수로 처리한다. 
  • 이렇게 스플릿으로 분리된 많은 조각을 각각 처리 => 병렬처리 하는 것이 훨씬 빠른다.
    • 스플릿의 크기가 작을수록 부하 분산에 더 좋은 효과를 낼 수 있다.
    • 그러나 스플릿 크기가 너무 작으면 스플릿 관리와 맵 태스크 생성을 위한 오버헤드 때문에 잡의 실행시간이 증가한다.
  • 기본적으로 스플릿 크기는  HDFS 블록의 기본 크기인 128MB가 적당하다고 알려져 있다. 
    • 블록의 크기는 클러스터 설정에 따라 다르고 파일을 생성할 때 개별로 지정할 수 있다.

하둡 맵리듀스의 데이터 지역성으로 인한 최적화

  • 일반적으로 입력 데이터가 있는 노드에서 맵 태스크를 실행(위 그림의 a)
    • 클러스터의 중요한 자원인 네트워크 대역폭을 사용하지 않는 방법이다.
  • 만약에 블록 복제본이 저장된 세개의 노드 모두 다른 맵 태스크를 실행하여 여유가 없다면, 저장된 동일 랙에 속한 다른 노드에서 가용한 맵슬롯을 찾느다(위 그림의 b)
  • 아주 드문 일이지만, 데이터 복제본이 저장된 노드가 없는 외부 랙의 노드가 선택될 수도 있는데 이때에는 랙간 네트워크 전송이 불가피하게 일어난다(위 그림의 c)
  • 최적의 스플릿크기가 HDFS블록 크기와 같아야 하는 이유는 그 블록 크기가 단일 노드에 저장된다고 확신할 수 있는 가장 큰 입력 크기이기 때문이다.
    • 하나의 스플릿이 두 블록에 걸쳐 있을 경우, 스플릿의 일부 데이터를 네트워크를 통해 맵 태스크가 실행되는 다른 노드로 전송해야 한다. ⇒ 이때 속도가 느리다

실제로 맵 태스크만의 결과는 로컬디스크에 저장되는데, 맵의 결과는 최종결과가 아닌 리듀스 작업을 위한 중간 결과물이기 때문이다.

따라서 HDFS에 저장되어 내부 복제과정을 추가하는 것은 적절치 않다.

  • 리듀스 태스크는 모든 매퍼의 출력 결과를 입력으로 받기 때문에 데이터 지역성의 장점이 없다.
    • 일반적으로 안정성을 위해 결과는 HDFS에 저장되고, 첫번째 복제본은 로컬 노드에 저장되고 나머지 복제본은 외부 랙에 저장된다.
    • 리듀스 태스크가 무조건 하나일 필요는 없다.
    • 태스크 수를 독립적으로 지정할 수 있다.
    • 만약 리듀스가 여러개면 파티션으 생성하고 맵의 결과를 각 파티션에 분배한다. (파티셔닝 알고리즘)

2.4.2 컴바이너 함수

맵리듀스 작업 진행 시 자원을 최소화하여 사용할 필요가 있을 때 컴바이너 함수가 맵-리듀스 간의 데이터 전송을 최소화할 수 있게 해준다.

 

컴바이너 함수는 리듀스 함수의 출력이 리듀스 함수의 입력이 되는 것을 허용하는 것을 뜻한다. 

예를 들어 최대값, 최솟값, count와 같은 결과를 얻기위해 map task에 취합한 결과를  reduce에서만 진행하는 것이 아니라 각각의 map task에서 최댓값, 최솟값, count와 같은 집계 과정을 거쳐 reduce task로 전달하는 것이다.

이를 통해 map-reduce 간 전달하는 데이터 양이 줄어 필요 자원을 줄일 수 있다.

 

컴바이너 함수는  Reducer 클래스를 사용해서 정의할 수 있다.

2.4.3 분산 맵리듀스 잡 실행하기

단일머신보다 분산된 노드에서 작업하면 실행속도가 빠르나 정확히 정비례로 성능이 증가하지는 않는다.

그 이유는 입력 데이터가 골고루 분산되지 않았기 때문이다.

 

2.5 하둡 스트리밍

하둡과 사용자 프로그램 사이의 인터페이스로 유닉스 표준 스트림을 사용한다. 이를 통해 사용자들은 다양한 언어를 이용하여 맵리듀스 프로그램을 작성할 수 있다.

 

스트리밍과 자바 맵리듀스 API의 차이 자바 맵리듀스 API는 한 번에 하나의 레코드를 맵 함수로 처리하도록 설계되었다. 이를 위해 입력에서 각 레코드를 처리하기 위해 mapper의 map()메서드를 호출한다. 그러나 스트리밍은 맵 프로그램에서 입력 자체를 처리하는 방식을 결정할 수 있다. 따라서 스트리밍은 입력방식을 제어할 수 있으므로 한 번에 여러 행을 읽어서 처리할 수 있다.

 

 

Reference

728x90

+ Recent posts