게시판
      
상위분류 : 잡필방 중위분류 : 서류가방 하위분류 : 전산과 컴퓨터
작성자 : 문시형 작성일 : 2013-03-19 조회수 : 5,059
제 목 : 빅데이터 환경을 위한 하둡

RDMS(Relational Database, 관계형 데이터베이스)에 데이터를 저장하고 관리 및 분석하기 힘들 만큼 방대하고 정형화되지 않은 데이터를 빅데이터라고 말한다. 예컨대 140개의 텍스트로 구성된 트위터의 글은 전 세계 수억 명의 사용자가 이용하는 만큼 하루에 수십 테라 바이트 용량의 거대 데이터가 생성되는데 이를 RDMS로 저장하고 관리 및 분석한다는 것은 사실상 불가능하다.

빅데이터에 주목하라
최근 대부분의 기업이 CRM(Customer Relationship Management)이나 마케팅 또는 효율적인 의사결정을 위한 DW(Data Warehouse)와 BI(Business intellignece)를 도입하고 있다. 고객의 자사 서비스 이용정보나 거래정보인 DW의 기초 데이터는 RDBMS로도 충분히 대응할 수 있는 수준이었다. 그러나 아이폰으로 대변되는 스마트폰을 시작으로 태블릿PC까지 함께 확산됨에 따라 데이터 량이 급증하고 있으며, 최근에는 로그 데이터를 새로운 분석 대상으로 활용되고 있다. 개인화된 추천 상품 및 맞춤형 광고 등이 모두 로그 분석을 활용해 가능해졌으며, 이 모두가 빅데이터로 인한 변화다. 이처럼 빅데이터를 비즈니스에 활용하고 기업을 보다 효율적으로 운영할 수 있는 새로운 솔루션에 대한 수요가 증가하고 있다.

대용량 RDBMS를 빅데이터 솔루션으로 대체하는 등 빅데이터가 비용절감을 위한 수단으로도 활용되고 있다. 오라클이나 MS 등 RDBMS 벤더가 고가의 라이선스와 유지보수 비용을 절감하기 위해 라이선스 비용이 없는 공개SW 기반의 빅데이터 솔루션으로의 전환을 많은 기업이 검토하는 추세다.

빅데이터를 통한 새로운 가치 창출 시작돼
최근 빅데이터를 새로운 가치 창출의 수단으로 도입한 사례가 늘고 있다. 하둡과 인포매티카(Informatica) 9.1을 도입한 미국의 US익스프레스는 차량 운전 습관을 이미지 파일로 자산화하고 센서나 RFID 태그, 위치 정보 데이터로 고객의 행동양식을 분석해 최적의 경로를 고객에게 제공함으로써 매년 수백만 달러의 연료 절감 효과를 거두고 있다. 국내에서도 친숙한 지메일과 페이스북의 맞춤형 광고도 빅데이터를 활용한 사례다.

최근에는 국내에서도 빅데이터를 활용하기 위한 다양한 노력이 시도되고 있으며, 국내 통신사 중 하나는 전화 로그 데이터를 하둡으로 저장하고 분석하는 프로젝트를 현재 진행하고 있다.

RDBMS에 비춰본 하둡에 대한 이슈
아직 빅데이터 도입은 걸음마 단계로, 이를 효과적으로 활용하기 위해서는 몇 가지 이슈를 이해해야 한다. 

RDBMS와 빅데이터 솔루션인 하둡은 용도에서 차이가 있다. RDBMS에서 emp_no에 인덱스된 경우 ‘select * from emp where emp_no = 2111’란 질의에 대해 실시간으로 ‘2111’란 결과가 바로 출력되지만 하둡은 이런 처리에 많은 시간을 소요한다. 이는 RDBMS와 하둡은 기본적인 개념에서 차이가 있기 때문이며, 이런 제약으로 인해 하둡은 대용량 데이터 분석에 주로 도입돼 DW를 대체하고 있다.

하둡은 수십에서 수천대의 서버에 데이터를 저장하기 때문에 서버 관리에 보다 많은 전력과 인력 그리고 유지비용이 필요하다. 대량의 데이터를 처리하는 만큼 데이터 오류에 대응할 수 있는 마땅한 수단이 없다.

더불어 데이터 처리 중에 발생된 문제에 대해서도 RDBMS보다 원인 분석과 해결에 더 많은 시간이 소요되고 상당히 까다로운 경우가 많다. 이는 결국 하둡이 실시간 처리가 안 되기 때문이다.
또한 빅데이터 시장이 막 개화하기 시작해 하둡 전문가가 부족하다. 고객 입장에서는 프로젝트를 수행하거나 유지보수에 더 많은 비용을 지불해야 한다.

빅데이터 시대에 주목받는 하둡과 NoSQL빅데이터 솔루션은 크게 분석 기술과 저장 기술로 나뉜다. 빅데이터 분석 기술로는 군집 분석, 텍스트 마이닝 등 다양한 알고리즘을 적용한 기존의 분석기술이 함께 활용되며, 빅데이터 저장 기술로는 하둡과 NoSQL이 있다.

하둡은 대용량분산저장과 처리를 위한 프레임워크로, 크게 HDFS와 맵리듀스(MapReduce)로 구분된다. 유닉스 파일시스템과 이용법이 유사한 HDFS는 파일을 여러 대의 서버에 분산 저장하기 위한 파일시스템이며, 맵리듀스는 각 서버에서 데이터를 분산 처리하는 분산병렬처리를 위한 프레임워크다. 개발자는 맵리듀스 프레임워크 기반의 자바 프로그램을 개발하고 하둡 플랫폼에서 이를 실행해 대량의 데이터를 병렬로 처리할 수 있다.

하둡은 오픈소스 기반의 다양한 서브 프로젝트가 진행되고 있다. 맵리듀스 프로그램을 데이터 형태에 따라 각각 개발하기란 쉽지 않으며, 이를 해소하기 위해 하이브(Hive)란 프로젝트가 진행 중이다. 하둡 프로젝트의 서브 프로젝트인 하이브는 CLI(Common Line Interface)로 쿼리를 마치 질의하듯 단순 처리할 수 있어 사용자 요청을 맵리듀스가 자동으로 처리하고 결과를 반환한다. 이 쿼리는 기본적으로 ANSI SQL을 지원하고 하이브의 경우 JDBC 드라이버를 제공해 자바 프로그램에서 하둡에 쉽게 접근할 수 있고 개발 편의성도 우수하다.

오라클과 MySQL 등의 RDBMS와 하둡 간에 데이터 전송을 위한 스쿱(sqoop) 프로젝트도 주목할 만하다. 스쿱은 RDBMS에서 데이터를 얻기 위해 데이터 스키마를 해당 데이터베이스에서 추출하고 하둡에 파일을 작성한다. 또한 스쿱은 데이터를 보내고 받기 위해 내부적으로 맵리듀스를 활용하기에 기본적으로 병렬 처리를 지원한다.

하둡에 데이터를 직접 저장할 수도 있지만 누적되는 로그 데이터를 정확하고 손실 없이 저장하기는 쉽지 않다. 이를 가능케 하는 서브 프로젝트가 플룸(Flume)이다. 플룸을 이용하면 로그가 실시간 갱신되는 여러 대의 서버에서 로그를 수집해 손쉽게 하둡에 이를 저장할 수 있을 뿐 아니라 수집된 데이터에 대한 데이터 무결성을 보장할 수 있다.

한편, 하둡은 파일을 분산 저장 및 관리하는 역할과 병렬 처리를 수행할 뿐 DBMS처럼 데이터를 구조화시켜 저장하진 않는다. RDBMS와 다른 형태의 DBMS인 NoSQL은 이런 기능을 수행한다. NoSQL은 기존 DBMS와는 달리 데이터의 신뢰성과 일관성보단 데이터의 가용성과 확장성에 중점을 둬 개발됐다. NoSQL 기반의 솔루션에는 Couch DB와 몽고(Mongo) DB가 있으며, 도큐먼트 기반의 몽고 DB의 경우 높은 성능과 가용성을 제공할 뿐 아니라 쉽게 용량 증설이 가능하도록 스케일아웃(Scale-Out)을 지원한다. 특히 쿼리나 인덱스 개념이 필요하고 다이내믹 쿼리가 필요할 때에도 몽고 DB는 매우 유용하다.

얼랭(Erlang) 언어로 제작된 CouchDB는 HTTP·REST 방식의 프로토콜을 사용해 데이터 수집 및 변경이 적은 경우 적합하다. Redis는 키-값으로 저장되는 메모리 DB로, 메모리에 데이터를 저장하는 만큼 성능이 우수하고 데이터를 디스크에 저장할 수도 있어 실시간 데이터 수집 및 실시간 커뮤니케이션에 적합하다.

하둡 기반의 HBase도 NoSQL로 분류된다. HBase는 하이브와 달리 실시간 처리에 중점을 둬 빅데이터 테이블을 빈번히 읽고 쓰는 환경에 적합하다. 

이외에도 NoSQL을 대표하는 DBMS로 카산드라(Cassan dra)가 있다. 카산드라는 컬럼과 컬럼 패밀리로 구성된 데이터를 모델을 가지고 있다. 여기서 컬럼은 이름 및 값으로만 이뤄진 구조체이며, 컬럼 패밀리는 컬럼의 집합이다. 자바로 제작돼 읽기보단 쓰기 성능이 우수하기 때문에 대량의 쓰기 작업에 유리하다.


< 그림 1> 빅데이터 관련 기술의 구조

빅데이터 분석을 위한 최적의 플랫폼, 하둡GFS(Google File System)와 맵리듀스에 대한 구글의 논문 속 개념을 야후가 개방형 프레임워크로 구현했다. 하둡이 각광 받게 된 이유는 대량의 데이터 처리를 위해 하드웨어를 업그레이드하는 스케일 업(Scale Up) 방식의 접근이 아니라 서버를 병렬로 추가하는 스케일 아웃 방식을 채택했기 때문이다. 이는 데이터 증가에 유동적으로 대처할 수 있고 시스템 중단 없이 용량을 증설할 수 있는 이점이 있다. 또한 하둡을 이용하면 개발 과정에서 네트워크 프로그래밍이나 동시성 등의 복잡한 고민 없이도 손쉽게 프로그램을 개발할 수 있다.

분산 환경에서 데이터 저장 및 처리에 최적의 솔루션으로 하둡이 꼽히는 이유는 크게 두 가지다. 바로 분산 환경에서 데이터를 저장하기 위한 하둡 분산 파일시스템(Hadoop Distributed File System, HDFS)과 데이터 처리를 위한 맵리듀스가 그것이다.

HDFS는 개발자에게 친숙한 유닉스 파일시스템의 명령어(ls, rm, cp)로 파일을 관리할 수 있으며, 파일이 저장된 물리적 서버의 위치를 사용자가 알지 못한다.

HDFS 아키텍처
HDFS의 구조는 크게 네임노드(NameNode)와 데이터노드(DataNode)로 나뉘며, 노드는 실제 서버라고 생각하면 쉽다. 데이터노드에는 실제 물리적인 데이터가 저장되고 64MB 또는 128MB 블록 사이즈로 관리된다. 데이터노드의 블록은 모두 3개 이상의 복제본이 각 노드에 복사 및 저장되며, 만약 파일에 문제가 발생하면 즉시 복제본으로 대체돼 서비스가 중단되지 않는 이점이 있다. 장애상황은 항상 발생한다는 가정 하에 설계된 HDFS의 특징 덕분이다.


< 그림 2> HDFS 구조 및 동작 방식

네임노드는 디렉터리 구조, 파일목록 등 데이터노드에 저장된 모든 데이터에 대한 정보를 가지고 있다. 그러므로 네임노드의 데이터 손실은 곧 치명적이기 때문에 하둡에서는 보조네임노드를 둬 네임노드의 백업 솔루션을 제공한다. 그러나 이는 실시간 복구는 아니기 때문에 네임노드에 장애가 발생할 경우 불가피하게 서비스의 중단이 일어날 수 있다. 다행히도 하둡 2.0에서는 여러 개의 보조 네임노드를 생성할 수 있어 네임노드에 장애가 발생해도 서비스가 중단된지 않는다.

앞서 언급했듯 HDFS는 유닉스 파일시스템과 유사한 명령어를 채택해 쉽게 디렉터리를 탐색하고 파일을 읽을 수 있다. 예컨대 하둡 서버의 쉘 커맨드에 ‘hadoop fs -ls hdfs://namenode: 54310/root’ 명령어를 실행하면 하둡의 /root 디렉터리 내의 모든 파일과 디렉터리 목록을 출력할 수 있으며, 이와 유사하게 ‘hadoop fs -cat hdfs://namenode:54310/root/test.txt’를 실행하면 /root/test.txt 파일의 내용이 문자열로 화면에 출력된다. 여기서 ‘namenode’는 네임노드가 설치된 서버나 주소, 호스트명이며, ‘54310’은 네임노드의 서비스 포트다. 

HDFS에 ls 명령으로 특정 디렉터리 목록을 요청할 경우 해당 정보를 가지고 있는 네임노드가 목록을 바로 반환한다(<그림 2> ①, ②번 참조).

그러나 cat와 get 명령(하둡의 경우 hadoop fs -cat 또는 hadoop fs -get)으로 특정 파일에 대한 노드상의 위치를 네임노드에 요청하면 물리적인 데이터 입출력을 관리하는 데이터노드가 결과를 반환한다(<그림 2> ③, ④번 참조).

또한 ‘hadoop fs -copyFromLocal test1.txt /root/test1.txt’ 명령어로 로컬PC의 test1.txt 파일을 HDFS의 /root/test1.txt에 쓸 수 있다. 이 경우 클라이언트에서 HDFS 네임노드에 파일을 생성할 위치와 함께 명령어를 전달하면, 파일 생성 후 네임노드가 지정한 데이터노드에 실제로 파일이 생성된다(<그림 2> ⑤, ⑥번 참조). 파일이 생성되면 데이터노드는 이 파일의 복제본을 생성하고(<그림 2> ⑦번 참조) 작업이 종료됐음을 네임노드에 알리면 HDFS 상에서의 파일 저장 과정이 모두 완료된다(<그림 2> ⑧번 참조).

맵리듀스 아키텍처
맵리듀스로 프로그램을 개발할 때에는 입력값으로 <key, value>을 대입하고 출력 또한 <key, value>로 설정한다.

(입력 : <k1, v1>) → 맵 함수 → <k2, v2> → 컴바이너(combiner) 함수 → <k2, v2> → 리듀스(reduce) → (출력 : <k3, v3>)

입력값을 전달받은 맵 함수는 이를 중간값으로 변환하고, 리듀스 함수를 거쳐 최종적인 출력값이 생성되며, 이후 맵리듀스 프레임워크 기반의 프로그램에서 이 출력값을 반환받을 수 있다. 맵 합수를 실행하는 매퍼(Mapper)는 데이터가 존재하는 각각의 노드(서버)에서 실행된 후 매퍼의 결과가 1개의 리듀서에서 병합된다는 점에 유념해야 한다.

매퍼가 각 노드에서 분산 처리되는 것은 맵 함수가 연산을 처리할 때 다른 노드에서 데이터를 받는 과정 간에 발생할 수 있는 네트워크 부하와 처리시간 지연을 방지하기 위해서다.

맵 함수와 리듀스 함수의 개념을 좀더 확실히 이해하기 위해 간단한 예를 준비했다.

‘Hello World Bye World’ 문장과 ‘Hello Hadoop Goodbye Hadoop’ 문장에서 단어를 추출하고 중복되는 단어를 카운트하는 맵리듀스 프로그램을 실습함으로써 맵 함수와 리듀스 함수로 이어지는 각 단계의 결과물을 살펴보자. 중복된 단어를 카운트하기 위해서 StringTokenizer를 이용해 공백을 기준으로 단어를 분리했다.

‘Hello World Bye World’를 분석한 맵 함수의 결과값은 <리스트 1>이며, 여기서 <k, v> 상의 k는 StringTokenizer로 파싱한 문자열이고, v 값은 반복되는 정수형 값이다.

 

<리스트 1> 첫 번째 맵 함수 출력결과 <Hello, 1>
<World, 1>
<Bye, 1>
<World, 1>

 

<리스트 2>는 ‘Hello Hadoop Goodbye Hadoop’을 분석한 맵 함수의 결과이며, 앞선 결과와 같이 k는 StringTokenizer로 파싱한 문자열이고 v 값은 반복되는 정수형 값이다.

 

<리스트 2> 두 번째 맵 함수 출력결과<Hello, 1>
<Hadoop, 1>
<Goodbye, 1>
<Hadoop, 1>

 

맵 함수가 처리한 결과를 컴바이너 함수로 각각 병합한 결과는 <리스트 3>과 같다.

 

<리스트 3> 컴바이너 함수 출력 결과
- 첫 번째 맵의 결과
<Hello, 1>
<Bye, 1>
<World, 2>

- 두 번째 맵의 결과
<Hello, 1>
<Hadoop, 2>
<Goodbye, 1>

 

<리스트 3>에서 ‘World’와 ‘Hadoop’은 중복 단어이며 컴바이너 함수로 병합됨에 따라 두 단어의 value가 2로 증가됐다. 컴바이너 함수의 결과를 리듀스 함수를 통해 최종 출력값을 구한 결과는 <리스트 4>와 같다.

 

<리스트 4> 리듀서 함수로 구한 최종 출력값<Hello, 1>
<Bye, 1>
<World, 2>
<Hadoop, 2>

 

지금까지 맵리듀스 아키텍처의 동작 흐름을 아파치 하둡의 맵리듀스 가이드의 ‘Wordcount.java’를 실제로 실행하며 개략적으로 살펴봤다. 이제 맵 함수를 동작시키는 매퍼와 리듀서가 어떻게 맵리듀스 프레임워크상에서 동작하는지 보다 상세한 아키텍처와 동작 흐름을 살펴보자.

맵리듀스 기반의 임의 프로그램을 개발하고 jar 확장자의 이 프로그램을 하둡 환경에서 <리스트 5>처럼 실행시키자.

 

<리스트 5> wordcount.jar 프로그램 실행
hadoop jar /usr/joe/wordcount.jar org.myorg.WordCount /usr/joe/wordcount/input/usr/joe/wordcount/output

 

<리스트 5>에서 ‘/usr/joe/wordcount.jar’는 맵리듀스 프로그램을 jar로 압축한 파일이며, ‘org.myorg.WordCount’는 실행할 클래스명, ‘/usr/joe/wordcount/input/usr/joe/wordcount /output’은 결과물이 저장될 디렉터리다. 자세한 설명에 앞서 org.myorg.WordCount의 main 함수를 살펴보자(<리스트 6> 참조).

 

<리스트 6> org.myorg.WordCount의 main 함수public static class Map extends MapReduceBase
  implements Mapper<LongWritable, Text, Text, IntWritable> {
 public void map(LongWritable key, Text value,
  OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
  // 맵 함수 구현
 }
}

public static class Reduce extends MapReduceBase
 implements Reducer<Text, IntWritable, Text, IntWritable> {
  public void reduce(Text key, Iterator<IntWritable> values,
  OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
  // 리듀스 함수 구현
  }
}
public static void main(String[] args) throws Exception {
  JobConf conf = new JobConf(WordCount.class);
  conf.setJobName("wordcount");
  // 중간 생략…
  FileInputFormat.setInputPaths(conf, new Path(args[0]));
  FileOutputFormat.setOutputPath(conf, new Path(args[1]));

  JobClient.runJob(conf);
}

 

<리스트 6>의 마지막 줄의 ‘JobClient.runJob(conf)’가 수행되면 <그림 3>에서 잡 클라이언트가 잡을 제출한다(①번 액션). 제출된 잡을 네임노드의 잡 트래커에서 수행을 요청하면 잡 트래커는 잡을 큐에 넣고 순차적으로 잡을 각 데이터노드에 설치된 태스크 트래커에게 할당한다(②번 액션).

잡 트래커는 org.myorg.WordCount 클래스에 정의된 전체 잡을 관리한다. 앞서 살펴본 매퍼와 리듀서는 각 1개의 태스크로 처리되며, 태스크 트래커가 이 매퍼와 리듀서 태스크의 수행을 관리한다. 

예컨대 잡 트래커는 매퍼가 각각의 노드에서 수행된 후 가장 늦게 처리된 매퍼의 작업이 끝나면 리듀서 태스크를 실행시키는 역할을 담당하며, 태스크 트래커는 각각의 태스크의 상태를 모니터링하고 만약 태스크 처리 중 에러가 발생하면 태스크를 다시 수행한다.

빅데이터 시대, 끊임없이 발전하는 하둡
스마트 기기와 소셜 미디어 등으로 비정형 데이터가 증가하며 비즈니스 산업의 경쟁 규칙조차 바뀌고 있다. 빅데이터는 더 이상 피할 수 없는 시대적 흐름이며, 이를 적극적으로 활용할 때 새로운 가치를 창출하고 시대를 앞서나갈 수 있다. 빅데이터 시대를 이끌고 있는 하둡은 7년간 개발돼 온 개방형 프레임워크로, 최근 하둡의 도입 성과가 가시화되고 다양한 프로젝트가 진행되면서 하둡을 중심으로 한 새로운 생태계가 조성되고 있다.


< 그림 3> 맵 리듀스 프레임워크의 아키텍처와 동작 방식

피그(pig), 하이브 등 하둡의 단점을 보완하는 보조 툴이 등장하며 하둡의 단점이 보완되고 있고, 데이터 분석 시 작업 효율성을 증대시킬 수 있는 아파치 우지(Apache Ooize) 등의 툴도 속속 등장하고 있다. 점차 작업 효율성과 개발 편의성을 증대시킬 하둡 기반의 다양한 툴이 등장할 것으로 예상된다.

사실 하둡은 빅데이터의 저장과 병렬처리에 치우쳐 기존 데이터마이너나 분석 전문가가 접근하긴 어려웠다. 그러나 이런 약점을 개선하기 위한 노력도 계속되고 있다. 예컨대 아파치 마하웃(Apache Mahout) 프로젝트는 마이닝 알고리즘을 하둡 프레임워크상에서 구현하고 오픈소스로 공유하기 위해 개발됐다. 현재 0.7 버전이 릴리즈됐으며, 일각에서는 하둡 기반의 오픈소스 통계언어인 R과의 연동을 위해 노력 중이다.

특히 작년부터는 MS나 오라클, SAS, IBM 등의 글로벌 솔루션 업체가 자사 솔루션에 하둡을 포함시킬 것이란 소식도 들리고 있다. 따라서 하둡의 쓰임이 점차 늘어나고 하둡을 여러 분야나 솔루션에 적용하고자 하는 노력은 지속될 전망이다.

| | 목록으로