nqky Flipbook PDF

nqky
Author: 

104 downloads 163 Views 10MB Size

Recommend Stories


Porque. PDF Created with deskpdf PDF Writer - Trial ::
Porque tu hogar empieza desde adentro. www.avilainteriores.com PDF Created with deskPDF PDF Writer - Trial :: http://www.docudesk.com Avila Interi

EMPRESAS HEADHUNTERS CHILE PDF
Get Instant Access to eBook Empresas Headhunters Chile PDF at Our Huge Library EMPRESAS HEADHUNTERS CHILE PDF ==> Download: EMPRESAS HEADHUNTERS CHIL

Story Transcript

신뢰성과 확장성을 갖춘 분산 시스템을 구축하고 관리하는 방법 H a d o o p

T h e

D e f i n i t i v e

데이터의 숨겨진 힘을 끌어내는 최고의 클라우드 컴퓨팅 기술

G u i d e

프로젝트 예제와, 헬스케어 시스템과 유전체 분석 사례가 새로이 추가되었다. 대규모 데이터셋을 분석하 는 개발자와 하둡 클러스터를 구축하고 실행하는 시스템 관리자를 위한 최고의 지침서다.

•맵리듀스, HDFS, YARN

•하둡 클러스터 관리 및 설정

•애플리케이션 개발

•에이브로로 데이터 직렬화하기

•피크, 하이브, 크런치, 스파크

•파케이로 중첩 데이터 처리하기

•분산 데이터베이스 HBase

•플룸으로 데이터 수집하기

•분산 설정 서비스 주키퍼

•스쿱으로 데이터 일괄 전송하기

4판

여러분은 진정한 고수에게서 하둡의 기술적인 측면뿐만 아니라 상식적이고 일반적인 개발 방법까지도

Hadoop The Definitive Guide

의 바이블로 손꼽히는 책으로서, 이번 4판에서는 하둡 2.0 기반 YARN과 파케이, 플룸, 크런치, 스파크

하둡 완벽 가이드

하둡은 신뢰성과 확장성을 갖춘 분산 시스템을 구축하고 관리하는 최선의 선택이다. 이 책은 하둡 분야

배울 기회를 얻었습니다. 더그 커팅, 하둡 창시자, 클라우데라

오픈스택 인 액션

클라우드 시스템을 관리하는 기술

처음 시작하는 AWS 람다

예제 소스 www.hanbit.co.kr/src/2459

톰 화이트 지음

장형석, 장정호, 임상배, 김훈동 옮김

관련 도서

하둡 완벽 가이드

4판

시스템 관리 / 클라우드

93000

9 788968 484599

ISBN 978-89-6848-459-9

정가 55,000원

톰 화이트 지음 장형석, 장정호, 임상배, 김훈동 옮김

| 표지 설명 | 이 책의 표지에 그려진 동물은 아프리카 코끼리다. 아프리카 코끼리는 지구에 서 가장 큰 육지 동물이고(사촌격인 아시아 코끼리보다도 조금 더 크다), 아 시아 대륙의 코끼리와도 약간 닮았는데, 귀를 통해 구별할 수 있다. 수컷은 키 가 어깨까지 12피트고 무게는 12,000파운드에서 15,000파운드에 달한다. 반면에 암컷은 키가 10피트고 무게는 8,000파운드에서 11,000파운드에 달 한다.

하둡 완벽 가이드(4판) 데이터의 숨겨진 힘을 끌어내는 최고의 클라우드 컴퓨팅 기술 초판1쇄발행 2017년 3월 1일 지은이 톰 화이트 / 옮긴이 장형석, 장정호, 임상배, 김훈동 / 펴낸이 김태헌 펴낸곳 한빛미디어 (주) / 주소 서울시 마포구 양화로7길 83 한빛미디어(주) IT출판부 전화 02 – 325 – 5544 / 팩스 02 – 336 – 7124 등록 1999년 6월 24일 제10 – 1779호 / ISBN 978 – 89 – 6848 – 459 – 9 93000 총괄 전태호 / 책임편집 김창수 / 기획 최현우 / 교정·조판 김철수 디자인 표지 김연정, 내지 여동일 영업 김형진, 김진불, 조유미 / 마케팅 박상용, 송경석, 변지영 / 제작 박성우, 김정우 이 책에 대한 의견이나 오탈자 및 잘못된 내용에 대한 수정 정보는 한빛미디어(주)의 홈페이지나 아래 이메일로 알려주십시오. 잘못된 책은 구입하신 서점에서 교환해드립니다. 책값은 뒤표지에 표시되어 있습니다. 한빛미디어 홈페이지 www.hanbit.co.kr / 이메일 [email protected] © 2017 Hanbit Media, Inc.

Authorized Korean translation of the English edition of Hadoop: The Definitive Guide, Fourth Edition, ISBN 9781491901632 © 2015 Tom White This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same. 이 책의 저작권은 오라일리와 한빛미디어(주)에 있습니다. 저작권법에 의해 한국내에서 보호를 받는 저작물이므로 무단전재와 복제를 금합니다.

지금 하지 않으면 할 수 없는 일이 있습니다. 책으로 펴내고 싶은 아이디어나 원고를 메일 ( [email protected] ) 로 보내주세요. 한빛미디어(주)는 여러분의 소중한 경험과 지식을 기다리고 있습니다.

하둡 완벽 가이드

4판

지은이·옮긴이 소개

지은이

톰 화이트 Tom White

2007년 2월부터 아파치 하둡 커미터가 되었고, 이후 아파치 소프트웨어 재단의 일원이 되었다. 현재 하둡에 대한 지원과 트레이닝을 제공하는 회사인 클라우데라에서 일하고 있다. 그전에는 독립적인 하둡 고문으로서 하둡을 설치, 사용, 확장하려는 회사와 일했다. 그는 oreilly.com,

java.net, IBM developerWorks에 수많은 글을 썼으며 몇몇 컨퍼런스에서 하둡에 관해 연 설했다. 톰은 케임브리지 대학교에서 수학 학사학위를 취득하고, 영국 리즈 Leeds 대학교에서 과 학 철학 석사학위를 취득하였다.

옮긴이

장형석 [email protected]

국민대학교 빅데이터경영MBA 과정 겸임교수. 1996년 공군사관학교에서 기상예보장교로 실 무를 시작했다. 전역 후 닷컴솔루션이란 회사를 창업하고 자연어 처리, 검색 엔진, 그룹웨어, ERP 솔루션을 개발했다. 2012년부터는 회사를 정리하고 국내 1호 빅데이터 대학원인 충북대학교 비즈니스데이터융합학과의 교수로 부임하여 분산 병렬 처리(하둡), 데이터 마이닝과 머신러닝 (스파크), 시각화 과목을 맡고 있다. 현재 국민대학교 빅데이터경영MBA 과정 겸임교수와 연세 대학교 데이터사이언스 과정 외래교수를 맡고 있으며 숙명여대, 한국생산성본부, 삼성SDS 등 다수의 대학교 및 기업에 출강하고 있다.

옮긴이

장정호 [email protected]

네이버 검색 소프트웨어 엔지니어. 2006년에 티맥스에서 애플리케이션/시스템 간 데이터 전송 시스템 개발을 시작으로 다음 커뮤니케이션에서 데이터 마이닝 업무를 했고, SAP에서 칼럼 기 반의 인메모리 RDBMS인 HANA 개발에 동참했으며, 그 후 빅데이터 저장/분석 시스템 영역에 관한 연구를 통해 네이버에서 데이터 분석 시스템 개발을 담당하고 있다.

4

옮긴이

임상배 [email protected]

Principal Sales Consultant. 한국오라클 Core Tech 본부 빅데이터 팀에서 빅데이터 솔루 션 컨설팅 업무를 하고 있으며 하둡, 스파크, R 기반의 오픈 소스 기술을 활용한 솔루션과 데이 터 가상화 솔루션을 담당하고 있다. 빅데이터 처리 및 분석을 주제로 대학, 협회, 기업 등에서 강 의를 하고 있다. 오라클에 입사하기 전에는 한국사이베이스에서 금융, 통신, 제조, 공공 등 다양 한 분야에서 데이터 웨어하우스, 복합 이벤트 처리, 엔터프라이즈 아키텍처 모델링 솔루션 컨 설팅 업무를 했고, 현대정보기술에서는 정보계 시스템 구축 프로젝트를 수행했으며, 비트컴퓨 터에서는 분석 플랫폼 개발을 했다.

옮긴이

김훈동 [email protected]

신세계 SSG.COM 빅데이터 팀 리더. 연세대학교에서 컴퓨터공학을 전공하고, 빅데이터 및

NoSQL로 석사학위를 받았다. 21살이었던 대학교 3학년 때 처음으로 벤처기업을 창업했다. 총 두 번의 벤처기업을 창업했으며, 두 번째 회사는 챗봇 관련 대화 에이전트 회사였다. 석사과정 중 빅데이터 세계에 입문한 이후 커다란 데이터를 찾아 현재의 신세계그룹에 입사했고 이마트 및 신세계백화점의 온오프 유통 데이터를 수집, 분석하고 기계학습을 적용하는 업무를 리딩하고 있다. 한국 스파크 사용자 모임과 하둡, 스파크, 머신러닝 분야의 한국 마이크로소프트

MVP로 활동하고 있다. 최근에는 딥러닝 NLP 분야의 오픈 소스 연구에 참여하고 있다.

5

추천의 글

하둡은 오픈 소스 검색 엔진인 너치 Nutch 에서 시작되었다. 오픈 소스 웹 검색 엔진을 구축하려고 노력했던 우리는 소수의 컴퓨터에서 연산을 실행할 때조차 문제가 생겨 어려움을 겪었다. 하지 만 구글이 GFS와 맵리듀스 논문을 발표했고, 우리는 그 논문에서 해결책을 찾을 수 있었다. 구 글은 너치가 가진 문제를 명확히 해결할 수 있는 시스템들을 새로 고안해냈다. 그래서 우리 중 두 명은 이들 시스템을 너치의 일부로 다시 구성하기 시작했다. 우리는 20대의 컴퓨터로 너치의 문제를 어느 정도 해결해나갔다. 하지만 엄청난 규모의 웹 데이 터를 처리하기 위해서는 수천 대의 컴퓨터가 필요하다는 것을 곧 깨닫게 되었다. 게다가 비전업 개발자 두 명이 이러한 일을 처리하는 것은 거의 불가능했다. 그 무렵 야후는 이 문제에 대해 관심을 가지고 되었고, 내가 속한 팀을 재빨리 합류시켰다. 우리 는 하둡이라 불리는 너치의 분산 컴퓨팅 팀으로 분리되었다. 야후의 도움으로 하둡은 엄청난 규 모의 웹을 처리하는 기술로 빠르게 성장할 수 있었다.

2006년에 톰 화이트가 하둡에 공헌하기 시작했다. 나는 그가 너치에 대해 쓴 훌륭한 기사를 이 미 읽어봤기 때문에 복잡한 아이디어를 명확하게 해결해줄 수 있을 것으로 여겼다. 톰이 그가 쓴 기사만큼 훌륭한 소프트웨어를 머지않아 개발할 것으로 기대했다. 사용자와 프로젝트에 대한 톰의 관심은 시작부터 남달랐고 하둡의 발전에 큰 기여를 했다. 다른 오픈 소스 개발자와 달리 톰은 자신이 원하는 시스템을 만드는 것이 아니라 다른 사람이 쉽게 사 용할 수 있는 시스템을 만드는 데 중점을 두었다. 초기에 톰은 아마존의 EC2와 S3 서비스에서도 제대로 동작하는 하둡을 만드는 전문적인 기술 을 가지고 있었다. 그 후 맵리듀스 API의 개선, 웹사이트 강화, 객체 직렬화 프레임워크의 고안 과 같은 다양한 주제의 문제를 해결하기 위해 노력했다. 그는 모든 면에서 자신의 생각을 구체적 으로 표현했다. 그는 하둡 커미터의 역할을 맡게 되었고, 얼마 지나지 않아 하둡 프로젝트 관리 위원회의 위원이 되었다.

6

톰은 현재 존경받는 하둡 개발자 커뮤니티의 회원이다. 프로젝트의 다양한 기술 분야에서 전문 가로서, 특히 쉽게 사용하고 이해할 수 있는 하둡을 만들기 위해 노력하고 있다. 이런 점 때문에 나는 톰이 하둡에 관한 책을 쓴다고 했을 때 매우 기뻤다. 그보다 더 적합한 사람 은 없다. 여러분은 진정한 고수에게서 하둡의 기술적인 측면뿐만 아니라 상식적이고 일반적인 개발 방법까지도 배울 기회를 얻었다. _더그 커팅 2009년 4월, 캘리포니아의 마당에 있는 창고에서

7

옮긴이의 말

대륙간탄도미사일인 ICBM으로 불리기도 하는 사물인터넷, 클라우드, 빅데이터, 모바일은 최 신 IT 트렌드를 대표하는 용어다. 2010년부터 2014년까지 5년간 IT의 핫이슈였던 빅데이터는 이제 사물인터넷, 인공지능, 무인자동차, 4차 산업혁명 등 새로운 트렌드의 등장으로 대중의 열 렬한 관심에서 점차 멀어지는 듯 보인다. 하지만 빅데이터 분야는 수집, 저장, 처리, 분석, 시각 화, 서비스까지 일련의 단계를 모두 거쳐야 빅데이터의 목적인 새로운 가치를 창출할 수 있다. 이 과정에서 데이터를 생성하는 사물인터넷, 데이터를 저장하는 클라우드, 데이터를 처리하고 분석하는 빅데이터, 분석한 결과를 서비스하는 모바일까지 ICBM의 네 분야를 서로 융합하지 않으면 아무런 가치도 발생하지 않는다.

2005년 더그 커팅이 오픈 소스로 공개한 하둡은 분산 저장 파일시스템인 HDFS와 분산 병 렬 처리를 담당하는 맵리듀스로 구성되어 있다. 하둡이 나온 후 이를 기반으로 피그, 하이브,

HBase, 스쿱, 플룸 등의 오픈 소스 기술이 등장했고, 이들을 모두 결합한 빅데이터 기술을 통 칭하여 하둡 에코시스템이라고 부르게 되었다. 최근에는 스파크의 등장으로 대용량 데이터를 저장하고 일괄 처리하는 수준에서 벗어나 머신러닝과 실시간 분석까지 아우르게 되었다. 『하둡 완벽 가이드』는 ‘빅데이터 기술의 바이블’이라 불리는 책이다. 이 책을 통해 빅데이터를 처음 배우는 사람들은 운이 좋은 것이다. 이 책을 저술한 톰 화이트는 2007년부터 아파치 하둡 의 커미터로 활동했고 클라우데라에서 일하고 있다. 개별 기술을 아는 사람은 많지만 수많은 기 술을 하나로 묶을 수 있는 전문가는 많지 않다. 하둡만을 다루는 책은 많지만 『하둡 완벽 가이드』 와 같이 하둡 에코시스템 전체를 다루는 책은 거의 없다. 숲을 먼저 보고 나무를 보자. 『하둡 완 벽 가이드』는 각 기술을 완벽하게 설명하지는 않는다. 그렇다고 대충 설명하는 것도 아니다. 톰 화이트는 이 책을 통해 각 기술의 핵심을 설명했고, 다른 기술과의 관계도 친절하게 설명하고 있다. 이제 직접 번역한 좋은 책이 하나 더 생겼다. 자랑스럽게 추천할 책이 있다는 것은 학자로서 큰 기쁨이다. 빅데이터를 배우려고 찾아왔던 많은 학생이 생각나는 하루다. 제자들과 앞으로 만나 게 될 인연 그 사이에 이 책이 있었으면 좋겠다. 빅데이터 대한 열정과 희망을 가진 모든 분께 감

8

사드린다. 함께 한 시간과 함께 할 수 있는 시간에 감사드린다. 마지막으로, 지칠 만하면 더욱 열 심히 공부하라고 지켜보는 따뜻한 눈길에 항상 감사드린다. _장형석 눈이 내리는 추운 겨울 어느 날 구로의 한 PC방에서...

하둡 0.1.0 버전이 2006년에 릴리즈되고, 이제 10년이 넘어가면서 기술적으로 더욱 성숙해지 고 안정된 것을 느낀다. 하둡은 거대한 데이터를 분산시켜 저장할 수 있는 HDFS와 이렇게 저장된 데이터를 분석할 수 있는 맵리듀스라는 핵심 컴포넌트로 구성되어 있다. 이제는 이 기술들이 하둡에만 머무는 것이 아니라 맵리듀스의 분산 처리 개념을 근간으로 하는 스파크와 같은 분산 데이터 처리 기술을 통 해 HDFS에 존재하는 데이터 분석이 가능해졌으며, 계속해서 새로운 데이터 처리 기법과 시스 템들이 파생되고 있다. 이렇게 다양한 시스템이 등장하면서 데이터의 특성이나 분석 기법에 적 합한 여러 시스템이 공존하게 되었고 전반적인 시스템의 복잡도가 증가했지만 분산 데이터의 저 장과 처리의 뿌리는 하둡임을 알고 하둡에 대한 완벽한 이해를 바탕으로 한다면 아무리 복잡한 시스템이더라도 어렵지 않게 활용할 수 있으리라 믿는다. 빅데이터 초창기에는 ‘하둡을 통해 데이터 저장만 하면 무슨 의미가 있나? 이러한 빅데이터에서 가치를 찾아내는 것이 더 중요하다. 그리고 데이터에서 통찰력을 얻고 가치를 뽑아내는 것은 기 존의 스몰데이터로도 충분하다’는 얘기도 있었다. 저장하더라도 어떻게 분석해야 할지 몰라서 데이터를 모으는 것조차 망설였던 회사들이 많았 다. 하지만 지금은 하둡을 이용해서 빅데이터를 저장하는 데 동참하지 않은 회사들이 뒤늦게 이 에 대한 가치를 깨닫고 합류하고 있다. 특히 알파고의 등장으로 전 세계에서 인공지능과 딥러닝 에 대한 관심이 높아지면서 학습할 데이터를 미리 구축하지 않은 회사들은 땅을 치고 후회하고 있다.

9

인공지능에서 경쟁우위를 차지하려면 학습에 필요한 양질의 데이터를 얼마나 많이 보유하고 있 느냐가 중요하기 때문이다. 앞으로 하둡은 이러한 분석 기술들의 발전과 함께 더더욱 중요한 역 할을 할 것이며, 따라서 이 책은 훌륭한 분석 결과나 서비스를 얻으려고 하는 누구나 기본적으로 알아야 할 하둡을 이해하기에 매우 적합하다는 생각이 든다. 끝으로 이 책을 번역하면서 옆에서 함께 여러모로 고생해준 사랑하는 아내와 딸 세아에게 고마 움을 전한다. _장정호

2년마다 데이터 크기가 두 배로 증가하면서 많은 기업이 대규모의 정형 및 비정형 데이터를 관 리 및 분석해야 하는 상황에 처해 있다. 관계형 테이블 내에서 모델링하고 저장할 수 있는 기존 기업 데이터와 달리 오늘날의 데이터는 웹 페이지, 소셜 미디어 사이트, 이메일 교환, 검색 인덱 스, 클릭 스트림, 장비 센서, 그리고 오디오, 비디오 및 사진을 포함한 모든 유형의 멀티미디어 파일 등 다양한 형태로 나타나고 있다. 이러한 대량의 데이터로부터 안정적으로 수집, 저장 및 처리하고 분석 기술을 사용해서 숨겨진 패턴을 밝혀내고, 전략적 통찰력을 얻고, 가치를 창출하 는 것은 기업의 발전을 좌우할 당면 과제다. 이를 해결하기 위한 방안으로 빅데이터 기술이 IT의 큰 화두가 되었다. 국내에는 2012년 하반 기를 시작으로 빅데이터에 대한 관심이 높아졌고 많은 프로젝트에서 빅데이터 표준 플랫폼으로 하둡을 선택했다. 또한 다양한 하둡 기반 생태계의 기능이 실제 업무에 도입되고 있다. IT 분야 에서 데이터를 다루는 업무를 수행하고 있는 17년 동안 하둡처럼 엔터프라이즈 환경에 빠르게 융합되는 플랫폼은 없었다. 요즘 IT분야에서 사용되는 기술을 살펴보면 개방형 개발 및 진화의 특성을 지닌 오픈 소스 소프트웨어와 전통적인 기존 벤더의 소프트웨어가 상호 간에 좋은 영향 을 주며 서로의 장점을 적극적으로 수용하는 구조로 발전하고 있으며, 앞으로의 발전에 더 큰 기 대를 하게 된다.

10

최근 스파크에 대한 관심이 높아지면서 이 분야를 처음 시작하는 분들이 ‘하둡을 공부해야 하나’ 라는 질문을 많이 한다. 하둡은 이미 특정 요소 기술이 아닌 데이터 플랫폼으로 인정되어 다양한 분야의 기업현장에서 사용하고 있다. 엔터프라이즈급의 안정적인 분산 파일시스템과 클러스터 관리자의 역할 및 이를 지원하는 다양한 생태계 시스템은 하둡이 가지고 있는 큰 가치다. 하둡과 스파크는 상호 보완하는 관계로, 빅데이터 관련 IT 개발/운영 및 기획에 관심이 있다면 하둡에 대한 지식을 쌓는 것은 많은 도움이 되리라 생각한다. 주말마다 카페에 나가 번역 작업을 해서 아이들 돌보느라 고생을 한 아내 임진우에게 정말 고맙 고 사랑한다는 말을 전한다. 그리고 그동안 잘 놀아주지도 못했는데 항상 아빠를 이해해주는 세 상에서 가장 예쁜 두 딸 도연, 서현에게 고마움을 전한다. 그동안 많은 어려움에도 이 책이 나오 도록 아낌없는 노력을 해주신 한빛미디어의 최현우 차장님께도 감사의 말씀을 드린다. 마지막 으로 오라클에서 ‘빅데이터’를 할 수 있도록 운명과 같은 기회를 주신 양수환 전무님, 회사에서 항상 든든한 지원과 자기 개발의 기회를 주시는 한국오라클 장성우 전무님께 깊은 감사의 말씀 을 드린다. _임상배 데이터 기반 시스템의 비상을 바라며

11

이 책에 대하여

수학 및 과학 분야의 작가인 마틴 가드너 Martin Gardner 는 인터뷰에서 다음과 같이 말했다. 미적분학으로 넘어가면 뭐가 뭔지 모르겠다. 이것이 바로 내 칼럼이 성공한 비결이다. 대 부분의 독자들이 쉽게 이해할 수 있는 글을 쓰는 방법을 알면서 글을 쓰고 있었다는 사실 을 이해하는 데까지 오랜 시간이 걸렸다.1 여러 면에서 이 글은 하둡에 대한 나의 느낌을 잘 설명해준다. 하둡의 내부 작동 방식은 매우 복 잡하다. 그 이유는 분산 시스템 이론, 응용 공학, 상식이 혼합되어 있기 때문이다. 초보자에게 하 둡은 괴물처럼 보일 것이다. 그러나 하둡은 이러한 것을 이해할 필요가 없다. 핵심을 알고 나면 빅데이터를 처리하기 위해 하 둡이 제공하는 도구들이 단순해진다. 공통된 주제가 있다면 그것은 시간과 기술이 없고 인프라 를 구축할 수 있는 분산 시스템 전문가가 될 의향이 없는 프로그래머가 대용량 데이터를 저장하 고 분석할 수 있는 구성요소를 생성할 수 있도록 추상화 수준을 높이는 방법과 관련된 것이다. 내가 하둡을 처음 사용했을 때는 비교적 단순하고 일반적으로 적용할 수 있는 특성이 보였기 때 문에 하둡이 널리 활용될 것으로 확신할 수 있었다. 하지만 2006년 초에는 설치, 설정, 하둡을 이용한 프로그램의 작성이 거의 예술 수준이었다. 그 후 엄청난 발전이 있었다. 문서화가 이루어 지고 예제도 많아졌고 질문에 답을 주는 메일링 리스트도 활발해졌다. 하지만 아직까지도 입문 자는 이 기술로 할 수 있는 것과 최적의 활용 분야와 사용 방법을 이해하는 데 큰 어려움을 겪고 있다. 이것이 바로 내가 이 책을 쓴 동기다. 아파치 하둡 커뮤니티는 지금까지 많은 진전을 이루었다. 이 책의 초판을 발행한 이후에도 많은 하둡 프로젝트가 생겨났다. ‘빅데이터’는 누구나 아는 용어가 되었다.2 현재 이 소프트웨어는 채 택 가능성, 성능, 신뢰성, 확장성, 관리성이 크게 향상되었다. 하둡 플랫폼에서 구현되고 실행되

1 알렉스 벨로스(Alex Bellos)의 「즐거운 과학(The science of fun )」( http://bit.ly/science_of_fun )(가디언, 2008년 5월 31일) 2 2013년 옥스퍼드 영어 사전( http://bit.ly/6_13_oed_update )에 빅데이터가 추가되었다.

12

는 소프트웨어 개수는 비약적으로 증가했다. 사실 하둡은 한 사람이 모두 따라가기 힘들다. 하 둡이 더 널리 퍼지기 위해서는 지금보다 더 사용하기 쉬워져야 한다고 생각한다. 더 많은 도구, 더 많은 시스템과의 통합, 새롭고 개선된 API 작성이 필요하다. 나는 이 일의 일부를 맡고자 한 다. 그리고 나는 이 책이 이러한 일을 하는 다른 사람들에게 도움이 되길 바란다.

소스 코드 이 책에서 특정 자바 클래스는 복잡성을 줄이기 위해 패키지 이름을 생략했다. 해당 클래스가 포 함된 패키지는 아파치 하둡 홈페이지3에 링크된 하둡용 자바 API 문서나 관련 프로젝트에서 쉽 게 찾을 수 있다. 일반적인 규칙에서는 벗어나지만 동일한 패키지에서 여러 클래스를 임포트하는 프로그램은 별 (* ) 문자를 사용하여 코드를 줄였다(예를 들면 import org.apache.hadoop.io.* ). 이 책의 예제 프로그램은 이 책의 홈페이지와 깃허브, 한빛미디어 웹페이지에서 내려받을 수 있다. http://hadoopbook.com/



https://github.com/tomwhite/hadoop-book/



http://www.hanbit.co.kr/src/2459



홈페이지에서는 이 책의 예제에서 사용된 데이터셋을 얻는 방법과 책에 있는 프로그램을 실행 하기 위한 주의사항 및 변경 내역, 추가 자료, 개인 블로그의 링크도 찾을 수 있다.

3 http://hadoop.apache.org/

13

4판의 새로운 내용 4판은 하둡 2 버전만 다룬다. 하둡 2 버전은 현재 가장 활발히 개선되고 있으며 가장 안정된 버 전이다.

YARN (4장), 파케이(13장), 플룸(14장), 크런치(18장), 스파크(19장)를 다루는 새로운 장 이 추가되었다. 독자들이 이 책을 읽는 다양한 순서를 알려주는 절도 포함되었다. 또한 새로운 두 가지 사례 연구를 포함한다. 헬스케어 시스템의 하둡 사용법은 22장, 유전체 데 이터를 처리하기 위한 하둡 기술은 23장에서 다룬다. 이전 판에서 소개했던 사례 연구는 웹사이 트4에서 확인할 수 있다. 하둡의 최신 버전과 관련 프로젝트에 대한 내용을 반영하기 위해 기존에 있었던 장의 내용도 많 이 고쳐지고 변경되고 개선되었다.

3판의 새로운 내용 3판은 아파치 하둡의 새로운 버전인 0.22와 2.x (이전에는 0.23 )뿐만 아니라 1.x (이전에는 0.20 )도 다룬다. 이 책의 예제는 일부 예외(별도로 표시)를 제외하면 모든 버전에서 작동한다. 3판의 예제에서는 주로 새로운 맵리듀스 API를 사용한다. 하지만 예전 API도 여전히 널리 활용 되고 있기 때문에 새로운 API를 설명할 때 함께 언급한다. 또한 예전 API를 사용한 코드도 이 책의 웹사이트에서 제공한다. 하둡 2.0의 가장 큰 변화는 새로운 분산 자원 관리 시스템인 YARN 위에서 구현되는 새로운 맵 리듀스(맵리듀스 2 ) 실행 엔진이다. 3판은 YARN 기반의 맵리듀스를 다루는 새로운 장을 포함 하고 있다. 작동 방식은 7장, 실행 방식은 10장에서 다룬다.

4 http://bit.ly/hadoop_tdg_prev

14

맵리듀스와 관련된 내용도 더 많아졌다. 메이븐으로 맵리듀스 잡을 패키징, 사용자의 자바 클래 스 경로 설정, MRUnit으로 테스트 코드 작성은 5장에서 다룬다. 추가로 출력 커미터와 분산 캐시(9장), 태스크 메모리 모터터링(10장)과 같은 깊이 있는 특징도 포함했다. 에이브로 데이 터를 처리하는 맵리듀스 잡을 작성하는 새로운 절(12장)과 오지에서 맵리듀스 워크플로를 실행 하는 절(6장)도 추가되었다.

HDFS를 다루는 3장에는 고가용성, 페더레이션, WebHDFS와 HttpFS 파일시스템에 대한 설 명이 추가되었다. 피그, 하이브, 스쿱, 주키퍼를 다루는 장은 새로운 특징과 최근 버전의 변화를 반영했다. 이와 더불어 책 전반에 걸쳐 정정과 개선이 많이 이루어졌다.

2판의 새로운 내용 2판에서는 스쿱(15장)과 하이브(17장)에 대한 장이 추가되었고, 에이브로를 다루는 새로운 절(12장), 하둡의 새로운 보안 속성 소개(10장), 하둡을 이용해서 대규모 네트워크 그래프를 분석하는 사례 연구가 추가되었다.

2판은 (글을 쓰는 시점에 가장 최신의 안정 버전인) 아파치 하둡 0.20을 중심으로 설명했다. 이후 버전의 새로운 특징도 가끔 나오는데, 이 경우 처음 도입된 버전을 명시했다.

15

감사의 글

이 책을 쓰는 데 직간접적으로 많은 사람에게 도움을 받았다. 많은 것을 배울 수 있었고, 배움 을 계속하는 데 크게 도움을 준 하둡 커뮤니티에 감사의 말을 전한다. 특히 HBase에 대한 장을 써준 조나단 그레이 Jonathan Gray 와 마이클 스택 Michael Stack 에게 감사드 린다. 또한 사례 연구에 도움을 준 아드리안 우드헤드 Adrian Woodhead, 마크 드 패롤 Marc de Palol, 조이딥 센 사르마 Joydeep Sen Sarma, 아쉬시 투수 Ashish Thusoo, 안드르제이 비아레키 Andrzej Białecki, 스 투 후드 Stu Hood, 크리스 웬셀 Chris K. Wensel, 오웬 오말리 Owen O’Malley 에게 감사드린다. 원고를 검토하고 좋은 제안과 개선을 해준 라구 안가디 Raghu Angadi 외 많은 리뷰어에게 감사드린 다. 이 책의 예제로 사용된 NCDC 기상 데이터셋은 필립 크로머 Philip Kromer 가 도움을 주었다. 맵 리듀스 셔플의 복잡성을 잘 설명해준 오웬 오말리와 아룬 머시 Arun C. Murthy 에게 특별히 감사드린 다는 말을 전한다. 물론 남아 있는 오류는 모두 내 책임이다.

2판을 낼 때 자세한 검토와 피드백을 해준 제프 빈 Jeff Bean, 더그 커팅 Doug Cutting, 글린 더햄 Glynn Durham

, 앨런 게이츠 Alan Gates, 제프 해머배처 Jeff Hammerbacher, 알렉스 코즐로프 Alex Kozlov, 켄 크러

글러 Ken Krugler, 지미 린 Jimmy Lin, 토드 립콘 Jimmy Lin, 사라 스프로인리 Sarah Sproehnle, 비니쓰라 바 라드하라잔 Vinithra Varadharajan, 이안 리글리 Ian Wrigley 와 초판의 오자를 지적해준 모든 독자에게 감 사드린다. 또한 스쿱에 관한 장에 도움을 준 아론 킴밸 Aaron Kimball 과 그래프 처리에 대한 사례 연구에 도움을 준 필립 크로머 Philip

Kromer

에게 감사드린다.

3판을 낼 때 좋은 피드백과 제안을 해준 알레잔드로 아브델누르 Alejandro Abdelnur, 에바 앤드리아 손 Eva Andreasson, 엘리 콜린스 Eli Collins, 더그 커팅, 패트릭 헌트 Patrick Hunt, 아론 킴밸, 아론 메이어 스 Aaron T. Myers, 브룩 놀랜드 Brock Noland, 알빈드 프래바하커 Arvind Prabhakar, 아흐메드 라드완 Ahmed Radwan

, 톰 휠러 Tom Wheeler 에게 감사드린다. 랍 웰트먼 Rob Weltman 은 책 전체에 걸쳐 상세한 피드

백을 주었고 최종 조판에도 큰 도움을 주었다. 또한 3판의 오자를 지적해준 모든 독자에게 감 사드린다.

16

4판을 낼 때 엄청난 피드백을 해준 요독 배트로그 Jodok Batlogg, 메간 블랑셰트 Meghan Blanchette, 리 안 블루 Ryan Blue, 예렉 예섹 세초 Jarek Jarcec Cecho, 쥘 담지 Jules Damji, 데니스 도슨 Dennis Dawson, 매 튜 가스트 Matthew Gast, 카르딕 캠배틀라 Karthik Kambatla, 줄라앙 드 뎀 Julien Le Dem, 브록 놀랜드 Brock Noland

, 샌디 리자 Sandy Ryza, 아크샤이 사르마 Akshai Sarma, 벤 스피베이 Ben Spivey, 미쉘 스택 Michael

Stack

, 케이트 팅 Kate Ting, 조쉬 월터 Josh Walter, 조쉬 윌스 Josh Wills, 아드리안 우드헤드에게 감사드

린다. 4판의 사례 연구에 도움을 준 리안 브러쉬 Ryan Brush, 미카 휘타크레 Micah Whitacre, 매트 매 쉬 Matt Massie 에게 감사드린다. 또한 3판의 오자를 알려준 모든 독자에게 감사드린다. 특히 격려와 지원과 우정을 아끼지 않고 게다가 추천사를 써준 더그 커팅에게 큰 감사를 드린다. 이 책의 초판을 쓰는 도중에 클라우데라에 합류하게 되었다. 나에게 글을 쓸 시간과 빨리 끝낼 수 있도록 아낌없는 지원을 해준 동료들에게 감사의 말을 전한다. 이 책을 준비하는 데 도움을 준 편집자 마이크 루키드스 Mike Loukides 와 메간 블란쉐뜨 Meghan Blanchette

및 오라일리의 동료들에게 감사드린다. 마이크와 메간은 처음부터 끝까지 나의 질문에

응해주고, 초고를 읽어주고, 일정을 관리해주었다. 마지막으로, 이 책을 쓰는 것은 중대한 일이었고, 내 가족의 전폭적인 지원이 없었으면 불가능 했을 것이다. 아내 엘리안 Eliane 은 우리 가정을 잘 돌보았을 뿐만 아니라 이 책을 검토하고 편집 하고 사례 연구를 수집하는 데 도움을 주었다. 이해심이 깊은 딸 에밀리아 Emilia, 로띠 Lottie와 앞 으로 더 많은 시간을 함께 보내고 싶다. _톰 화이트

17

CONTENTS





지은이·옮긴이 소개 ��������������������������������������������������������������������������������������������������������� 4





추천의 글 ����������������������������������������������������������������������������������������������������������������������� 6





옮긴이의 말 �������������������������������������������������������������������������������������������������������������������� 8





이 책에 대하여 �������������������������������������������������������������������������������������������������������������� 12





감사의 글 ��������������������������������������������������������������������������������������������������������������������� 16

Part

1

CHAPTER

하둡 기초

1 하둡과의 만남



1.1 데이터! ��������������������������������������������������������������������������������������������������������������������� 39



1.2 데이터 저장소와 분석 ��������������������������������������������������������������������������������������������������� 41



1.3 전체 데이터에 질의하기 ������������������������������������������������������������������������������������������������ 43



1.4 일괄 처리를 넘어서 ������������������������������������������������������������������������������������������������������ 43



1.5 다른 시스템과의 비교 ��������������������������������������������������������������������������������������������������� 45





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





1.5.2 그리드 컴퓨팅 ������������������������������������������������������������������������������������������������� 47





1.5.3 자발적 컴퓨팅 ������������������������������������������������������������������������������������������������� 48



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



1.7 이 책의 내용 �������������������������������������������������������������������������������������������������������������� 53

CHAPTER

2 맵리듀스



2.1 기상 데이터셋 ������������������������������������������������������������������������������������������������������������ 57







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



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

18

2.1.1 데이터 포맷 ���������������������������������������������������������������������������������������������������� 57





2.3.1 맵과 리듀스 ���������������������������������������������������������������������������������������������������� 61





2.3.2 자바 맵리듀스 ������������������������������������������������������������������������������������������������� 63



2.4 분산형으로 확장하기 ���������������������������������������������������������������������������������������������������� 71





2.4.1 데이터 흐름 ���������������������������������������������������������������������������������������������������� 71





2.4.2 컴바이너 함수 ������������������������������������������������������������������������������������������������� 76





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



2.5 하둡 스트리밍 ������������������������������������������������������������������������������������������������������������ 79





2.5.1 루비 �������������������������������������������������������������������������������������������������������������� 79





2.5.2 파이썬 ����������������������������������������������������������������������������������������������������������� 82

CHAPTER

3 하둡 분산 파일시스템



3.1 HDFS 설계 ��������������������������������������������������������������������������������������������������������������� 86



3.2 HDFS 개념 ��������������������������������������������������������������������������������������������������������������� 87





3.2.1 블록 �������������������������������������������������������������������������������������������������������������� 87





3.2.2 네임노드와 데이터노드 ������������������������������������������������������������������������������������� 89





3.2.3 블록 캐싱 ������������������������������������������������������������������������������������������������������� 90





3.2.4 HDFS 페더레이션 ������������������������������������������������������������������������������������������� 91





3.2.5 HDFS 고가용성 ���������������������������������������������������������������������������������������������� 91



3.3 명령행 인터페이스 ������������������������������������������������������������������������������������������������������� 94







3.4 하둡 파일시스템 ���������������������������������������������������������������������������������������������������������� 97







3.5 자바 인터페이스 �������������������������������������������������������������������������������������������������������� 101





3.5.1 하둡 URL로 데이터 읽기 �������������������������������������������������������������������������������� 102





3.5.2 파일시스템 API로 데이터 읽기 ������������������������������������������������������������������������� 103





3.5.3 데이터 쓰기 �������������������������������������������������������������������������������������������������� 107





3.5.4 디렉터리 ������������������������������������������������������������������������������������������������������ 110

3.3.1 기본적인 파일시스템 연산 ��������������������������������������������������������������������������������� 95

3.4.1 인터페이스 ����������������������������������������������������������������������������������������������������� 99

19

CONTENTS





3.5.5 파일시스템 질의 �������������������������������������������������������������������������������������������� 110





3.5.6 데이터 삭제 �������������������������������������������������������������������������������������������������� 116



3.6 데이터 흐름 ������������������������������������������������������������������������������������������������������������� 117





3.6.1 파일 읽기 상세 ���������������������������������������������������������������������������������������������� 117





3.6.2 파일 쓰기 상세 ���������������������������������������������������������������������������������������������� 120





3.6.3 일관성 모델 �������������������������������������������������������������������������������������������������� 123



3.7 distcp로 병렬 복사하기 ��������������������������������������������������������������������������������������������� 125





CHAPTER

3.7.1 HFDS 클러스터 균형 유지 ������������������������������������������������������������������������������ 127

4 YARN



4.1 YARN 애플리케이션 수행 해부해보기 �������������������������������������������������������������������������� 130





4.1.1 자원 요청 ����������������������������������������������������������������������������������������������������� 131





4.1.2 애플리케이션의 수명 �������������������������������������������������������������������������������������� 132





4.1.3 YARN 애플리케이션 만들기 ���������������������������������������������������������������������������� 133



4.2 YARN과 맵리듀스 1의 차이점 ������������������������������������������������������������������������������������ 134



4.3 YARN 스케줄링 ������������������������������������������������������������������������������������������������������� 136





4.3.1 스케줄러 옵션 ����������������������������������������������������������������������������������������������� 137





4.3.2 캐퍼시티 스케줄러 설정 ���������������������������������������������������������������������������������� 139





4.3.3 페어 스케줄러 설정 ���������������������������������������������������������������������������������������� 141





4.3.4 지연 스케줄링 ����������������������������������������������������������������������������������������������� 146





4.3.5 우성 자원 공평성 ������������������������������������������������������������������������������������������� 147



4.4 참고 도서 ���������������������������������������������������������������������������������������������������������������� 148

CHAPTER



20

5 하둡 I/O 5.1 데이터 무결성 ���������������������������������������������������������������������������������������������������������� 149





5.1.1 HDFS의 데이터 무결성 ���������������������������������������������������������������������������������� 150





5.1.2 LocalFileSystem ����������������������������������������������������������������������������������������� 151





5.1.3 ChecksumFileSystem ��������������������������������������������������������������������������������� 152



5.2 압축 ����������������������������������������������������������������������������������������������������������������������� 153





5.2.1 코덱 ������������������������������������������������������������������������������������������������������������ 154





5.2.2 압축과 입력 스플릿 ���������������������������������������������������������������������������������������� 159





5.2.3 맵리듀스에서 압축 사용하기 ���������������������������������������������������������������������������� 161



5.3 직렬화 �������������������������������������������������������������������������������������������������������������������� 164





5.3.1 Writable 인터페이스 �������������������������������������������������������������������������������������� 165





5.3.2 Writable 클래스 �������������������������������������������������������������������������������������������� 168





5.3.3 커스텀 Writable 구현하기 ������������������������������������������������������������������������������� 178





5.3.4 직렬화 프레임워크 ����������������������������������������������������������������������������������������� 184



5.4 파일 기반 데이터 구조 ������������������������������������������������������������������������������������������������ 186





5.4.1 SequenceFile ��������������������������������������������������������������������������������������������� 186





5.4.2 MapFile ������������������������������������������������������������������������������������������������������ 195





5.4.3 기타 파일 포맷과 컬럼 기반 파일 포맷 ��������������������������������������������������������������� 196

Part

2

CHAPTER

맵리듀스

6 맵리듀스 프로그래밍



6.1 환경 설정 API ���������������������������������������������������������������������������������������������������������� 202





6.1.1 리소스 결합하기 �������������������������������������������������������������������������������������������� 203





6.1.2 변수 확장 ����������������������������������������������������������������������������������������������������� 204



6.2 개발환경 설정하기 ����������������������������������������������������������������������������������������������������� 205





6.2.1 환경 설정 파일 관리하기 ��������������������������������������������������������������������������������� 207





6.2.2 GenericOptionsParser, Tool, ToolRunner ����������������������������������������������������� 211

21

CONTENTS



6.3 엠알유닛으로 단위 테스트 작성하기 ������������������������������������������������������������������������������ 215





6.3.1 매퍼 ������������������������������������������������������������������������������������������������������������ 215





6.3.2 리듀서 ��������������������������������������������������������������������������������������������������������� 219



6.4 로컬에서 실행하기 ����������������������������������������������������������������������������������������������������� 220





6.4.1 로컬 잡 실행하기 ������������������������������������������������������������������������������������������� 220





6.4.2 드라이버 테스트하기 �������������������������������������������������������������������������������������� 222



6.5 클러스터에서 실행하기 ����������������������������������������������������������������������������������������������� 224





6.5.1 잡 패키징 ����������������������������������������������������������������������������������������������������� 224





6.5.2 잡 구동하기 �������������������������������������������������������������������������������������������������� 227





6.5.3 맵리듀스 웹 UI ���������������������������������������������������������������������������������������������� 230





6.5.4 결과 얻기 ����������������������������������������������������������������������������������������������������� 232





6.5.5 잡 디버깅 ����������������������������������������������������������������������������������������������������� 234





6.5.6 하둡 로그 ����������������������������������������������������������������������������������������������������� 238





6.5.7 원격 디버깅 �������������������������������������������������������������������������������������������������� 240



6.6 잡 튜닝하기 ������������������������������������������������������������������������������������������������������������� 241







6.7 맵리듀스 작업 흐름 ���������������������������������������������������������������������������������������������������� 243





6.7.1 맵리듀스 잡으로 문제 분해하기 ������������������������������������������������������������������������ 244





6.7.2 JobControl ������������������������������������������������������������������������������������������������� 245





6.7.3 아파치 오지 �������������������������������������������������������������������������������������������������� 246

CHAPTER

6.6.1 태스크 프로파일링 ����������������������������������������������������������������������������������������� 242

7 맵리듀스 작동 방법



7.1 맵리듀스 잡 실행 상세분석 ������������������������������������������������������������������������������������������ 253





7.1.1 잡 제출 �������������������������������������������������������������������������������������������������������� 254





7.1.2 잡 초기화 ����������������������������������������������������������������������������������������������������� 255





7.1.3 태스크 할당 �������������������������������������������������������������������������������������������������� 256

22





7.1.4 태스크 실행 �������������������������������������������������������������������������������������������������� 257





7.1.5 진행 상황과 상태 갱신 ������������������������������������������������������������������������������������ 258





7.1.6 잡 완료 �������������������������������������������������������������������������������������������������������� 260



7.2 실패 ����������������������������������������������������������������������������������������������������������������������� 261





7.2.1 태스크 실패 �������������������������������������������������������������������������������������������������� 261





7.2.2 애플리케이션 마스터 실패 ������������������������������������������������������������������������������� 263





7.2.3 노드 매니저 실패 ������������������������������������������������������������������������������������������� 264





7.2.4 리소스 매니저 실패 ���������������������������������������������������������������������������������������� 265



7.3 셔플과 정렬 ������������������������������������������������������������������������������������������������������������� 266





7.3.1 맵 부분 �������������������������������������������������������������������������������������������������������� 266





7.3.2 리듀스 부분 �������������������������������������������������������������������������������������������������� 268





7.3.3 설정 조정 ����������������������������������������������������������������������������������������������������� 270



7.4 태스크 실행 ������������������������������������������������������������������������������������������������������������� 273





7.4.1 태스크 실행 환경 ������������������������������������������������������������������������������������������� 273





7.4.2 투기적 실행 �������������������������������������������������������������������������������������������������� 274





7.4.3 출력 커미터 �������������������������������������������������������������������������������������������������� 276

CHAPTER

8 맵리듀스 타입과 포맷



8.1 맵리듀스 타입 ���������������������������������������������������������������������������������������������������������� 279







8.2 입력 포맷 ���������������������������������������������������������������������������������������������������������������� 291





8.2.1 입력 스플릿과 레코드 ������������������������������������������������������������������������������������� 293





8.2.2 텍스트 입력 �������������������������������������������������������������������������������������������������� 304





8.2.3 바이너리 입력 ����������������������������������������������������������������������������������������������� 309





8.2.4 다중 입력 ����������������������������������������������������������������������������������������������������� 310





8.2.5 데이터베이스 입력과 출력 ������������������������������������������������������������������������������� 312

8.1.1 기본 맵리듀스 잡 ������������������������������������������������������������������������������������������� 284

23

CONTENTS



8.3 출력 포맷 ���������������������������������������������������������������������������������������������������������������� 312





8.3.1 텍스트 출력 �������������������������������������������������������������������������������������������������� 312





8.3.2 바이너리 출력 ����������������������������������������������������������������������������������������������� 313





8.3.3 다중 출력 ����������������������������������������������������������������������������������������������������� 314





8.3.4 느린 출력 ����������������������������������������������������������������������������������������������������� 319





8.3.5 데이터베이스 출력 ����������������������������������������������������������������������������������������� 319

CHAPTER

9 맵리듀스 기능



9.1 카운터 �������������������������������������������������������������������������������������������������������������������� 321





9.1.1 내장 카운터 �������������������������������������������������������������������������������������������������� 322





9.1.2 사용자 정의 자바 카운터 ��������������������������������������������������������������������������������� 326





9.1.3 사용자 정의 스트리밍 카운터 ��������������������������������������������������������������������������� 330



9.2 정렬 ����������������������������������������������������������������������������������������������������������������������� 331





9.2.1 준비 ������������������������������������������������������������������������������������������������������������ 331





9.2.2 부분 정렬 ����������������������������������������������������������������������������������������������������� 332





9.2.3 전체 정렬 ����������������������������������������������������������������������������������������������������� 334





9.2.4 2차 정렬 ������������������������������������������������������������������������������������������������������ 339



9.3 조인 ����������������������������������������������������������������������������������������������������������������������� 346





9.3.1 맵-사이드 조인 ��������������������������������������������������������������������������������������������� 347





9.3.2 리듀스-사이드 조인 ��������������������������������������������������������������������������������������� 348



9.4 사이드 데이터 분배 ���������������������������������������������������������������������������������������������������� 352





9.4.1 잡 환경 설정 사용 ������������������������������������������������������������������������������������������ 352





9.4.2 분산 캐시 ����������������������������������������������������������������������������������������������������� 353



9.5 맵리듀스 라이브러리 클래스 ���������������������������������������������������������������������������������������� 358

24

Part

3

CHAPTER

하둡 운영

10 하둡 클러스터 설정



10.1 클러스터 명세 ��������������������������������������������������������������������������������������������������������� 364





10.1.1 클러스터 규모 결정 ������������������������������������������������������������������������������������ 366





10.1.2 네트워크 토폴로지 ������������������������������������������������������������������������������������� 367



10.2 클러스터 설치 및 설정 ���������������������������������������������������������������������������������������������� 369





10.2.1 자바 설치 ������������������������������������������������������������������������������������������������� 369





10.2.2 유닉스 사용자 계정 생성 ����������������������������������������������������������������������������� 369





10.2.3 하둡 설치 ������������������������������������������������������������������������������������������������� 370





10.2.4 SSH 구성 ������������������������������������������������������������������������������������������������ 370





10.2.5 하둡 구성 ������������������������������������������������������������������������������������������������� 372





10.2.6 HDFS 파일시스템 포맷 ������������������������������������������������������������������������������ 372





10.2.7 데몬의 시작과 중지 ������������������������������������������������������������������������������������ 372





10.2.8 사용자 디렉터리 생성 ��������������������������������������������������������������������������������� 374



10.3 하둡 환경 설정 �������������������������������������������������������������������������������������������������������� 374





10.3.1 환경 설정 관리 ������������������������������������������������������������������������������������������ 375





10.3.2 환경 설정 ������������������������������������������������������������������������������������������������� 376





10.3.3 중요한 하둡 데몬 속성 �������������������������������������������������������������������������������� 379





10.3.4 하둡 데몬 주소 및 포트 ������������������������������������������������������������������������������� 387





10.3.5 다른 하둡 속성 ������������������������������������������������������������������������������������������ 390



10.4 보안 ��������������������������������������������������������������������������������������������������������������������� 393





10.4.1 커버로스와 하둡 ���������������������������������������������������������������������������������������� 394





10.4.2 위임 토큰 ������������������������������������������������������������������������������������������������� 397





10.4.3 다른 보안 강화 사항 ����������������������������������������������������������������������������������� 398



10.5 하둡 클러스터 벤치마크 �������������������������������������������������������������������������������������������� 399

25

CONTENTS





10.5.1 하둡 벤치마크 ������������������������������������������������������������������������������������������� 400





10.5.2 사용자 잡 ������������������������������������������������������������������������������������������������� 402

CHAPTER

11 하둡 관리



11.1 HDFS ������������������������������������������������������������������������������������������������������������������ 403





11.1.1 영속적인 데이터 구조 ��������������������������������������������������������������������������������� 403





11.1.2 안전 모드 ������������������������������������������������������������������������������������������������� 409





11.1.3 감사 로깅 ������������������������������������������������������������������������������������������������� 411





11.1.4 도구 �������������������������������������������������������������������������������������������������������� 412



11.2 모니터링 ��������������������������������������������������������������������������������������������������������������� 418





11.2.1 로깅 �������������������������������������������������������������������������������������������������������� 418





11.2.2 메트릭과 JMX ������������������������������������������������������������������������������������������ 419



11.3 유지 보수 ��������������������������������������������������������������������������������������������������������������� 421





11.3.1 일상적인 관리 절차 ������������������������������������������������������������������������������������ 421





11.3.2 노드의 추가와 퇴역 ������������������������������������������������������������������������������������ 423





11.3.3 업그레이드 ����������������������������������������������������������������������������������������������� 426

Part

4

CHAPTER

관련 프로젝트

12 에이브로



12.1 에이브로 자료형과 스키마 ����������������������������������������������������������������������������������������� 437



12.2 인메모리 직렬화와 역직렬화 �������������������������������������������������������������������������������������� 440







12.3 에이브로 데이터 파일 ����������������������������������������������������������������������������������������������� 444

26

12.2.1 구체적인 API ������������������������������������������������������������������������������������������� 442



12.4 상호운영성 ������������������������������������������������������������������������������������������������������������� 446





12.4.1 파이썬 API ���������������������������������������������������������������������������������������������� 446





12.4.2 에이브로 도구 ������������������������������������������������������������������������������������������� 448



12.5 스키마 해석 ������������������������������������������������������������������������������������������������������������ 448



12.6 정렬 순서 ��������������������������������������������������������������������������������������������������������������� 451



12.7 에이브로 맵리듀스 ��������������������������������������������������������������������������������������������������� 453



12.8 에이브로 맵리듀스를 이용하여 정렬하기 ���������������������������������������������������������������������� 457



12.9 다양한 언어에서 에이브로 사용하기 ���������������������������������������������������������������������������� 460

CHAPTER

13 파케이



13.1 데이터 모델 ������������������������������������������������������������������������������������������������������������ 462







13.2 파케이 파일 포맷 ����������������������������������������������������������������������������������������������������� 465



13.3 파케이 설정 ������������������������������������������������������������������������������������������������������������ 467



13.4 파케이 파일 쓰기와 읽기 ������������������������������������������������������������������������������������������� 468







13.5 파케이 맵리듀스 ������������������������������������������������������������������������������������������������������ 473

CHAPTER

13.1.1 중첩 인코딩 ���������������������������������������������������������������������������������������������� 464

13.4.1 에이브로, 프로토콜 버퍼, 쓰리프트 ��������������������������������������������������������������� 470

14 플룸



14.1 플룸 설치 ��������������������������������������������������������������������������������������������������������������� 478



14.2 예제 ��������������������������������������������������������������������������������������������������������������������� 478



14.3 트랜잭션과 신뢰성 ��������������������������������������������������������������������������������������������������� 481







14.4 HDFS 싱크 ����������������������������������������������������������������������������������������������������������� 483





14.3.1 배치 �������������������������������������������������������������������������������������������������������� 482

14.4.1 파티셔닝과 인터셉터 ���������������������������������������������������������������������������������� 484

27

CONTENTS

14.4.2 파일 포맷 ������������������������������������������������������������������������������������������������� 485







14.5 분기 ��������������������������������������������������������������������������������������������������������������������� 487





14.5.1 전송 보장 ������������������������������������������������������������������������������������������������� 488





14.5.2 복제와 다중화 선택기 ��������������������������������������������������������������������������������� 489



14.6 분배: 에이전트 계층 ������������������������������������������������������������������������������������������������� 489







14.7 싱크 그룹 ��������������������������������������������������������������������������������������������������������������� 494



14.8 애플리케이션과 플룸의 통합 �������������������������������������������������������������������������������������� 498



14.9 컴포넌트 목록 ��������������������������������������������������������������������������������������������������������� 498



14.10 참고 도서 ��������������������������������������������������������������������������������������������������������������� 500

CHAPTER

14.6.1 전송 보장 ������������������������������������������������������������������������������������������������� 493

15 스쿱



15.1 스쿱 얻기 ��������������������������������������������������������������������������������������������������������������� 502



15.2 스쿱 커넥터 ������������������������������������������������������������������������������������������������������������ 504



15.3 임포트 예제 ������������������������������������������������������������������������������������������������������������ 504







15.4 생성된 코드 ������������������������������������������������������������������������������������������������������������ 508







15.5 임포트 자세히 살펴보기 �������������������������������������������������������������������������������������������� 509





15.5.1 임포트 제어하기 ���������������������������������������������������������������������������������������� 512





15.5.2 임포트와 일관성 ���������������������������������������������������������������������������������������� 513





15.5.3 증분 임포트 ���������������������������������������������������������������������������������������������� 513





15.5.4 직접 모드 임포트 ��������������������������������������������������������������������������������������� 514



15.6 불러온 데이터로 작업하기 ����������������������������������������������������������������������������������������� 514







15.7 대용량 객체 임포트하기 �������������������������������������������������������������������������������������������� 519

28

15.3.1 텍스트와 바이너리 파일 포맷 ����������������������������������������������������������������������� 508

15.4.1 추가적인 직렬화 시스템 ������������������������������������������������������������������������������ 509

15.6.1 임포트한 데이터와 하이브 ��������������������������������������������������������������������������� 516



15.8 익스포트 수행하기 ��������������������������������������������������������������������������������������������������� 521



15.9 익스포트 자세히 살펴보기 ����������������������������������������������������������������������������������������� 523





15.9.1 익스포트와 트랜잭션 ���������������������������������������������������������������������������������� 524





15.9.2 익스포트와 시퀀스 파일 ������������������������������������������������������������������������������ 525



15.10 참고 도서 ��������������������������������������������������������������������������������������������������������������� 527

CHAPTER

16 피그



16.1 피그의 설치 및 실행 ������������������������������������������������������������������������������������������������� 530





16.1.1 실행 유형 ������������������������������������������������������������������������������������������������� 531





16.1.2 피그 프로그램 실행 ������������������������������������������������������������������������������������ 533





16.1.3 그런트 ����������������������������������������������������������������������������������������������������� 533





16.1.4 피그 라틴 편집기 ��������������������������������������������������������������������������������������� 534



16.2 예제 ��������������������������������������������������������������������������������������������������������������������� 534







16.3 데이터베이스와 비교 ������������������������������������������������������������������������������������������������ 539



16.4 피그 라틴 ��������������������������������������������������������������������������������������������������������������� 540





16.4.1 구조 �������������������������������������������������������������������������������������������������������� 541





16.4.2 문장 �������������������������������������������������������������������������������������������������������� 542





16.4.3 표현식 ����������������������������������������������������������������������������������������������������� 547





16.4.4 자료형 ����������������������������������������������������������������������������������������������������� 549





16.4.5 스키마 ����������������������������������������������������������������������������������������������������� 550





16.4.6 함수 �������������������������������������������������������������������������������������������������������� 556





16.4.7 매크로 ����������������������������������������������������������������������������������������������������� 558



16.5 사용자 정의 함수 ����������������������������������������������������������������������������������������������������� 560





16.5.1 필터 UDF ������������������������������������������������������������������������������������������������ 560





16.5.2 평가 UDF ������������������������������������������������������������������������������������������������ 564

16.2.1 예제 생성하기 ������������������������������������������������������������������������������������������� 538

29

CONTENTS

16.5.3 로드 UDF ������������������������������������������������������������������������������������������������ 566







16.6 데이터 처리 연산자 �������������������������������������������������������������������������������������������������� 570





16.6.1 데이터 로드와 저장 ������������������������������������������������������������������������������������ 570





16.6.2 데이터 필터링 ������������������������������������������������������������������������������������������� 570





16.6.3 데이터 그룹과 조인 ������������������������������������������������������������������������������������ 574





16.6.4 데이터 정렬 ���������������������������������������������������������������������������������������������� 580





16.6.5 데이터 결합과 분할 ������������������������������������������������������������������������������������ 582



16.7 피그 실무 ��������������������������������������������������������������������������������������������������������������� 583





16.7.1 병렬성 ����������������������������������������������������������������������������������������������������� 583





16.7.2 익명 관계자 ���������������������������������������������������������������������������������������������� 584





16.7.3 매개변수 대체 ������������������������������������������������������������������������������������������� 584



16.8 참고 도서 ��������������������������������������������������������������������������������������������������������������� 586

CHAPTER

17 하이브



17.1 하이브 설치하기 ������������������������������������������������������������������������������������������������������ 588







17.2 예제 ��������������������������������������������������������������������������������������������������������������������� 591



17.3 하이브 실행하기 ������������������������������������������������������������������������������������������������������ 592





17.3.1 하이브 설정하기 ���������������������������������������������������������������������������������������� 593





17.3.2 하이브 서비스 ������������������������������������������������������������������������������������������� 596





17.3.3 메타스토어 ����������������������������������������������������������������������������������������������� 598



17.4 전통적인 데이터베이스와의 비교 �������������������������������������������������������������������������������� 600





17.4.1 읽기 스키마와 쓰기 스키마의 비교 ���������������������������������������������������������������� 601





17.4.2 갱신, 트랜잭션, 색인 ���������������������������������������������������������������������������������� 601





17.4.3 SQL- on - Hadoop 대안 ���������������������������������������������������������������������������� 602



17.5 HiveQL ���������������������������������������������������������������������������������������������������������������� 604

30

17.1.1 하이브 쉘 ������������������������������������������������������������������������������������������������� 589





17.5.1 자료형 ����������������������������������������������������������������������������������������������������� 605





17.5.2 연산자와 함수 ������������������������������������������������������������������������������������������� 608



17.6 테이블 ������������������������������������������������������������������������������������������������������������������ 609





17.6.1 관리 테이블과 외부 테이블 �������������������������������������������������������������������������� 609





17.6.2 파티션과 버킷 ������������������������������������������������������������������������������������������� 611





17.6.3 저장 포맷 ������������������������������������������������������������������������������������������������� 617





17.6.4 데이터 임포트하기 ������������������������������������������������������������������������������������� 621





17.6.5 테이블 변경하기 ���������������������������������������������������������������������������������������� 623





17.6.6 테이블 삭제하기 ���������������������������������������������������������������������������������������� 625



17.7 데이터 질의하기 ������������������������������������������������������������������������������������������������������ 625





17.7.1 정렬과 집계 ���������������������������������������������������������������������������������������������� 625





17.7.2 맵리듀스 스크립트 ������������������������������������������������������������������������������������� 626





17.7.3 조인 �������������������������������������������������������������������������������������������������������� 628





17.7.4 서브쿼리 �������������������������������������������������������������������������������������������������� 632





17.7.5 뷰 ����������������������������������������������������������������������������������������������������������� 633



17.8 사용자 정의 함수 ����������������������������������������������������������������������������������������������������� 634





17.8.1 UDF 작성하기 ������������������������������������������������������������������������������������������ 636





17.8.2 UDAF 작성하기 ���������������������������������������������������������������������������������������� 639



17.9 참고 도서 ��������������������������������������������������������������������������������������������������������������� 644

CHAPTER

18 크런치



18.1 예제 ��������������������������������������������������������������������������������������������������������������������� 646



18.2 크런치 핵심 API ����������������������������������������������������������������������������������������������������� 650





18.2.1 기본 연산자 ���������������������������������������������������������������������������������������������� 650





18.2.2 자료형 ����������������������������������������������������������������������������������������������������� 656





18.2.3 소스와 타깃 ���������������������������������������������������������������������������������������������� 660

31

CONTENTS





18.2.4 함수 �������������������������������������������������������������������������������������������������������� 663





18.2.5 실체화 ����������������������������������������������������������������������������������������������������� 666



18.3 파이프라인 실행 ������������������������������������������������������������������������������������������������������ 668





18.3.1 파이프라인 수행하기 ���������������������������������������������������������������������������������� 669





18.3.2 파이프라인 정지하기 ���������������������������������������������������������������������������������� 671





18.3.3 크런치 계획 조사하기 ��������������������������������������������������������������������������������� 671





18.3.4 반복적 알고리즘 ���������������������������������������������������������������������������������������� 675





18.3.5 파이프라인 체크포인트 ������������������������������������������������������������������������������� 677



18.4 크런치 라이브러리 ��������������������������������������������������������������������������������������������������� 678



18.5 참고 도서 ��������������������������������������������������������������������������������������������������������������� 680

CHAPTER

19 스파크



19.1 스파크 설치 ������������������������������������������������������������������������������������������������������������ 682



19.2 예제 ��������������������������������������������������������������������������������������������������������������������� 682





19.2.1 스파크 애플리케이션, 잡, 스테이지, 태스크 ����������������������������������������������������� 685





19.2.2 스칼라 독립 애플리케이션 ��������������������������������������������������������������������������� 686





19.2.3 자바 예제 ������������������������������������������������������������������������������������������������� 687





19.2.4 파이썬 예제 ���������������������������������������������������������������������������������������������� 689



19.3 탄력적인 분산 데이터셋 RDD ����������������������������������������������������������������������������������� 690





19.3.1 생성 �������������������������������������������������������������������������������������������������������� 690





19.3.2 트랜스포메이션과 액션 ������������������������������������������������������������������������������� 692





19.3.3 지속성 ����������������������������������������������������������������������������������������������������� 696





19.3.4 직렬화 ����������������������������������������������������������������������������������������������������� 699



19.4 공유변수 ��������������������������������������������������������������������������������������������������������������� 700





19.4.1 브로드캐스트 변수 ������������������������������������������������������������������������������������� 701





19.4.2 어큐뮬레이터 �������������������������������������������������������������������������������������������� 701

32



19.5 스파크 잡 수행 분석 ������������������������������������������������������������������������������������������������� 702





19.5.1 잡 제출 ���������������������������������������������������������������������������������������������������� 703





19.5.2 DAG 구성 ������������������������������������������������������������������������������������������������ 704





19.5.3 태스크 스케줄링 ���������������������������������������������������������������������������������������� 706





19.5.4 태스크 수행 ���������������������������������������������������������������������������������������������� 707



19.6 익스큐터와 클러스터 매니저 �������������������������������������������������������������������������������������� 708







19.7 참고 도서 ��������������������������������������������������������������������������������������������������������������� 713

CHAPTER

19.6.1 YARN에서 스파크 실행 ������������������������������������������������������������������������������ 709

20 HBase



20.1 HBase 개요 ���������������������������������������������������������������������������������������������������������� 715







20.2 개념 ��������������������������������������������������������������������������������������������������������������������� 716





20.2.1 데이터 모델 둘러보기 ��������������������������������������������������������������������������������� 717





20.2.2 구현 �������������������������������������������������������������������������������������������������������� 719



20.3 설치 ��������������������������������������������������������������������������������������������������������������������� 722







20.4 클라이언트 ������������������������������������������������������������������������������������������������������������� 726





20.4.1 자바 �������������������������������������������������������������������������������������������������������� 726





20.4.2 맵리듀스 �������������������������������������������������������������������������������������������������� 730





20.4.3 REST와 쓰리프트 ������������������������������������������������������������������������������������� 732



20.5 온라인 쿼리 애플리케이션 구축 ���������������������������������������������������������������������������������� 732





20.5.1 스키마 설계 ���������������������������������������������������������������������������������������������� 732





20.5.2 데이터 로드 ���������������������������������������������������������������������������������������������� 734





20.5.3 온라인 쿼리 ���������������������������������������������������������������������������������������������� 738



20.6 HBase와 RDBMS의 비교 ��������������������������������������������������������������������������������������� 742

20.1.1 배경 �������������������������������������������������������������������������������������������������������� 716

20.3.1 테스트 드라이브 ���������������������������������������������������������������������������������������� 723

33

CONTENTS





20.6.1 성공적인 서비스 ���������������������������������������������������������������������������������������� 743





20.6.2 HBase ��������������������������������������������������������������������������������������������������� 744



20.7 활용 ��������������������������������������������������������������������������������������������������������������������� 745





20.7.1 HDFS ����������������������������������������������������������������������������������������������������� 745





20.7.2 UI ���������������������������������������������������������������������������������������������������������� 746





20.7.3 메트릭 ����������������������������������������������������������������������������������������������������� 746





20.7.4 카운터 ����������������������������������������������������������������������������������������������������� 746



20.8 참고 도서 ��������������������������������������������������������������������������������������������������������������� 747

CHAPTER

21 주키퍼



21.1 주키퍼 설치와 실행 �������������������������������������������������������������������������������������������������� 750



21.2 예제 ��������������������������������������������������������������������������������������������������������������������� 753





21.2.1 주키퍼의 그룹 멤버십 ��������������������������������������������������������������������������������� 753





21.2.2 그룹 생성 ������������������������������������������������������������������������������������������������� 754





21.2.3 그룹 가입 ������������������������������������������������������������������������������������������������� 756





21.2.4 그룹 멤버 목록 ������������������������������������������������������������������������������������������ 758





21.2.5 그룹 삭제 ������������������������������������������������������������������������������������������������� 761



21.3 주키퍼 서비스 ��������������������������������������������������������������������������������������������������������� 762





21.3.1 데이터 모델 ���������������������������������������������������������������������������������������������� 762





21.3.2 연산 �������������������������������������������������������������������������������������������������������� 764





21.3.3 구현 �������������������������������������������������������������������������������������������������������� 770





21.3.4 일관성 ����������������������������������������������������������������������������������������������������� 771





21.3.5 세션 �������������������������������������������������������������������������������������������������������� 773





21.3.6 상태 �������������������������������������������������������������������������������������������������������� 775



21.4 주키퍼 애플리케이션 구현 ����������������������������������������������������������������������������������������� 777





34

21.4.1 환경 설정 서비스 ��������������������������������������������������������������������������������������� 777





21.4.2 탄력적인 주키퍼 애플리케이션 ��������������������������������������������������������������������� 781





21.4.3 락 서비스 ������������������������������������������������������������������������������������������������� 786





21.4.4 더 많은 분산 데이터 구조와 프로토콜 ������������������������������������������������������������ 790



21.5 주키퍼 실 서비스 ����������������������������������������������������������������������������������������������������� 790





21.5.1 탄력성과 성능 ������������������������������������������������������������������������������������������� 790





21.5.2 환경 설정 ������������������������������������������������������������������������������������������������� 791



21.6 참고 도서 ��������������������������������������������������������������������������������������������������������������� 793

Part

5

CHAPTER

사례 연구

22 서너의 구조적 데이터



22.1 CPU에서 시맨틱 통합까지 ��������������������������������������������������������������������������������������� 797



22.2 아파치 크런치의 도입 ����������������������������������������������������������������������������������������������� 798



22.3 완전한 설계도의 제작 ����������������������������������������������������������������������������������������������� 799



22.4 헬스케어 데이터 통합 ����������������������������������������������������������������������������������������������� 802



22.5 프레임워크를 뛰어넘는 결합성 ����������������������������������������������������������������������������������� 806



22.6 발전 방향 ��������������������������������������������������������������������������������������������������������������� 807

CHAPTER

23 생물학의 데이터 과학: 소프트웨어로 생명 구하기



23.1 DNA 구조 ������������������������������������������������������������������������������������������������������������� 811



23.2 유전 암호: DNA 글자의 단백질 전환 �������������������������������������������������������������������������� 812



23.3 DNA를 소스 코드처럼 생각하기 �������������������������������������������������������������������������������� 813



23.4 인간 게놈 프로젝트와 표준 게놈 ��������������������������������������������������������������������������������� 815



23.5 DNA 시퀀싱과 얼라이닝 ������������������������������������������������������������������������������������������ 816

35

CONTENTS



23.6 대규모 게놈 분석 플랫폼 ADAM �������������������������������������������������������������������������������� 817





23.6.1 에이브로 인터페이스 정의 언어로 작성한 문학적 프로그래밍 ����������������������������� 818





23.6.2 파케이를 이용한 컬럼 기반 접근 ������������������������������������������������������������������� 820





23.6.3 예제: 스파크와 ADAM을 이용한 k - mer 빈도 세기 ����������������������������������������� 822



23.7 개인맞춤광고에서 개인맞춤의학까지 ��������������������������������������������������������������������������� 824



23.8 참여하기 ��������������������������������������������������������������������������������������������������������������� 825

CHAPTER

24 캐스케이딩



24.1 필드, 튜플, 파이프 ��������������������������������������������������������������������������������������������������� 828



24.2 연산 ��������������������������������������������������������������������������������������������������������������������� 831



24.3 탭, 스킴, 플로 ��������������������������������������������������������������������������������������������������������� 833



24.4 예제 ��������������������������������������������������������������������������������������������������������������������� 835



24.5 유연성 ������������������������������������������������������������������������������������������������������������������ 838



24.6 쉐어디스에서의 하둡과 캐스케이딩 ����������������������������������������������������������������������������� 839



24.7 요약 ��������������������������������������������������������������������������������������������������������������������� 844

부록 A 아파치 하둡 설치하기 ���������������������������������������������������������������������������������������������������������������������

845

부록 B

클라우데라 아파치 하둡 배포판 ���������������������������������������������������������������������������������������������������������

853

부록 C

NCDC 기상 데이터 준비 ����������������������������������������������������������������������������������������������������������������

857

부록 D

예전과 새로운 자바 맵리듀스 API �����������������������������������������������������������������������������������������������������

861

찾아보기 ���������������������������������������������������������������������������������������������������������������������������������������������������

865

36

CHAPTER

1

하둡과의 만남

예전에 사람들은 무거운 것을 끌기 위해 소를 이용했다. 그리고 소 한 마리가 통나무 하나를 움직일 수 없을 때 그 소를 더 키우려 애쓰지 않았다. 우리에게 필요한 것은 커 다란 한 대의 컴퓨터가 아니라 매우 많은 컴퓨터로 이루어진 새로운 시스템이다. _그레이스 호퍼 Grace Hopper

1.1 데이터! 우리는 데이터 시대에 살고 있다. 컴퓨터에 저장된 데이터의 전체 크기를 쉽게 측정할 수는 없지 만 IDC 1는 ‘디지털 세계’의 크기가 2013년에는 4.4제타바이트 zettabyte, 2020년에는 10배 증가 한 44제타바이트에 다다를 것으로 전망했다.2 제타바이트는 1021바이트고, 1,000엑사바이트,

100만 페타바이트, 10억 테라바이트와 동일하다. 제타바이트는 세상의 모든 사람이 각자 디스 크를 하나씩 가진 것보다 더 큰 크기다.

1 옮긴이_ IT, 통신, 소비 부분의 세계 최고 시장조사 분석 및 컨설팅 기관 2 이 통계치는 「디지털 세계의 기회: 풍부한 데이터와 사물 인터넷의 가치 증가」( http://bit.ly/digital_universe )란 제목의 연구에서 나온 것이다.

39

수많은 곳에서 엄청난 데이터가 만들어지고 있다.3 뉴욕증권거래소에서는 하루에 4.5테라바이트의 데이터가 발생한다.



페이스북은 2,400억 개의 사진을 보유하고 있으며, 매달 7페타바이트 증가한다.



계통조사 사이트인 앤서스트리 Ancestry.com 는 약 10페타바이트의 데이터를 저장하고 있다.



인터넷 아카이브 Internet Archive 는 약 18.5페타바이트의 데이터를 저장하고 있다.



스위스 제네바에 있는 대형 하드론 입자가속기 Large Hadron Collider 는 매년 30페타바이트의 데이터를 생산한다.



그 밖에도 엄청난 데이터가 있다. 하지만 이러한 데이터가 우리에게 어떤 의미가 있는지 궁금할 것이다. 대부분의 데이터는 검색 엔진과 같이 매우 큰 웹사이트에 있거나 과학이나 금융 분야의 기관에 폐쇄적으로 보관되어 있지 않은가? 또한 빅데이터의 출현이 작은 조직이나 개인에게 무 슨 의미가 있다는 것인가? 나는 분명 의미가 있다고 본다. 사진을 예로 들어 보겠다. 내 아내의 할아버지는 열정적인 사진 작가였고 평생 사진을 찍었다. 중형, 슬라이드, 35mm 필름을 고해상도로 스캔하면 대략 10기 가바이트의 용량을 차지한다. 이것을 2008년에 우리 가족이 찍었던 5기가바이트의 디지털 사진 과 비교해보자. 우리 가족은 내 아내의 할아버지보다 35배의 데이터를 생산하고 있었고, 이러한 비율은 사진 찍기가 쉬워지는 만큼 매년 증가할 것이다. 특히 개인이 생산하는 디지털 스트림이 빠르게 증가하고 있다. 마이크로소프트 리서치의

MyLifeBits 프로젝트 4를 보면 가까운 미래에 개인 정보의 기록 보관은 매우 흔한 일이 될 것으 로 짐작할 수 있다. MyLifeBits 프로젝트는 전화, 이메일, 문서와 같은 개인의 일상을 컴퓨터 에 자동으로 보관하고 나중에 필요할 때 활용하도록 한 실험이다. 분 단위로 찍힌 사진을 포함 한 전체 데이터의 크기는 한 달에 1기가바이트에 달한다. 저장소의 비용이 모든 오디오와 비디 오를 저장할 수 있을 만큼 저렴해지면 미래에는 MyLifeBits 서비스의 데이터 크기도 엄청나게 증가할 것이다. 개인이 만들어내는 데이터의 족적도 계속 증가하지만, 정말 중요한 점은 사물인터넷의 일부인 기계에서 생산되는 데이터양이 훨씬 더 크다는 것이다. 기계 로그, RFID 리더, 센서 네트워크, 3 언급된 수치는 2013년 또는 2014년 자료다. 자세한 내용은 톰 그렌펠드( Tom Groenfeldt )의 「뉴욕증권거래소의 전통적인 데이터베 이스로 처리할 수 없는 엄청난 데이터」( http://bit.ly/nyse_?>

color yellow Color

size 10 Size

weight heavy true Weight

size-weight

202 2부 맵리듀스

${size},${weight} Size

and weight

다음 코드를 이용하면 환경 설정 파일인 configuration-1.xml로부터 속성 정보를 얻을 수 있다. Configuration conf = new Configuration(); conf.addResource("configuration-1.xml"); assertThat(conf.get("color"), is("yellow")); assertThat(conf.getInt("size", 0), is(10)); assertThat(conf.get("breadth", "wide"), is("wide"));

여기서 우리는 XML 파일에 자료형에 대한 정보가 없다는 점에 주의해야 한다. 그 대신 속성 파 일을 읽을 때 지정한 자료형으로 해석된다. 또한 get ( ) 메서드에 기본값을 넘길 수 있으며, 예 제의 breadth와 같이 XML 파일에 정의되지 않은 속성도 사용할 수 있다.

6.1.1 리소스 결합하기 환경 설정을 정의할 때 하나 이상의 리소스(XML 파일)를 사용할 수 있다. 하둡은 이 기능을 활 용하여 시스템의 기본 속성은 내부의 core-default.xml 파일로, 특정 속성은 core-site.xml 파일로 분리해서 정의했다. [예제 6-2]는 size와 weight 속성을 정의한 것이다. 예제 6-2 두 번째 설정 파일(configuration-2.xml )

size 12

weight light

6장 맵리듀스 프로그래밍 203

리소스들은 다음과 같이 환경 설정에 순서대로 추가된다. Configuration conf = new Configuration(); conf.addResource("configuration-1.xml"); conf.addResource("configuration-2.xml");

나중에 추가된 리소스에 정의된 속성은 이전에 정의된 속성을 오버라이드한다. 따라서 size 속 성은 두 번째 설정 파일 configuration-2.xml에 정의된 값을 따른다. assertThat(conf.getInt("size", 0), is(12));

그러나 final로 지정된 속성은 이후에 다시 정의해도 변경되지 않는다. 따라서 weight 속성은 첫 번째 설정 파일에서 final로 지정되었기 때문에 두 번째 오버라이드 시도는 실패하고 처음 할당된 값을 그대로 갖게 된다. assertThat(conf.get("weight"), is("heavy"));

일반적으로 final 속성을 재정의하려는 시도는 환경 설정 오류의 원인이 되므로 장애 진단을 위해 경고 메시지를 로그로 남긴다. 관리자는 클라이언트의 설정 파일이나 잡 제출 매개변수를 사용자가 변경하지 못하도록 데몬 사이트 파일의 속성을 final로 지정할 수 있다.

6.1.2 변수 확장 환경 설정 속성은 다른 속성이나 시스템 속성으로도 정의할 수 있다. 예를 들어 앞서 첫 번째 설 정 파일의 size-weight 속성은 ${size}, ${weight}로 정의되며, 이 속성들은 환경 설정에서 찾 은 값을 사용한다. assertThat(conf.get("size-weight"), is("12,heavy"));

시스템 속성은 리소스 파일에 정의된 속성보다 우선순위가 높다.

204 2부 맵리듀스

System.setProperty("size", "14"); assertThat(conf.get("size-weight"), is("14,heavy"));

이 기능은 명령행에서 -Dproperty =value 라는 JVM 인자를 이용하여 속성을 오버라이드할 때 유용하다. 환경 설정 속성은 시스템 속성으로도 정의할 수 있지만 주의할 점이 있다. 미리 정의되지 않은 속성을 시스템 속성으로 재정의한다면 환경 설정 API는 새로운 시스템 속성을 전혀 인식하지 못 한다.1 System.setProperty("length", "2"); assertThat(conf.get("length"), is((String) null));

6.2 개발환경 설정하기 맵리듀스 프로그램을 명령행이나 IDE 환경에서 빌드하고 로컬(독립) 모드로 실행하려면 먼저 프로젝트를 생성해야 한다. [예제 6-3]은 메이븐 POM Project Object Model 으로, 맵리듀스 프로그램 을 빌드하고 테스트하는 데 필요한 의존성을 잘 보여준다. 예제 6-3 맵리듀스 애플리케이션을 빌드하고 테스트하기 위한 메이븐 POM

4.0.0 com.hadoopbook hadoop-book-mr-dev 4.0

UTF-8 2.5.1



junit junit 4.11 test

org.apache.mrunit mrunit 1.1.0 hadoop2 test

org.apache.hadoop hadoop-minicluster ${hadoop.version} test

hadoop-examples

org.apache.maven.plugins maven-compiler-plugin 3.1

1.6 1.6

org.apache.maven.plugins maven-jar-plugin 2.5

${basedir}

206 2부 맵리듀스





POM에서 흥미로운 부분은 바로 의존성 섹션이다. 여기서 정의한 의존성과 동일하다면 그레이 들 Gradle 이나 아파치 앤트 Ant 의 아이비 Ivy 같은 빌드 도구를 사용하는 것이 더 직관적이다. 맵리 듀스 잡을 빌드하려면 하둡의 클라이언트 클래스(HDFS 및 맵리듀스와 통신하기 위한)를 모두 포함한 hadoop-client 의존성만 있으면 된다. 단위 테스트에는 junit 을, 맵리듀스 테스트에 는 mrunit 을 사용할 수 있다. hadoop-minicluster 라이브러리는 단일 JVM으로 실행되는 하 둡 클러스터에서 테스트할 때 유용한 ‘미니’ 클러스터를 포함하고 있다. 많은 IDE에서 메이븐 POM을 직접 지원하기 때문에 pom.xml 파일을 포함한 디렉터리를 지 정한 후 바로 코드를 작성하면 된다. 아니면 메이븐을 사용하여 IDE를 위한 설정 파일을 만들 수도 있다. 예를 들어 다음 명령은 프로젝트를 이클립스로 임포트하기 위해 이클립스용 설정 파 일을 생성하는 예제다. % mvn eclipse:eclipse -DdownloadSources=true -DdownloadJavadocs=true

6.2.1 환경 설정 파일 관리하기 하둡 애플리케이션을 개발할 때는 로컬 모드와 클러스터 모드를 번갈아가며 테스트하는 것이 좋 다. 보통 여러 대의 머신으로 구성된 클러스터에서 실제 작업을 수행한다. 하지만 테스트를 위해 단일 로컬 머신에서 모든 데몬을 실행하는 의사분산 pseudodistributed 클러스터를 하나쯤 가지고 있 는 경우가 많다(설치는 부록 A에서 다룬다). 다양한 클러스터 환경을 이용할 수 있도록 각 클러스터의 연결 정보를 가진 환경 설정 파일들을 먼저 만들고 하둡 애플리케이션이나 도구를 실행할 때 그중 하나를 지정하는 방법이 있다. 설정 파일의 중복이나 분실을 방지하기 위해 하둡 설치 디렉터리 외부에 이러한 파일을 보관할 것을 권장한다. 더욱 쉽게 설명하기 위해 conf 디렉터리에 hadoop-local.xml, hadoop-localhost.xml,

6장 맵리듀스 프로그래밍 207

hadoop-cluster.xml 등 세 개의 환경 설정 파일이 있다고 가정하자(예제 코드 참조). 이 파 일들에 특별한 명명 규칙이 있는 것은 아니고 단지 환경 설정 정보를 패키지로 편리하게 관리 하려는 것이다(동일한 서버 측 환경을 설정하는 [표 A-1]과 비교해보라). 로컬 모드. hadoop-local.xml 파일은 기본 파일시스템과 맵리듀스 잡을 실행하는 로컬(단일

JVM ) 프레임워크에 적합한 하둡 설정을 가진다.

fs.defaultFS file:///

mapreduce.framework.name local

의사분산 모드. hadoop-localhost.xml 파일에 로컬에서 작동하는 네임노드 namenode 와 YARN

리소스 매니저 resource manager 의 위치를 설정한다.

fs.defaultFS hdfs://localhost/

mapreduce.framework.name yarn

yarn.resourcemanager.address

208 2부 맵리듀스

localhost:8032

완전분산 모드. hadoop-cluster.xml 파일은 클러스터의 네임노드와 YARN 리소스 매니저의

주소를 가진다. 실무에서는 예제에 사용된 ‘cluster’라는 이름 대신 실제 클러스터의 이름을 사 용할 것을 권장한다.

fs.defaultFS hdfs://namenode/

mapreduce.framework.name yarn

yarn.resourcemanager.address resourcemanager:8032

필요 시 설정 파일에 다른 환경 설정 속성을 추가할 수 있다.

사용자 인증 설정 하둡은 클라이언트 시스템에서 whoami 명령어를 실행하여 알게 된 사용자에 대해 HDFS의 접근 권한을 확인한다. 비슷하게 그룹명은 groups 명령으로 확인할 수 있다. 만약 하둡의 사용자 이름과 클라이언트 머신의 사용자 계정이 다르면 HADOOP_USER_NAME 환경 변수에 사용자 이름을 명시적으로 설정하면 된다. 그리고 사용자 그룹은 hadoop.user.group. static.mapping.overrides 설정 속성으로 재정의할 수 있다. 예를 들어 dr.who=;preston=dir

6장 맵리듀스 프로그래밍 209

ectors,inventors는 dr.who 사용자는 그룹이 없고 preston은 directors와 inventors 그룹에

속한다는 것을 의미한다. 하둡 웹 인터페이스를 실행하는 사용자 이름은 hadoop.http.staticuser.user 속성에 설정한 다. 슈퍼유저 superuser 가 아닌 dr.who가 기본 사용자이므로 웹 인터페이스를 통해서는 시스템 파일 에 접근할 수 없다. 하둡은 기본적으로 시스템 내에 인증 기능을 제공하지 않는다는 점을 명심해야 한다. 하둡을 위한 커버로스 Kerberos 인증 사용법은 10.4절 ‘보안’을 참조하라.

명령행에서 -conf 뒤에 설정 파일을 명시적으로 지정하면 원하는 환경 설정을 쉽게 이용할 수 있다. 예를 들어 다음 명령행은 로컬 호스트에서 의사분산 모드로 실행 중인 HDFS 서버의 디 렉터리 목록을 보여준다. % hadoop fs -conf conf/hadoop-localhost.xml -ls . Found 2 items drwxr-xr-x 0 2014-09-08 10:19 input - tom supergroup drwxr-xr-x 0 2014-09-08 10:19 output - tom supergroup

-conf 옵션을 생략하면 $HADOOP_HOME 아래에 있는 etc/hadoop 디렉터리에서 하둡 설정을

찾는다. 또한 HADOOP_CONF_DIR를 별도로 설정했다면 그 위치에서 하둡 설정 파일을 찾는다. NOTE_ 환경 설정 파일을 관리하는 좋은 방법이 있다. 하둡이 설치된 디렉터리 아래에 있는 etc/hadoop

디렉터리를 다른 곳으로 복사하고, 그곳에 *-site.xml 설정 파일들을 옮긴 후, HADOOP_CONF_DIR 환경변수 의 값을 새로운 위치로 다시 설정한다. 이 방식의 주요 장점은 모든 명령행에서 -conf를 명시할 필요가 없 다는 것이다. 또한 HADOOP_CONF_DIR 디렉터리에 모든 환경 설정 파일의 복사본이 존재하기 때문에 하둡

XML 설정 파일 외에 다른 설정 파일(log4j.properties 등)을 독립적으로 변경할 수 있다(10.3절 ‘하둡 환경 설정’ 참조).

하둡이 제공하는 도구는 -conf 옵션을 지원하지만 Tool 인터페이스를 이용하여 사용자 프로그 램(맵리듀스 잡을 실행하는 프로그램)에서 이 옵션을 지원하도록 작성하는 것이 더 직관적이다.

210 2부 맵리듀스

CHAPTER

7

맵리듀스 작동 방법

이 장에서는 하둡에서 맵리듀스의 작동 방법을 자세히 살펴본다. 여기서 배운 지식은 다음 두 장에서 다룰 맵리듀스 고급 프로그램 작성에 좋은 밑거름이 될 것이다.

7.1 맵리듀스 잡 실행 상세분석 Job 객체의 submit ( ) 메서드 호출로 맵리듀스 잡을 실행할 수 있다(또한 waitForCompleti on ( ) 메서드를 호출할 수 있는데, 이 메서드는 아직 잡이 제출되지 않았다면 잡을 제출하고 종

료할 때까지 기다린다).1 이 메서드가 실행되는 이면에는 엄청난 처리 과정이 숨겨져 있다. 이 절에서는 하둡이 잡을 실행하는 과정을 자세히 알아본다. [그림 7-1]은 잡의 전체 과정을 보여준다. 상위 수준에서 보면 다섯 개의 독립적인 단계로 구분 되어 있다.2 ●

클라이언트 : 맵리듀스 잡을 제출한다.



YARN 리소스 매니저 : 클러스터 상에 계산 리소스의 할당을 제어한다.



YARN 노드 매니저 : 클러스터의 각 머신에서 계산 컨테이너를 시작하고 모니터링한다.

1 기존 맵리듀스 API에서는 JobClient.submitJob(conf) 또는 JobClient.runJob(conf)를 호출할 수 있다. 2 잡 히스토리 내역을 보관하는 잡 히스토리 서버 데몬과 맵의 출력을 리듀스 태스크에 제공하는 셔플 처리 보조 서비스는 여기에서 논하 지 않는다.

253

맵  리듀스 애플리케이션 마스터 : 맵리듀스 잡을 수행하는 각 태스크를 제어한다. 애플리케이션 마스터와 맵



리듀스 태스크는 컨테이너 내에서 실행되며, 리소스 매니저는 잡을 할당하고 노드 매니저는 태스크를 관리하 는 역할을 맡는다. 분  산 파일시스템 : 다른 단계 간에 잡 리소스 파일들을 공유하는 데 사용된다(보통 HDFS를 사용. 3장 참



조). 그림 7-1 하둡이 맵리듀스 잡을 실행하는 방식

2: 새로운 애플리케이션 획득 1: 잡 실행

맵리듀스 프로그램

4: 애플리케이션 제출 클라이언트 JVM 클라이언트 노드

리소스 매니저 노드 5a: 컨테이너 시작

8: 리소스 할당

3: 잡 리소스 복사 5b: 시작 6: 잡 초기화

노드 매니저 노드 7: 입력 스플릿 추출 공유 파일시스템 (예: HDFS)

9a: 컨테이너 시작 9b: 시작 태스크 JVM

10: 잡 리소스 추출

11: 실행

또는

노드 매니저 노드

7.1.1 잡 제출 Job의 submit ( ) 메서드는 내부의 JobSubmitter 인스턴스를 생성하고 submitJobInter

254 2부 맵리듀스

nal ( ) 메서드를 호출한다([그림 7-1]의 1단계). 일단 잡을 제출하면 waitForCompletion ( )

메서드가 1초에 한 번씩 잡의 진행 상황을 조사하여 변경 내역이 있으면 콘솔로 보여준다. 잡이 성공적으로 완료되면 잡 카운터를 보여준다. 실패하면 잡 실패의 원인이 된 에러를 콘솔에 보여 준다. JobSubmitter의 잡 제출 과정은 다음과 같다. 리소스 매니저에 맵리듀스 잡 ID로 사용될 새로운 애플리케이션 ID를 요청한다(2단계).



잡의 출력 명세를 확인한다. 예를 들어 출력 디렉터리가 지정되지 않았거나 이미 존재한다면 해당 잡은 제출



되지 않고 맵리듀스 프로그램에 에러를 전달한다. 잡의 입력 스플릿 Input Split 을 계산한다. 스플릿을 계산할 수 없다면(예를 들어 입력 경로가 없다면) 잡은 제출



되지 않고 맵리듀스 프로그램에 에러를 전달한다. 잡 실행에 필요한 잡 JAR 파일, 환경 설정 파일, 계산된 입력 스플릿 등의 잡 리소스를 공유 파일시스템에



있는 해당 잡 ID 이름의 디렉터리에 복사한다(3단계). 잡 JAR 파일의 복제 인수는 mapreduce.client. submit.file.replication 속성에 정의하며 기본값은 10으로 매우 높게 설정되어 있다. 클러스터 상에 잡 JAR의 복제본이 많으면 노드 매니저가 잡의 태스크를 실행할 때 접근성이 높아지는 장점이 있다. 리소스 매니저의 submitApplication ( )을 호출하여 잡을 제출한다(4단계).



7.1.2 잡 초기화 리소스 매니저가 submitApplication ( ) 메서드의 호출을 받으면 YARN 스케줄러에 요청을 전 달한다. 스케줄러는 컨테이너를 하나 할당하고, 리소스 매니저는 노드 매니저의 운영 규칙에 따 라 애플리케이션 마스터 프로세스를 시작한다(5a와 5b 단계). 맵리듀스 잡의 애플리케이션 마스터는 자바 애플리케이션이며 메인 클래스는 MRAppMaster 다. 애플리케이션 마스터는 잡을 초기화할 때 잡의 진행 상태를 추적하기 위한 다수의 북키핑 bookkeeping

(장부) 객체를 생성하고, 이후 각 태스크로부터 진행 및 종료 보고서를 받는다(6단

계). 다음으로 클라이언트가 계산한 입력 스플릿 정보를 공유 파일시스템에서 읽어온다(7단 계). 그러고 나서 입력 스플릿별로 맵 태스크 객체를 생성하고, Job의 setNumReduceTask ( ) 메서드로 지정한 mapreduce.job.reduces 속성의 값(리듀서 수)만큼 맵 태스크 객체를 생성 한다. 이 시점에 각 태스크는 ID를 부여받는다. 애플리케이션 마스터는 맵리듀스 잡을 구성하는 태스크를 실행할 방법을 결정해야 한다. 잡의 크기가 작다면 애플리케이션 마스터는 태스크를 자신의 JVM에서 실행할 수도 있다. 이러한 상

7장 맵리듀스 작동 방법 255

황에 적합한 경우는 병렬 처리를 위해 새로운 컨테이너에 태스크를 할당하고 실행하는 오버헤드 가 단일 노드에서 순차적으로 실행하는 방식에 비해 유리하다고 판단될 때다. 이러한 잡을 우버 되었다 uberized 고 말하며, 우버 태스크로 실행된다고 하기도 한다. 어느 정도 돼야 잡이 작다고 할 수 있을까? 기본적으로 작은 잡이란 10개 미만의 매퍼와 하나 의 리듀서, HDFS 블록 하나보다 작은 크기의 입력을 말한다(각각 mapreduce.job.ubertask. maxmaps, mapreduce.job.ubertask.maxreduces, mapreduce.job.ubertask.maxbytes 속성

으로 설정하여 변경할 수 있다). 우버 태스크는 반드시 mapreduce.job.ubertask.enable 속성 을 true로 변경하여 명시적으로 활성화해야 한다(개별 잡 또는 클러스터에 적용 가능). 마지막으로, 태스크를 실행하기 전에 애플리케이션 마스터는 OutputCommitter의 setupJob ( ) 메서드를 호출한다. 기본 클래스인 FileOutputCommitter는 잡의 최종 출력 디렉터리와 태스 크 출력을 위한 임시 작업 공간을 생성한다. 커밋 프로토콜은 7.4.3절 ‘출력 커미터’에서 자세히 다룬다.

7.1.3 태스크 할당 잡을 우버 태스크로 실행하기 적합하지 않다면 애플리케이션 마스터는 리소스 매니저에 잡의 모 든 맵과 리듀스 태스크를 위한 컨테이너를 요청한다(8단계). 맵 태스크 요청이 먼저며 리듀스 태스크 요청보다 우선순위가 높다. 리듀스의 정렬 단계가 시작되기 전에 모든 맵 태스크가 완료 되어야 하기 때문이다(7.3절 ‘셔플과 정렬’ 참조). 전체 맵 태스크의 5%가 완료되기 전까지 리 듀스 태스크의 요청은 처리되지 않는다(10.3.5절의 ‘느린 리듀스 시작’ 참조). 리듀스 태스크는 클러스터의 어느 곳에서도 실행될 수 있지만, 맵 태스크 요청은 스케줄러가 최 대한 준수하는 데이터 지역성 data locality 제약이 있다(4.1.1절 ‘자원 요청’ 참조). 최적의 상황은 태스크가 데이터 로컬 data local 일 때다. 즉, 입력 스플릿이 저장된 노드에서 맵 태스크가 실행되 는 것을 의미한다. 대안으로는 랙 로컬 rack local 이 있다. 이는 동일한 랙에 속한 노드에서 맵 태스 크가 실행되지만 입력 스플릿이 있는 노드는 아닐 때다. 어떤 태스크는 데이터 로컬이나 랙 로 컬 어느 쪽도 아니어서 다른 랙에서 데이터를 가져오기도 한다. 개별 잡에 대한 잡 카운터를 살 펴보면 지역성 수준별로 몇 개의 태스크가 실행되었는지 확인할 수 있다. 또한 요청할 때 태스크를 위한 메모리 요구사항과 CPU 수를 명시한다. 기본적으로 1,024MB의

256 2부 맵리듀스

메모리와 가상 코어 1개를 각 맵과 리듀스 태스크에 할당한다. 이 값은 mapreduce.map.memory. mb, mapreduce.reduce.memory.mb, mapreduce.map.cpu.vcores, mapreduce.reduce.cpu. vcores 속성을 통해 잡 단위로 설정할 수 있다( 10.3.3절의 ‘YARN과 맵리듀스의 메모리 설

정’에서 설명한 최솟값과 최댓값 제약이 존재한다).

7.1.4 태스크 실행 리소스 매니저의 스케줄러가 특정 노드 상의 컨테이너를 위한 리소스를 태스크에 할당하면 애플 리케이션 마스터는 노드 매니저와 통신하며 컨테이너를 시작한다(9a와 9b 단계). 각 태스크는 YarnChild 메인 클래스를 가진 자바 애플리케이션으로 실행된다. 태스크를 실행하기 전에 잡

환경 설정, JAR 파일, 분산 캐시와 관련된 파일(10단계, 9.4.2절 ‘분산 캐시’ 참조) 등 필요한 리소스를 로컬로 가져와야 한다. 최종적으로 맵과 리듀스 태스크를 실제 실행한다( 11단계). YarnChild는 전용 JVM에서 실행된다. 따라서 사용자 정의 맵과 리듀스 함수(심지어 YarnChild

내에서)에서 버그가 발생하여 강제 종료 crash 되거나 멈추어도 hang 노드 매니저는 영향을 받지 않 는다. 각 태스크는 태스크 자체와 동일한 JVM에서 설정과 커밋 동작을 수행하며, 잡의 OutputCommi tter가 이를 결정한다( 7.4.3절 ‘출력 커미터’ 참조). 파일 기반의 잡에서 커밋 동작은 임시 위치

에서 최종 위치로 태스크 출력을 옮긴다. 커밋 프로토콜은 투기적 실행이 활성화되었을 때(7.4.2 절 ‘투기적 실행’ 참조) 중복 태스크 중 단 하나만 커밋하고 나머지는 버린다.

스트리밍 스트리밍은 사용자가 제공한 실행 파일을 시작하고 이와 통신하기 위한 목적을 가진 특별한 맵 과 리듀스 태스크를 실행한다(그림 7-2 ). 스트리밍 태스크는 표준 입출력 스트림을 통해 프로세스(어떤 언어로도 작성될 수 있음)와 통 신한다. 태스크가 실행되는 동안 자바 프로세스는 키-값 쌍을 외부 프로세스에 전달하고, 이를 사용자 정의 맵과 리듀스 함수로 처리한 뒤, 최종적으로 출력 키-값 쌍을 자바 프로세스에 돌려 준다. 따라서 노드 매니저 관점에서는 자식 프로세스가 마치 맵과 리듀스 코드를 스스로 실행한 것처럼 보일 것이다.

7장 맵리듀스 작동 방법 257

그림 7-2 스트리밍 실행에서 노드 매니저와 태스크 컨테이너에 대한 관계 스트리밍

시작 태스크 JVM

실행

또는

입력키/값

출력키/값

표준 입력

표준 출력

실행

스트리밍 프로세스

노드 매니저 노드

7.1.5 진행 상황과 상태 갱신 맵리듀스 잡은 수행 시간이 오래 걸리는 배치 잡으로, 수십 초에서 길게는 수 시간이 소요될 수 있다. 이렇게 상당한 시간이 걸리므로 사용자가 잡의 진행 상황에 대한 피드백을 받는 것은 매우 중요하다. 잡과 개별 태스크는 실행 중 running, 성공적으로 완료됨 successfully completed, 실패 failed와 같은 잡 또는 태스크의 상태, 맵과 리듀스의 진행 상황, 잡의 카운터 값, 상태 메시지 또는 명세 (사용자 코드에서 설정된) 등의 상태 정보를 가진다. 이러한 상태 정보는 잡의 진행 과정에서 수시로 변경되는데 이를 클라이언트에 전달할 방법은 무엇일까?

258 2부 맵리듀스

CHAPTER

8

맵리듀스 타입과 포맷

맵리듀스의 데이터 처리 모델은 단순하다. 맵과 리듀스 함수의 입력과 출력은 키-값 쌍으로 되 어 있다. 이 장에서는 맵리듀스 모델을 자세히 살펴볼 것이다. 특히 단순한 텍스트부터 구조화된 바이너리 객체까지 다양한 포맷의 데이터를 맵리듀스 모델에서 어떻게 처리하는지 살펴보겠다.

8.1 맵리듀스 타입 하둡 맵리듀스의 맵과 리듀스 함수의 형식은 다음과 같다. map: (K1, V1) list(K2, V2) reduce: (K2, list(V2)) list(K3, V3)

일반적으로 맵의 입력키와 값의 타입(K1과 V1 )은 맵의 출력 타입(K2와 V2 )과 다르다. 하지만 리듀스의 입력은 맵의 출력과 반드시 같은 타입이어야 하며, 리듀스의 출력 타입(K3과 V3 )과는 다를 수 있다. 맵리듀스 자바 API의 일반적인 형태는 다음과 같다. public class Mapper { public class Context extends MapContext { // ... }

279

protected void map(KEYIN key, VALUEIN value, Context context) throws IOException, InterruptedException { // ... } } public class Reducer { public class Context extends ReducerContext { // ... } protected void reduce(KEYIN key, Iterable values, Context context) throws IOException, InterruptedException { // ... } }

context 객체는 키-값 쌍을 내보낼 때 사용되며, 출력 타입으로 인자화된다. write ( ) 함수의 원형은 다음과 같다. public void write(KEYOUT key, VALUEOUT value) throws IOException, InterruptedException

Mapper와 Reducer는 별개의 클래스이므로 각각의 타입 매개변수는 서로 다른 유효 범위를 갖

는다. 따라서 동일한 이름의 KEYIN 타입 매개변수라도 Mapper와 Reducer의 실제 타입 인자는 서로 다를 수 있다. 예를 들어 이전 장에서 살펴본 최고 기온 예제에서 Mapper는 LongWritable 을 Reducer는 Text를 각각 KEYIN으로 사용했다. 마찬가지로 맵의 출력 타입과 리듀스의 입력 타입은 반드시 일치해야 하지만 자바 컴파일러가 이를 강제할 수는 없다. 타입 매개변수와 추상 타입의 이름은 다를 수 있지만(KEYIN과 K1 ), 그 형태는 동일해야 한다. 컴바인 함수는 Reducer의 구현체로, 리듀스 함수와 동일한 형태를 가진다. 컴바인 함수의 출력 타입은 중간 키-값 타입(K2와 V2 )이며, 컴바인의 출력은 리듀스 함수의 입력으로 전달된다. map: (K1, V1) list(K2, V2) combiner: (K2, list(V2)) list(K2, V2) reduce: (K2, list(V2)) list(K3, V3)

280 2부 맵리듀스

컴바인 함수와 리듀스 함수는 같은 경우가 많다. 이 경우 K3는 K2와 같고 V3는 V2와 같다. 파티션 함수는 컴바인의 중간 키-값 타입(K2와 V2 )을 처리한 후 파티션 인덱스를 반환한다. 실 제로 파티션은 순전히 키에 의해 결정된다(그 값은 무시한다). partition: (K2, V2)

integer

자바에서는 다음과 같이 구현한다. public abstract class Partitioner { public abstract int getPartition(KEY key, VALUE value, int numPartitions); }

이전 API에서 맵리듀스 함수의 원형 이전 API(부록 D 참조)를 보면 맵리듀스 원형은 거의 비슷하고 이전과 새로운 API의 제약 조건 도 정확히 같지만 K1, V1 등 타입 매개변수의 이름을 실제로 지정했다. public interface Mapper extends JobConfigurable, Closeable { void map(K1 key, V1 value, OutputCollector output, Reporter reporter) throws IOException; } public interface Reducer extends JobConfigurable, Closeable { void reduce(K2 key, Iterator values, OutputCollector output, Reporter reporter) throws IOException; } public interface Partitioner extends JobConfigurable { int getPartition(K2 key, V2 value, int numPartitions); }

이론은 이쯤에서 접고, 맵리듀스 잡을 설정하는 데 도움이 되는 방법을 살펴보자. [표 8-1]은 새 로운 API의 환경 설정 옵션을 요약한 것이다([표 8-2]는 이전 API ). 표는 타입을 결정하는 속 성과 설정된 타입의 상호 호환성으로 크게 나뉘어 있다. 입력 타입은 InputFormat을 통해 설정된다. 예를 들어 TextInputFormat은 LongWritable 타

8장 맵리듀스 타입과 포맷 281

입의 키와 Text 타입의 값을 생성한다. 다른 입력 타입은 Job의 메서드(이전 API의 JobConf )를 명시적으로 호출하여 설정한다. 중간 타입을 명시적으로 설정하지 않으면 자동으로 (최종) 출 력 타입과 같게 되어 있다. 출력의 기본 타입은 LongWritable과 Text다. 따라서 만약 K2와 K3 가 같다면 setMapOutputKeyClass ( )를 호출할 필요가 없다. setOutputKeyClass ( )에 정의 된 타입으로 다시 설정되기 때문이다. 마찬가지로 V2와 V3가 같다면 setOutputValueClass ( ) 만 사용하면 된다. 중간과 최종 출력 타입을 설정하는 함수가 각각 존재하는 것이 이상하게 보일 수 있다. 왜 매퍼 와 리듀서의 조합으로 이러한 타입을 결정할 수 없는 것일까? 해답은 자바 제네릭 1의 한계와 관 련이 있다. 즉, 타입 삭제 type erasure 2 때문에 런타임에 타입 정보가 항상 존재하지 않을 수 있으 므로 타입 정보를 명시적으로 하둡에 제공해야 한다. 또한 컴파일 타임에 환경 설정을 점검하지 않기 때문에 맵리듀스 잡과 호환되지 않는 타입을 설정할 가능성도 있다. [표 8-1] 하단에 맵리 듀스 타입과 반드시 호환되어야 하는 설정이 있다. 타입 충돌은 잡을 실행하는 런타임에 발견된 다. 이러한 이유 때문에 먼저 작은 데이터로 테스트 잡을 실행하여 타입 호환성에 문제가 없는지 점검하는 것이 좋다. 표 8-1 새로운 API에서 맵리듀스 타입 설정 속성

Job 설정 메서드

입력 타입

중간 타입

출력 타입

K1

V1

K2

K3





V2

V3

타입 설정 속성:

mapreduce.job.inputformat. class

setInputFormatClass()

mapreduce.map.output.key. class

setMapOutputKeyClass()

mapreduce.map.output.value. class

setMapOutputValueClass()

mapreduce.job.output.key. class

setOutputKeyClass()

mapreduce.job.output.value. class

setOutputValueClass()









타입과 반드시 일치해야 하는 속성:

mapreduce.job.map.class

setMapperClass()









1 옮긴이_ 클래스에 사용할 타입을 디자인할 때 지정하는 것이 아니라 클래스를 사용할 때 지정하는 기법 2 옮긴이_ 타입 삭제는 JVM 레벨의 호환성을 위해 컴파일 타임에 제네릭 타입 정보( , , ...)를 삭제해버리는 기능이다.

282 2부 맵리듀스

CHAPTER

9

맵리듀스 기능

이 장에서는 카운터, 정렬, 데이터셋 조인 등 맵리듀스의 고급 기능을 살펴본다.

9.1 카운터 우리는 가끔 분석 작업과는 별도로 분석하려는 데이터 자체에 대해 궁금할 때가 있다. 예를 들어 부적절한 레코드 수를 세는 중 전체 데이터셋에서 이러한 레코드가 차지하는 비율이 굉장히 높 다는 사실을 알게 되면 왜 그렇게 많은 레코드가 잘못되었는지 즉시 확인하고 싶을 것이다. 아마 프로그램 일부의 버그 때문에 부적절한 레코드가 많을 수도 있고, 실제로 데이터의 품질에 문제 가 있어서 이러한 레코드가 많을 수도 있다. 확인을 한 후에는 의미 있는 분석을 하기에 충분한 정상 레코드를 확보하기 위해 데이터셋의 크기를 늘리고 싶을 것이다. 카운터는 잡에 대한 통계 정보를 수집하는 유용한 채널로, 데이터 품질의 통제나 애플리케이션 수준의 통계를 제공한다. 또한 카운터는 문제 진단에 매우 유용하다. 맵이나 리듀스 태스크에 로 그 메시지를 넣어서 특정 조건의 발생을 기록하는 것보다는 카운터를 사용하는 것이 더 좋다. 게 다가 큰 분산 잡의 로그 출력을 일일이 확인하는 것보다는 그냥 카운터 값을 확인하는 것이 훨씬 수월하다. 카운터 대신 로그를 사용하면 수많은 로그파일로부터 특정 조건에 맞는 레코드를 모 두 추출하는 프로그램을 별도로 작성해야 하는 어려움이 있다.

321

9.1.1 내장 카운터 하둡은 모든 잡에 대해 내장 카운터를 제공하며 이들은 다양한 메트릭 metric (지표)을 알려준다. 예를 들어 처리한 데이터의 바이트와 레코드 수를 세는 카운터가 있으면 입력과 출력 데이터의 크기가 예상과 맞는지 확인할 수 있다. 카운터는 여러 그룹으로 나누어지며, [표 9-1]에서 내장 카운터 그룹을 확인할 수 있다. 표 9-1 내장 카운터 그룹 그룹

이름/열거자

참고

맵리듀스 태스크 카운터

org.apache.hadoop.mapreduce.TaskCounter

[표 9-2]

파일시스템 카운터

org.apache.hadoop.mapreduce.FileSystemCounter

[표 9-3]

FileInputFormat 카운터

org.apache.hadoop.mapreduce.lib.input. FileInputFormatCounter

[표 9-4]

FileOutputFormat 카운터

org.apache.hadoop.mapreduce.lib.output. FileOutputFormatCounter

[표 9-5]

잡 카운터

org.apache.hadoop.mapreduce.JobCounter

[표 9-6]

내장 카운터 그룹은 태스크가 진행되면서 갱신되는 태스크 카운터 또는 잡이 진행되면서 갱신되 는 잡 카운터를 포함하고 있다.

태스크 카운터 태스크 카운터는 각 태스크가 실행될 때 해당 태스크에 대한 정보를 수집한 후 잡의 모든 태스크 에 대한 값을 취합하여 최종 결과를 알려준다. 예를 들어 MAP_INPUT_RECORDS 카운터는 먼저 각 맵 태스크가 읽어 들이는 입력 레코드 수를 센 후 잡에 속한 모든 맵 태스크의 값을 집계하므 로 최종값은 잡의 총 입력 레코드 수가 된다. 태스크 카운터는 각 태스크 시행마다 관리되고 주기적으로 애플리케이션 마스터에 전송되므로 결국 전역적으로 수집된다(7.1.5절 ‘진행 상황과 상태 갱신’ 참조). 태스크 카운터는 마지막 전 송 이후에 변경된 수치만 보내는 것이 아니라 보낼 때마다 누적된 전체 수치를 전송하므로 메 시지 유실로 인한 오류를 방지할 수 있다. 또한 잡 실행 도중 태스크가 실패하면 카운터는 중단 된다. 카운터의 값은 잡이 성공적으로 끝나야 의미가 있다. 하지만 어떤 카운터는 태스크 진행 도중

322 2부 맵리듀스

에도 의미 있는 진단 정보를 제공하므로 웹 UI를 통해 이를 모니터링하는 것도 유용하다. 예를 들어 PHYSICAL_MEMORY_BYTES, VIRTUAL_MEMORY_BYTES, COMMITTED_HEAP_BYTES는 특정 태스 크의 메모리 사용량 변화 정보를 실시간으로 보여준다. 내장 태스크 카운터는 맵리듀스 태스크 카운터 그룹([표 9-2])과 파일 관련 카운터 그룹([표

9-3], [표 9-4], [표 9-5])에 속한 카운터를 포함한다. 표 9-2 내장 맵리듀스 태스크 카운터 카운터

설명

맵 입력 레코드

잡의 모든 맵이 처리한 입력 레코드 수. RecordReader로 한 레코드를

(MAP_INPUT_RECORDS)

읽은 후 프레임워크를 통해 맵의 map() 메서드로 전달할 때마다 증가한 다.

스플릿 원시 바이트

맵이 읽은 입력 스플릿 객체의 바이트 수. 이 객체는 스플릿 데이터 자체가

(SPLIT_RAW_BYTES)

아닌 스플릿의 메타데이터(즉, 파일의 오프셋과 길이)이므로 전체 크기는 작다.

맵 출력 레코드

잡의 모든 맵이 생성한 출력 레코드 수. 맵의 OutputCollector 의

(MAP_OUTPUT_RECORDS)

collect() 메서드를 호출할 때마다 증가한다.

맵 출력 바이트

잡의 모든 맵이 생성한 압축되지 않은 바이트 수. 맵의 OutputCollector

(MAP_OUTPUT_BYTES)

의 collect() 메서드를 호출할 때마다 증가한다.

맵 출력 실질 바이트

실제로 디스크에 쓰여진 맵 출력 바이트 수. 맵의 출력을 압축할 때만 카운

(MAP_OUTPUT_MATERIALIZED_BYTES)

터 값에 반영된다.

컴바인 입력 레코드

잡의 모든 컴바이너(존재할 때만)가 처리한 입력 레코드 수. 컴바이너의

(COMBINE_INPUT_RECORDS)

반복자가 값을 읽을 때마다 증가한다. 이 수치는 컴바이너가 처리한 값의 개수다. 유일한 키 그룹의 개수를 제공하지 않는 이유는 컴바이너에 키별 로 하나의 그룹만 존재하는 것은 아니기 때문이다. 따라서 유용한 지표가 될 수 없다(2.4.2절 ‘컴바이너 함수’와 7.3절 ‘셔플과 정렬’ 참조).

컴바인 출력 레코드

잡의 모든 컴바이너(존재할 때만)가 생성하는 출력 레코드 수. 컴바이너의

(COMBINE_OUTPUT_RECORDS)

OutputCollector의 collect() 메서드를 호출할 때마다 증가한다.

리듀스 입력 그룹

잡의 모든 리듀서가 처리하는 유일한 키 그룹 수. 프레임워크가 리듀서의

(REDUCE_INPUT_GROUPS)

reduce() 메서드를 호출할 때마다 증가한다.

리듀스 입력 레코드

잡의 모든 리듀서가 처리하는 입력 레코드 수. 리듀서의 반복자가 값을 읽

(REDUCE_INPUT_RECORDS)

을 때마다 증가한다. 리듀서가 입력을 모두 처리했다면 이 수치는 맵의 출 력 레코드 수와 일치해야 한다.

리듀스 출력 레코드

잡의 모든 맵이 생성하는 리듀스 출력 레코드 수. 리듀서의 Output

(REDUCE_OUTPUT_RECORDS)

Collector의 collect() 메서드를 호출할 때마다 증가한다.

리듀스 셔플 바이트

셔플에 의해서 리듀서로 복사된 맵 출력 바이트 수

(REDUCE_SHUFFLE_BYTES)

9장 맵리듀스 기능 323

카운터

설명

디스크에 쓰여진 레코드

잡의 모든 맵과 리듀스 태스크에서 디스크로 쓴 레코드 수

(SPILLED_RECORDS)

CPU 밀리초(CPU_MILLISECONDS)

/proc/cpuinfo에 기록된 태스크의 밀리초 단위 누적 CPU 시간

물리 메모리 바이트

/proc/meminfo에 기록된 태스크가 사용한 물리 메모리 바이트

(PHYSICAL_MEMORY_BYTES) 가상 메모리 바이트

/proc/meminfo에 기록된 태스크가 사용한 가상 메모리 바이트

(VIRTUAL_MEMORY_BYTES) 커밋된 힙 바이트

Runtime.getRuntime().totalMemory()의 결과인 JVM에서 사용

(COMMITTED_HEAP_BYTES)

가능한 전체 메모리 바이트 크기

GC 밀리초 시간 (GC_TIME_MILLIS)

GarbageCollectorMXBean.getCollectionTime()의 결과인 태

셔플된 맵(SHUFFLED_MAPS)

셔플에 의해 리듀서로 전송된 맵 출력 파일 수(7.3절 ‘셔플과 정렬’ 참조)

실패한 셔플(FAILED_SHUFFLE)

셔플 진행 중에 복사에 실패한 맵 출력 수

병합된 맵 출력(MERGED_MAP_OUTPUTS)

셔플의 리듀서 측에서 병합된 맵 출력 수

스크의 밀리초 단위 가비지 컬렉션 경과 시간

표 9-3 내장 파일시스템 태스크 카운터 카운터

설명

파일시스템에서 읽은 바이트

맵과 리듀스 태스크가 파일시스템에서 읽은 바이트 수. 각 파일시스템마

(BYTES_READ)

다 카운터가 존재하며 로컬, HDFS, S3 등의 파일시스템이 있다.

파일시스템에 쓴 바이트(BYTES_WRITTEN) 맵과 리듀스 태스크가 파일시스템에 쓴 바이트 수 파일시스템 읽기 동작(READ_OPS)

맵과 리듀스 태스크가 파일시스템에 수행한 읽기 동작(예를 들면 열기, 파

파일시스템 대량 읽기 동작

맵과 리듀스 태스크가 파일시스템에 수행한 대량 읽기 동작(예를 들면 큰

(LARGE_READ_OPS)

디렉터리를 나열) 수

파일시스템 쓰기 동작(WRITE_OPS)

맵과 리듀스 태스크가 파일시스템에 수행한 쓰기 동작(예를 들면 생성, 추

일 상태 보기) 수

가) 수

표 9-4 내장 FileInputFormat 태스크 카운터 카운터

설명

읽은 바이트(BYTES_READ)

맵 태스크가 FileInputFormat을 통해 읽은 바이트 수

표 9-5 내장 FileOutputFormat 태스크 카운터 카운터

설명

쓴 바이트(BYTES_READ)

맵 태스크(맵-단독 잡에서)나 리듀스 태스크가 FileOutputFormat을 통해 쓴 바이트 수

324 2부 맵리듀스

CHAPTER

10

하둡 클러스터 설정

이 장에서는 다수의 머신으로 구성된 클러스터 환경에서 하둡을 구동하기 위한 설정 방법을 설 명한다. 하둡 시스템을 배울 때 단일 컴퓨터 환경에서 HDFS, 맵리듀스, YARN을 구동하는 것 도 좋지만, 실무에 활용하기 위해서는 다수의 노드로 구성된 클러스터 환경이 필요하다. 하둡 클러스터를 구축하는 방법은 매우 다양하다. 자체적으로 구축하는 방법과 하드웨어를 임 대하거나 클라우드 호스팅 방식으로 제공되는 하둡 서비스를 이용하는 방법으로 크게 구분할 수 있다. 호스팅 방식은 여기에 나열하기 힘들 정도로 많은 종류가 있으며, 하둡 클러스터를 자 체적으로 구축하는 방법도 다음과 같이 몇 가지 설치 옵션이 있다. ●

아파치 타르볼 아파치 하둡 프로젝트 및 관련 프로젝트는 각 릴리즈별로 바이너리 타르볼과 소스를 제공한다. 바이너리 타르 볼 설치 방식은 사용자에게 높은 유연성을 제공하지만, 사용자가 설치 파일, 설정 파일, 로그파일의 위치를 직 접 결정해야 하고 정확한 권한 설정을 해야 하는 등 상당한 노력이 필요하다.



패키지 아파치 빅톱 프로젝트1 와 하둡 벤더(클라우데라, 호튼웍스 등)는 RPM과 데비안 패키지를 제공한다. 패키지 는 타르볼에 비해 많은 장점이 있다. 패키지는 일관된 파일시스템 레이아웃을 제공하며 스택 방식(함께 잘 작 동하는 하둡과 하이브 버전을 알 수 있다)의 호환성 테스트를 거쳤다. 또한 퍼펫 Puppet 과 같은 설정 관리 도구 를 함께 사용할 수 있다.

1 http://bigtop.apache.org/

363

하둡 클러스터 관리 도구



클라우데라 매니저 Cloudera Manager 와 아파치 암바리 Apache Ambari 는 전체 수명 주기에 걸쳐 하둡 클러스터의 설 치 및 관리 기능을 제공하는 전용 도구다. 이러한 관리 도구는 간단한 웹 사용자 인터페이스를 제공하며, 하둡 클러스터를 구축하려는 사용자와 운영자에게 권장되는 방식이다. 이러한 도구들은 하둡 운영에 필요한 많은 운영 지식을 내포하고 있다. 예를 들면 하둡 설정에 적합한 기본값을 선택할 때 하드웨어 프로파일을 기반으로 한 경험적 수치를 제공한다. 하둡 클러스터 관리 도구는 고가용성(HA )이나 보안 하둡과 같은 복잡한 설치 작 업을 지원하기 위해 충분히 검증된 위자드 wizard (구성 지원 기능)를 제공하므로 단시간 내에 작업 클러스터 구 축이 가능하다. 마지막으로, 이러한 관리 도구는 다른 설치 방식이 제공하지 않는 통합 모니터링, 로그 검색, 롤링 업그레이드(중단 없이 클러스터를 업그레이드)와 같은 추가 기능도 제공한다.

이 장과 다음 장에서는 기본적인 클러스터를 구축하고 운영할 때 필요한 충분한 정보를 제공할 것이다. 여러분이 이미 하둡 클러스터 관리 도구를 사용하고 있거나 설치 및 관리를 원활히 지원 하는 서비스를 이용하고 있더라도 운영 관점에서 하둡의 작동 원리와 관련된 귀중한 정보를 배 우는 것은 실무에 큰 도움이 될 것이다. 좀 더 상세한 내용을 알고 싶다면 에릭 새머 Eric Sammer 의 『실전 하둡 운용 가이드』(한빛미디어, 2013 )2를 읽어볼 것을 적극 추천한다.

10.1 클러스터 명세 하둡은 범용 하드웨어에서 구동되도록 설계되었다. 이것은 특정 제조사에서 제공하는 비싼 전용 장비에 종속될 필요가 없다는 것을 의미한다. 즉, 다양한 벤더로부터 쉽게 구할 수 있는 표준화 된 범용 하드웨어를 구입하여 자체적인 클러스터를 구성할 수 있다. ‘범용 commodity ’이라는 것이 ‘저급 low-end ’을 의미하는 것은 절대 아니다. 흔히 말하는 저급의 컴 퓨터는 값싼 부품을 사용하는데, 범용에 속하는 좀 더 비싼 컴퓨터에 비해 고장날 확률이 높다. 수십, 수백 혹은 수천 대의 저급 컴퓨터를 운영하면 값싼 부품 덕분에 초기 비용은 절약되겠지 만, 높은 고장률로 인해 높은 유지비용이 발생하여 결국 절약 실패 false economy 상황에 빠지게 된다. 한편으로 대용량 데이터베이스급의 컴퓨터도 비용 대비 성능이 좋지 않으므로 역시 권장 하지 않는다. 소수의 컴퓨터만으로도 중급 범용 컴퓨터로 구성된 클러스터와 비슷한 성능을 낼 수 있지만, 클러스터 하드웨어에서 컴퓨터 한 대가 차지하는 비율이 높기 때문에 컴퓨터 한 대의 장애가 클러스터에 미치는 영향은 훨씬 크다.

2 『Hadoop Operations』(O’Reilly, 2012)(http://shop.oreilly.com/product/0636920025085.do)

364 3부 하둡 운영

하드웨어는 시간이 지나면 바로 구식이 되므로 컴퓨터의 사양을 명시하는 것이 크게 의미는 없 겠지만, 2014년에 HDFS 데이터노드와 YARN 노드 매니저를 구동하기 위해 선택한 전형적인 컴퓨터의 사양은 다음과 같다. 프로세서: 헥사/옥토-코어 3GHZ CPU 2개



메모리: 64~512GB ECC RAM 3



스토리지: 1~4TB SATA 디스크 12~24개



네트워크: 링크 통합 기능을 지원하는 기가비트 이더넷



지금 사용하고 있는 클러스터의 하드웨어 사양과 많이 다를 수 있다. 하둡은 다중 코어와 디스크 를 사용할 수 있도록 설계되어 있으므로 높은 사양의 하드웨어를 이용하면 더 좋은 성능을 얻을 수 있다.

RAID를 사용하는 것은 어떨까? HDFS 클러스터는 데이터노드 저장소로 RAID Redundant Array of Independent Disks 를 사용하더라도 얻을 수 있는 이익이 거의 없다(메타데이터의 손상을 막기 위해 네임노드의 디스크에 RAID를 사용하 는 것은 권장한다). HDFS는 각 블록을 여러 대의 노드에 복제하는 기능을 제공하므로 RAID 장 치가 지원하는 중복성 redundancy 은 필요하지 않다. 더욱이 성능 향상을 위해 흔히 사용하는 RAID 스트라이핑 striping (RAID 0) 방식은 HDFS 블록 을 모든 디스크에 라운드 로빈 round-robin (순차 순환) 방식으로 배열하는 HDFS의 JBOD Just a Bunch Of Disks

방식보다 더 느리다는 것이 밝혀졌다. ‘RAID 0’의 읽기와 쓰기 동작은 RAID 배열의 가

장 느린 디스크의 속도에 의해 제한받기 때문이다. 반면 JBOD는 각 디스크가 독립적으로 동작 하므로 디스크 동작의 평균 속도는 가장 느린 디스크보다 빠르다. 실제 환경에서 디스크의 성능 은 같은 기종이라도 종종 큰 편차를 보인다. 야후 클러스터에서 수행한 벤치마크 4 에서 JBOD는 ‘RAID 0’보다 Gridmix에서는 10%, HDFS 쓰기에서는 30% 정도 빨랐다. 마지막으로, 만약 JBOD 환경에서 디스크 하나가 고장나면 HDFS는 고장난 디스크 없이도 계속 동작할 수 있지만, RAID는 하나의 디스크 고장이 전체 디스크 배열을 불능 상태로 만들 수 있다.

3 하둡을 운영하는 여러 명의 사용자가 ECC가 아닌 메모리를 사용한 하둡 클러스터에서 체크섬 오류가 발생한 것을 보고했다. 따라서 ECC 메모리를 권장한다. 또한 하둡을 기반으로 작동하는 많은 에코시스템이 메모리를 상당히 많이 요구하므로 최소 128GB 이상의 메 모리를 추천한다. 4 http://markmail.org/message/xmzc45zi25htr7ry

10장 하둡 클러스터 설정 365

10.1.1 클러스터 규모 결정 ‘클러스터의 규모는 얼마나 커야 할까?’ 이 질문에 대한 정확한 답은 없다. 하지만 클러스터를 작은 규모(가령 10노드)로 시작한 후 저장 및 계산 능력에 대한 요구가 증가함에 따라 클러스 터의 규모를 쉽게 증가시킬 수 있다는 것이 바로 하둡의 장점이다. 따라서 ‘얼마나 빨리 클러스 터가 커질 것인가?’라고 묻는 것이 더 좋은 질문이다. 저장소의 용량을 고려한다면 이 질문에 대 한 감이 올 것이다. 예를 들어 하루에 데이터가 1TB씩 증가하고 HDFS의 복제인수가 3으로 설정되어 있다면 하루 에 3TB의 저장소가 필요할 것이다. 임시 파일과 로그를 위한 공간(약 30%)을 추가로 고려하 면 대략 1주일에 한 대의 컴퓨터(2014년 기준)가 필요하다는 계산이 나온다. 여러분이 실제로 매주 한 대의 컴퓨터를 사서 클러스터에 추가하는 일은 거의 없을 것이다. 여기서 이런 계산을 해보는 이유는 클러스터의 규모를 산정하는 감각을 심어주기 위해서다. 이 예제에 나오는 클러 스터는 2년치 데이터를 보유하기 위해 약 100대의 컴퓨터가 필요하다.

마스터 노드 시나리오 네임노드, 보조 네임노드, 리소스 매니저, 히스토리 서버와 같은 마스터 데몬을 어떤 노드에서 실행할지 결정하는 방법은 매우 다양하며 클러스터의 규모에 따라서도 다르다. 대략 10대 정도 수준의 작은 클러스터에서는 네임노드와 리소스 매니저를 단일 마스터 컴퓨터에서 동시에 구동 해도 된다(단, 네임노드의 메타데이터 사본이 원격 파일시스템에 최소 한 개 이상 저장되어 있 어야 한다). 하지만 클러스터의 전체 노드 수가 계속 증가한다면 네임노드와 리소스 매니저를 각기 다른 컴퓨터로 분리해야 할 필요가 있다. 네임노드는 전체 네임스페이스의 파일 및 블록에 대한 메타데이터를 모두 메모리에 보관해야 하 므로 상당한 용량의 메모리가 필요하다. 보조 네임노드는 가끔씩 실행되지만 체크포인트 작업을 수행할 때 네임노드와 거의 비슷한 용량의 메모리가 필요하다(11.1.1절의 ‘파일시스템 이미지 와 에디트 로그’ 참조). 따라서 파일의 수가 매우 많은 파일시스템은 단일 컴퓨터에서 주 네임노 드와 보조 네임노드를 동시에 실행하면 물리 메모리가 부족할 수 있다. 시스템 자원에 대한 요구사항 이외에, 마스터 데몬을 각기 다른 컴퓨터로 분리하는 가장 큰 이유 는 고가용성 때문이다. HDFS와 YARN은 마스터 데몬을 활성-대기 쌍으로 실행할 수 있는 설 정(고가용성)을 지원한다. 활성 마스터에 장애가 발생하면 별도의 하드웨어에서 구동되는 대

366 3부 하둡 운영

기 마스터가 활성 마스터의 역할을 대신 수행하므로 무중단 서비스가 가능하다. HDFS에 고가 용성 설정을 하면 대기 네임노드가 기존에 보조 네임노드가 맡았던 체크포인트 작업을 대신 수 행한다. 따라서 대기 네임노드와 보조 네임노드를 동시에 구동할 필요는 없다. 하둡의 고가용성 설정이나 구동 방법은 이 책에서 다루지 않는다. 자세한 내용은 하둡 웹사이트 및 하둡 벤더의 문서를 참고하기 바란다.5

10.1.2 네트워크 토폴로지 일반적인 하둡 클러스터 아키텍처는 [그림 10-1]처럼 두 단계의 네트워크 토폴로지 topology 로 구성된다. 랙 하나에 대략 30~40대의 서버(다이어그램에서는 3대만 표시했다)와 한 대의

10Gb 스위치가 있으며, 코어 스위치나 라우터로 가는 업링크 uplink 는 최소 10Gb 이상의 대역 폭을 갖는다. 같은 랙에 있는 노드 간의 대역폭의 총합은 다른 랙의 노드 간의 대역폭보다 훨씬 크다는 점에 주목하자. 그림 10-1 하둡 클러스터를 구성하는 일반적인 두 단계 네트워크 아키텍처

스위치1

랙1

랙2

노드1

노드2

노드3

노드4

노드5

노드6

디스크

디스크

디스크

디스크

디스크

디스크

5 옮긴이_ 『실전 하둡 운용 가이드』(한빛미디어, 2013)의 ‘네임 노드 고가용성’ 부분을 참고하라.

10장 하둡 클러스터 설정 367

랙 인식 기능 하둡의 성능을 최대로 끌어내기 위해서는 하둡에 네트워크 토폴로지를 설정해야 한다. 물론 전 체 클러스터가 단일 랙에서만 구동된다면 기본 설정과 동일하므로 특별히 할 일은 없다. 하지만 여러 개의 랙으로 구성된 클러스터를 운영한다면 각 노드를 랙에 매핑한 네트워크 토폴로지 정 보를 설정해주는 것이 좋다. 이처럼 네트워크 토폴로지를 설정하고 나면, 맵리듀스 태스크를 여 러 대의 노드에 할당할 때 하둡은 랙 외부보다 더 넓은 대역폭을 사용할 수 있는 랙 내부에서 데 이터가 전송되도록 한다. 또한 HDFS는 성능과 장애 복구의 균형을 유지하면서 복제소 replica 의 배치 작업을 지능적으로 수행할 수 있다. 노드와 랙 같은 네트워크의 위치 정보는 트리 형태로 표현되며, 각 위치 사이의 네트워크 ‘거리’ 를 반영할 수 있다. 네임노드는 각 블록의 복제소를 결정할 때 네트워크 위치 정보를 사용한다 (3.6.1절의 ‘네트워크 토폴로지와 하둡’ 글상자 참조). 또한 맵리듀스의 스케줄러는 맵 태스크 의 입력으로 사용될 가장 가까운 복제소(3개의 복제소 중 하나)를 찾을 때 네트워크 위치 정보 를 이용한다. [그림 10-1]의 네트워크에서 랙의 토폴로지는 두 개의 네트워크 위치 정보인 /스위치1/랙1과 / 스위치1/랙2로 기술되었다. 이 클러스터를 보면 상위 단계의 스위치가 하나밖에 없으므로 위치 정보를 /랙1과 /랙2로 단순화할 수 있다. 클러스터 환경에서 하둡 설정을 할 때 노드 주소와 네트워크 위치를 매핑한 정보를 명시하는 것 이 좋다. 매핑 정보는 자바 인터페이스인 DNSToSwitchMapping에 기술하며, 다음과 같이 작성 한다. public interface DNSToSwitchMapping { public List resolve(List names); }

매개변수 names는 IP 주소의 목록이고 반환값은 이에 대응하는 네트워크 위치 정보에 대한 문 자열 목록이다. net.topology.node.switch.mapping.impl 설정 속성에 인터페이스 구현체인 DNStoSwitchMapping을 정의하며, 네임노드와 리소스 매니저는 이를 이용하여 워커 노드의

네트워크 위치 정보를 파악한다. 그림의 네트워크에서 노드1, 노드2, 노드3은 /랙1에 매핑되고, 노드4, 노드5, 노드6은 /랙2에 매핑된다. 368 3부 하둡 운영

CHAPTER

11

하둡 관리

앞 장에서는 하둡 클러스터를 설정하는 방법을 다루었다. 이 장에서는 하둡 클러스터를 원활히 운영하기 위한 절차를 살펴보겠다.

11.1 HDFS 11.1.1 영속적인 데이터 구조 하둡 관리자는 HDFS의 컴포넌트인 네임노드, 보조 네임노드, 데이터노드가 영속적으로 사용 하는 데이터를 디스크에 구성하는 방식을 이해할 필요가 있다. 어떤 파일이 어느 위치에 있는지 아는 것은 장애를 진단하고 해결하는 데 도움이 되기 때문이다.

네임노드 디렉터리 구조 운영 중인 네임노드의 디렉 터리 구조는 오른쪽 그림과 같다.

403

10장에서 살펴본 dfs.namenode.name.dir 속성은 디렉터리의 목록으로, 각 디렉터리에는 동 일한 내용이 복제되어 있다는 점을 상기하자. 이런 메커니즘은 특히 이 디렉터리 중 하나가 NFS 마운트로 구성되어 있다면(권장사항) 장애복구 resilience 능력을 제공한다.

VERSION은 자바 속성 파일로, 구동 중인 HDFS 버전에 대한 정보를 포함한다. 일반적인 파일 의 내용은 다음과 같다. #Mon Sep 29 09:54:36 BST 2014 namespaceID=1342387246 clusterID=CID-01b5c398-959c-4ea8-aae6-1e0d9bd8b142 cTime=0 storageType=NAME_NODE blockpoolID=BP-526805057-127.0.0.1-1411980876842 layoutVersion=-57

layoutVersion은 HDFS의 영속적인 데이터 구조의 버전을 음의 정수로 정의한다. 이 숫자는

하둡 배포판의 릴리즈 버전과는 아무런 관계가 없다. 레이아웃이 변경될 때마다 버전 숫자는 줄 어든다(예를 들어 -57 다음 버전은 -58이다). 새로운 네임노드(또는 데이터노드)의 저장소 레이아웃이 너무 오래된 버전이면 제대로 동작하지 않기 때문에 레이아웃이 변경되면 HDFS를 업그레이드해야 한다. HDFS를 업그레이드하는 방법은 11.3.3절 ‘업그레이드’에서 다룬다. namespaceID는 파일시스템 네임스페이스의 유일한 식별자로, 네임노드를 처음 포맷할 때 생성

된다. clusterID는 HDFS 클러스터 전체의 유일한 식별자로, 특히 HDFS 페더레이션 federation 을 구성할 때 중요한 역할을 한다(3.2.4절 ‘HDFS 페더레이션’ 참조). HDFS 페더레이션을 사 용하는 클러스터는 여러 개의 네임스페이스로 구성되며 각 네임스페이스는 하나의 네임노드가 관리한다. blockpoolID는 네임노드가 관리하는 네임스페이스의 모든 파일이 들어 있는 블록 풀 의 유일한 식별자다. cTime 속성은 네임노드 저장소의 생성 시간을 표시한다. 새롭게 포맷된 저장소의 cTime 속성 값

은 항상 0이다. 이후 파일시스템이 업그레이드되면 cTime 속성의 값은 갱신된 시점의 타임스탬 프로 변경된다. storageType은 해당 저장소의 디렉터리가 네임노드의 데이터 구조를 가진다는 것을 나타낸다.

in_use.lock 파일은 네임노드가 저장소 디렉터리를 잠그는 데 사용하는 잠금 파일 lock file 이다. 이 파일은 다른 네임노드의 인스턴스가 동일한 저장소 디렉터리에서 실행되는 것(파일시스템의

404 3부 하둡 운영

손상)을 방지하는 역할을 한다. 네임노드 저장소 디렉터리에는 edits, fsimage, seen_txid와 같은 파일이 있다. 이러한 파일 들이 어디에 사용되는지 이해하려면 네임노드의 동작 방식을 좀 더 깊이 알아보아야 한다.

파일시스템 이미지와 에디트 로그 파일시스템의 클라이언트가 쓰기 동작(파일 생성이나 이동)을 하면 일단 에디트 로그에 해당 내역이 기록된다. 네임노드는 파일시스템의 메타데이터를 인메모리 in-memory (파일과 메모리 양 쪽에 데이터를 유지하는 방식)로 관리하는데, 에디트 로그를 먼저 변경한 후 메모리상의 메타 데이터도 변경한다. 클라이언트의 읽기 요청에는 인메모리 메타데이터만 사용된다. 에디트 로그는 개념적으로는 단일 개체지만 디스크에서는 다수의 파일로 관리된다. 각 파일을 세그먼트라고 하며 접두사 edits와 트랜잭션 ID를 의미하는 접미사로 구성되어 있다. 한번에 하나의 파일만 쓰기를 위해 열리며(예제에서 에디트 로그파일의 이름은 edits_inprogress_

0000000000000000020이다), 네임노드는 쓰기 동작이 끝날 때마다 성공했다는 결과를 클라 이언트에 알려주기 전에 에디트 로그를 플러시 flush 하여 동기화시킨다. 네임노드는 여러 개의 디 렉터리에 에디트 로그를 기록할 수 있기 때문에 변경 내역을 모든 에디트 로그 복제본 파일에 플 러시하고 동기화한 후에 성공했다는 것을 알려주어야 한다. 이는 어떠한 기계적 결함에도 데이 터가 손실되지 않도록 하기 위함이다. 각각의 fsimage 파일은 파일시스템 메타데이터의 완전하고 영속적인 체크포인트다(fsimage 파일의 접미사는 파일시스템 이미지의 마지막 트랜잭션을 나타낸다). 파일시스템에서 쓰기 동 작이 있을 때마다 fsimage 파일을 변경하지는 않는데, fsimage 파일이 기가바이트 크기로 커 지면 성능이 매우 느려지기 때문이다. fsimage 파일을 바로 갱신하지 않더라도 하둡의 장애복 구 능력이 저하되는 것은 아니다. 만약 네임노드에 장애가 발생하면 먼저 fsimage를 메모리에 로드하고 에디트 로그파일에서 특정 지점 이후에 발생한 변경 내역들을 메모리에 반영하여 파 일시스템의 메타데이터를 최신의 상태로 복원할 수 있기 때문이다. 실제로 이와 동일한 과정이 네임노드 서비스가 시작될 때 수행된다(11.1.2절 ‘안전 모드’ 참조). 앞에서 설명한 것처럼 에디트 로그파일은 무한정 커질 수 있다(여러 개의 물리적 edits 파일로 분산되더라도). 에디트 로그파일이 커지더라도 네임노드가 구동 중일 때는 특별한 영향을 주지 않는다. 하지만 네임노드가 재시작될 경우 매우 큰 에디트 로그의 변경 내역을 모두 적용하기 위

11장 하둡 관리 405

해서는 상당한 시간이 소요된다. 이 작업을 수행하는 동안은 파일시스템을 사용하지 못하는 원 치 않는 상황에 처하게 된다. NOTE_ 각 fsimage 파일은 파일시스템에 존재하는 모든 디렉터리와 파일의 아이노드 inode 정보를 직렬화한

파일이다. 각 아이노드는 파일이나 디렉터리 메타데이터의 내부 구조를 나타내며 파일의 복제 수준, 변경 및 접근 시간, 접근 권한, 블록 크기, 파일을 구성하는 블록 집합과 같은 정보를 가지고 있다. 디렉터리에는 파일 과 달리 변경 시간, 권한, 할당 크기와 같은 메타데이터 정보가 저장되어 있다. 블록이 실제 저장된 데이터노드에 대한 정보는 fsimage 파일에 기록되지 않는다. 대신 네임노드는 매핑 정보 (어떤 블록이 어느 데이터노드에 저장되어 있는지)를 메모리에서 따로 관리한다. 네임노드는 클러스터에 데 이터노드가 추가될 때마다 블록 목록에 대한 정보를 데이터노드에 요청하여 매핑 정보를 구성하며, 주기적으 로 네임노드의 블록 매핑 정보를 최신 상태로 갱신한다.

이러한 문제의 해결책은 보조 네임노드를 운영하는 것이다. 보조 네임노드의 용도는 주 네임노 드의 메모리에 있는 파일시스템 메타데이터의 체크포인트를 만드는 것이다.1 체크포인팅 작업 의 절차는 다음과 같으며, [그림 11-1]은 에디트 로그와 fsimage 파일에 관한 내용을 도식화한 것이다. 1 보조 네임노드는 주 네임노드에 사용 중인 edits 파일을 순환할 것을 요청한다. 이제부터 새로 발생하는 edits 로그는 새로운 파일에 저장된다. 주 네임노드는 모든 저장소 디렉터리의 seen_txid 파일을 변경한다. 2 보조 네임노드는 HTTP GET 방식으로 주 네임노드에 있는 최신 fsimage와 edits 파일을 가져온다. 3 보조 네임노드는 fsimage 파일을 메모리에 올리고 edits 파일의 각 변경 내역을 적용한다. 그리고 병합된 새 로운 fsimage 파일을 생성한다. 4 보조 네임노드는 새로운 fsimage 파일을 HTTP PUT 방식으로 주 네임노드에 전송하고, 주 네임노드는 받 은 파일을 .ckpt라는 확장자를 가진 임시 파일로 저장한다. 5 주 네임노드는 임시 저장한 fsimage 파일의 이름을 변경하여 사용 가능하게 만든다.

마지막 단계까지 완료되면 주 네임노드는 최신 fsimage 파일과 작은 edits 파일을 가지게 된다. 이때 edits 파일은 빈 파일이 아닐 수도 있는데, 보조 네임노드에서 체크포인팅 작업이 진행되 는 동안 몇 번의 edits 변경 요청을 받았을 수 있기 때문이다. hdfs dfsadmin -saveNamespace 명령을 이용하면 관리자는 네임노드를 안전 모드로 변환하여 체크포인팅 절차를 수동으로 실행 할 수 있다. 1 네임노드를 -checkpoint 옵션으로 시작하면 또 다른 (주) 네임노드에 대한 체크포인팅 프로세스를 실행할 수 있다. 이런 방식은 보조 네임노드를 실행하는 것과 기능은 동일하며, 실행 시간을 보면 보조 네임노드와 거의 차이가 없다. 보조 네임노드는 가장 검증되고 믿을 수 있는 옵션이다. 고가용성 환경(3.2.5절 ‘HDFS 고가용성’ 참조)에서는 대기(standby) 네임노드가 체크포인팅 절차를 수행한다.

406 3부 하둡 운영

이러한 체크포인팅 절차를 알게 되면 왜 보조 네임노드가 주 네임노드와 비슷한 메모리 용량을 요구하는지 명확하게 알 수 있으며(fsimage 파일을 메모리에 올려야 하기 때문), 이런 이유로 대형 클러스터에서는 보조 네임노드 전용의 컴퓨터가 반드시 필요하다. 체크포인팅 절차는 두 개의 환경 설정 매개변수를 사용해서 제어한다. 보조 네임노드는 매 시 간(dfs.namenode.checkpoint.period, 초 단위)마다 체크포인트를 생성하거나, 매 분(dfs. namenode.checkpoint.check.period, 초 단위)마다 에디트 로그를 확인하여 마지막 체크포

인트 이후에 기록된 변경 내역의 개수가 1백만 개(dfs.namenode.checkpoint.txns )를 넘으 면 새로운 체크포인트를 생성한다. 그림 11-1 체크포인팅 절차 주 네임노드

보조 네임노드

2. 주 네임노드의 fsimage와 edits를 가져옴 1. edits 순환

3. 병합

4. 체크포인트를 주 네임노드에 전송

5. fsimage.ckpt 이름 변경

11장 하둡 관리 407

보조 네임노드 디렉터리 구조 보조 네임노드의 체크포인트 디렉터리(dfs.namenode.checkpoint.dir )의 구조는 주 네임노 드의 체크포인트 디렉터리와 동일하다. 주 네임노드 전체에 장애(NFS에도 복구할 수 있는 백 업본이 없을 때)가 생기더라도 보조 네임노드를 이용해서 복구할 수 있도록 설계되었기 때문 이다. 해당 저장소 디렉터리를 새로운 네임노드에 복사하여 복구하거나, 보조 네임노드를 시 작할 때 -importCheckpoint 옵션을 사용하여 새로운 주 네임노드 역할을 맡길 수도 있다. -importCheckpoint 옵션은 dfs.namenode.checkpoint.dir 속성으로 정의된 디렉터리에 있

는 가장 최근의 체크포인트의 네임노드 메타데이터를 불러온다. 하지만 이 작업은 dfs.nameno de.name.dir 디렉터리에 메타데이터가 없을 때만 수행되므로 중요한 메타데이터를 겹쳐 쓸 위

험은 없다.

데이터노드 디렉터리 구조 네임노드와 달리 데이터노드는 명시적으로 포맷할 필요가 없다. 각 머신에서 데이터노드가 처 음 시작될 때 자동으로 저장소 디렉터리를 생성하기 때문이다. 데이터노드의 주요 파일과 디렉 터리를 살펴보자.

HDFS의 각 블록은 blk_로 시작되는 파일에 저장되며, 각 파일은 저장된 파일의 일부분을 원시 raw

바이트 형태로 저장한다.2 각 블록은 blk_로 시작되는 파일 외에도 .meta로 끝나는 연관

메타데이터 파일을 가진다. 메타데이터 파일은 버전 및 타입 정보를 가진 헤더와 일련의 블록 구간별 체크섬 checksum 으로 구성되어 있다. 2 옮긴이_ HDFS에 저장된 파일은 논리적으로 하나의 파일로 보이나 내부적으로는 데이터노드에 blk_ 접두사가 붙은 여러 개의 물리적인 파일로 분리되어 저장된다.

408 3부 하둡 운영

CHAPTER

12

에이브로

아파치 에이브로 Apache Avro 1는 특정 언어에 종속되지 않는 언어 중립적 데이터 직렬화 시스템 이다. 하둡의 창시자인 더그 커팅이 하둡 Writable (직렬화 방식)의 주요 단점인 언어 이식성 language portability

을 해결하기 위해 만든 프로젝트다. 에이브로는 현재 C, C++, C#, 자바, 자바스

크립트, 펄, PHP, 파이썬, 루비 등의 언어로 처리할 수 있는 새로운 데이터 포맷을 제공하기 때 문에 단일 언어에 얽매이지 않고 다양한 언어로 데이터셋을 쉽게 공유할 수 있다. 에이브로는 데 이터를 읽고 쓰는 어떤 언어가 사라지더라도 계속 사용할 수 있기 때문에 기존 방식에 비해 미 래 지향적이라고 할 수 있다. 그런데 새로운 데이터 직렬화 시스템이 필요한 이유는 무엇일까? 에이브로는 아파치 쓰리프트 Apache Thrift

나 구글의 프로토콜 버퍼 Protocol Buffer 와 같은 다른 직렬화 시스템과 차별화된 특성을

가지고 있다.2 에이브로의 데이터는 다른 시스템과 비슷하게 언어 독립 스키마 schema 로 기술된 다. 하지만 다른 시스템과 달리 에이브로에서 코드를 생성하는 것은 선택사항이다. 이것은 여러 분 코드가 특정 스키마를 사전에 알지 못하더라도 해당 스키마에 부합하는 데이터를 읽고 쓸 수 있음을 의미한다. 이러한 기능을 제공하기 위해 에이브로는 읽고 쓰는 시점에 스키마가 항상 존 재한다고 가정한다. 이렇게 하면 인코드한 값은 필드 식별자로 태깅할 필요가 없어 매우 간결한 인코딩이 가능하다. 에이브로의 스키마는 보통 JSON으로 작성하며, 데이터는 바이너리 포맷으로 인코딩한다. 물론 1 에이브로는 1910년 설립된 영국의 항공기 제조업체의 이름을 따서 명명한 것이다. http://avro.apache.org/ 2 벤치마크에 의하면 에이브로는 다른 직렬화 라이브러리보다 훨씬 좋은 성능을 보여준다.

435

다른 선택사항도 있다. 에이브로는 개발자에게 익숙한 C와 유사한 언어로 스키마를 작성할 수 있는 에이브로 IDL이라는 고수준 언어를 제공한다. 또한 사람이 읽기 쉬운 JSON 기반 데이터 인코더도 제공하는데, 에이브로 데이터를 시범적으로 사용하거나 디버깅하는 데 유용하다. 에이브로 명세 3를 보면 모든 구현체가 지원해야 하는 바이너리 포맷에 대한 자세한 내용을 알 수 있다. 이 명세에는 구현체에 필요한 에이브로의 수많은 기능도 명시되어 있다. 에이브로 명세 에서 다루지 않는 영역이 하나 있는데, 바로 API다. 각 API는 특정 언어에 따라 다르게 작성되 기 때문에 구현체는 에이브로 데이터를 다루는 API를 완전히 자유롭게 만들 수 있다. 하나의 바 이너리 포맷만 지원한다는 사실도 매우 중요하다. 이를 통해 새로운 언어의 바인딩 편의성을 높 이고, 프로그래밍 언어와 포맷의 수많은 조합의 발생으로 상호운영성이 저하되는 문제를 해결할 수 있다. 에이브로는 풍부한 스키마 해석 schema resolution 기능이 있다. 신중하게 정의된 어떠한 제약조건에 서도 데이터를 읽는 데 사용되는 스키마와 데이터를 쓰는 데 사용되는 스키마가 같지 않아도 된 다. 이것이 바로 에이브로가 제공하는 스키마 변형 schema evolution 메커니즘이다. 예를 들어 과거 데이터를 읽을 때 사용한 스키마에 새로운 필드를 추가할 수 있다. 새로운 사용자와 기존 사용자 는 모두 과거의 데이터를 문제없이 읽을 수 있으며, 새로운 사용자는 새로운 필드가 추가된 데이 터를 쓸 수 있다. 반대로 기존 사용자는 새로운 데이터를 보게 되는데, 이때 새로운 필드는 적당 히 무시하고 기존 데이터 작업처럼 처리할 수 있다. 에이브로는 하둡의 시퀀스 파일과 유사한 연속적 객체를 위한 객체 컨테이너 포맷 object container format

을 제공한다. 에이브로 데이터 파일 Avro data file 은 스키마가 저장된 메타데이터 섹션을 포함

하고 있어 자신을 설명하는 파일이 된다. 에이브로 데이터 파일은 압축과 분할 기능을 제공한다. 이것은 맵리듀스의 데이터 입력 포맷에 있어서 매우 중요한 기능이다. 사실 맵리듀스 그 이상을 지원한다. 피그, 하이브, 크런치, 스파크 등 이 책에 소개된 모든 데이터 처리 프레임워크는 에이 브로 데이터 파일을 읽고 쓸 수 있다. 이 책에서는 다루지 않지만 에이브로는 RPC로 사용될 수도 있다. 에이브로 명세를 보면 더 많은 정보를 얻을 수 있다.

3 http://avro.apache.org/docs/current/spec.html

436 4부 관련 프로젝트

12.1 에이브로 자료형과 스키마 에이브로는 소수의 기본 자료형을 제공한다. 사용자는 기본 자료형을 이용한 스키마를 작성하여 특정 애플리케이션을 위한 새로운 자료구조를 만들 수 있다. 구현체는 상호운영성을 위해 모든 에이브로 자료형을 지원해야 한다. [표 12-1]에서 에이브로의 기본 자료형을 볼 수 있다. 기본 자료형은 다음과 같이 type 속성으로 정의한다. { "type": "null" }

표 12-1 에이브로 기본 자료형 자료형

설명

스키마

null

값 없음

"null"

boolean

바이너리 값

"boolean"

Int

부호 있는 32비트 정수

"int"

long

부호 있는 64비트 정수

"long"

float

단정밀도(32비트) IEEE 754 부동소수점 숫자

"float"

double

배정밀도(64비트) IEEE 754 부동소수점 숫자

"double"

bytes

순차 8비트 부호 없는 바이트

"bytes"

string

순차 유니코드 문자

"string"

또한 에이브로는 복합 자료형도 정의할 수 있다. [표 12-2]에서 에이브로가 지원하는 복합 자료 형과 대표적인 예제를 볼 수 있다. 표 12-2 에이브로 복합 자료형 자료형

설명

스키마 예제

array

순서 있는 객체 집합. 배열의 모든 객체는 동일

{ "type": "array", "items": "long"

한 스키마를 가져야 한다.

} map

순서 없는 키-값 쌍의 집합. 키는 반드시 문자열

{ "type": "map", "values": "string"

이고, 값은 어떤 자료형도 될 수 있다. 단, 특정 맵의 모든 값은 동일한 스키마를 가져야 한다.

}

12장 에이브로 437

자료형

설명

스키마 예제

record

임의의 자료형으로 명명된 필드의 집합

{ "type": "record", "name": "WeatherRecord", "doc": "A weather reading.", "fields": [ {"name": "year", "type": "int"}, {"name": "temperature", "type": "int"}, {"name": "stationId", "type": "string"} ] }

enum

명명된 값의 집합

{ "type": "enum", "name": "Cutlery", "doc": "An eating utensil.", "symbols": ["KNIFE", "FORK", "SPOON"] }

fixed

고정길이의 8비트 부호 없는 바이트

{ "type": "fixed", "name": "Md5Hash", "size": 16 }

union

스키마의 유니온. 유니온은 JSON 배열로 표

[

현되며, 배열의 각 요소는 스키마임. 유니온으로

"null", "string", {"type": "map", "values": "string"} ]

표현되는 데이터는 유니온에 포함된 스키마 중 하나와 반드시 일치해야 한다.

에이브로 자료형을 표현하는 에이브로 언어 API는 개별 프로그래밍 언어에 따라 다르다. 예를 들어 에이브로의 double 형은 C, C++, 자바에서는 double로 파이썬에서는 float로 루비에 서는 Float로 표현된다. 게다가 언어별로 하나 이상의 표현이나 매핑이 있을 수 있다. 모든 프로그래밍 언어는 런타임 직

438 4부 관련 프로젝트

전에 스키마를 결정할 수 없을 때 동적 매핑을 사용한다. 자바에서는 이것을 제네릭 매핑 Generic mapping

이라고 한다.

추가로 자바와 C++ 구현체는 에이브로 스키마의 데이터를 표현하는 코드를 생성한다. 자바에 서는 코드 생성을 구체적 매핑 Specific mapping 이라고 하며, 데이터를 읽거나 쓰기 전에 스키마의 사 본이 있을 때 유용한 최적화 방식이다. 파생 클래스는 제네릭 매핑에 비해 좀 더 도메인 지향적인

API를 제공한다. 자바는 리플렉션을 이용하여 에이브로 자료형을 기존의 자바 자료형으로 매핑하는 리플렉트 매 핑 Reflect mapping 을 지원한다. 리플렉트 매핑은 제네릭이나 구체적 매핑에 비해 느리지만 에이브 로가 자동으로 스키마를 유추하기 때문에 자료형을 쉽게 정의할 수 있는 장점이 있다. 자바의 자료형 매핑은 [표 12-3]에서 볼 수 있다. 표에서 구체적 매핑에 별다른 명시가 없으면 제네릭 매핑과 동일하다(그리고 리플렉트 매핑에 별다른 명시가 없으면 구체적 매핑과 동일하 다). 구체적 매핑과 제네릭 매핑은 record, enum, fixed에 대해서만 다르며, 각 자료형은 파생 클래스를 갖는다(자료형의 이름은 name과 선택적인 namespace 속성으로 제어된다). 표 12-3 에이브로 자바 자료형 매핑 에이브로 자료형 제네릭 자바 매핑

구체적 자바 매핑

리플렉트 자바 매핑

null

null type

boolean

Boolean

int

int

long

long

float

float

double

double

bytes

java.nio.ByteBuffer

byte의 배열

string

org.apache.avro.util.Utf8 또는 java.lang.String

java.lang.String

array

org.apache.avro.generic.GenericArray

Array 또는 java.util. Collection

map

java.util.Map

record

org.apache.avro. generic.GenericRecord

byte, short, int 또는 char

org.apache.avro. specific.SpecificRecord

인자 없는 생성자를 갖는 임의

를 구현한 파생 클래스

든 영구 인스턴스 필드가 사용

의 사용자 클래스. 상속받은 모 됨.

12장 에이브로 439

에이브로 자료형 제네릭 자바 매핑

구체적 자바 매핑

리플렉트 자바 매핑

enum

java.lang.String

생성된 자바 열거형

임의의 자바 열거형

fixed

org.apache.avro. generic.GenericFixed

org.apache.avro. specific.SpecificFixed

org.apache.avro. generic.GenericFixed

를 구현한 파생 클래스

union

java.lang.Object

NOTE_ 에이브로 string은 자바 String이나 에이브로 Utf8 자바 자료형으로 표현할 수 있다. Utf8은

가변적이고 단일 Utf8 인스턴스는 일련의 값을 읽거나 쓸 때 재사용할 수 있기 때문에 Utf8을 사용하는 것 이 더 효율적이다. 자바 String은 객체를 생성하는 시점에 UTF-8을 해석하지만, 에이브로는 Utf8을 나중 에 해석하여 어떤 경우에는 더 좋은 성능을 보인다. Utf8은 자바 라이브러리와의 상호운영성을 허용하는 java.lang.CharSequence 인터페이스를 구현한다. 가끔은 toString() 메서드를 호출하여 Utf8 인스턴스를 String 객체로 변환해야 할 때도 있다. 제네릭 매핑과 구체적 매핑에서는 Utf8이 기본이지만, 특정한 매핑에서는 String을 사용할 수도 있다. 이 를 위한 방법이 몇 가지 있다. 첫 번째 방법은 스키마의 avro.java.string 속성을 String으로 지정하는 것이다. { "type": "string", "avro.java.string": "String" } 또는 구체적 매핑을 위해 String 기반의 getter와 setter 클래스를 생성할 수 있다. 에이브로 메이븐 플러그 인을 사용할 때는 string 자료형의 속성을 String으로 설정하면 된다(12.2.1절 ‘구체적인 API’ 참조). 마지막으로, 자바의 리플렉트 매핑은 성능이 아닌 자바 호환성을 위해 만들어졌기 때문에 항상 String 객체 를 사용한다는 점을 유념하자.

12.2 인메모리 직렬화와 역직렬화 에이브로는 직렬화와 역직렬화 API를 지원하기 때문에 메시징 시스템과 같이 구성 포맷이 미리 정의된 기존 시스템과 에이브로를 쉽게 통합할 수 있다. 또 다른 사례로 에이브로 데이터 파일 포맷을 고려해보자. 에이브로 데이터를 스트림에 읽고 쓰는 자바 프로그램을 하나 작성해보자. 두 개의 문자열을 가 진 레코드를 표현하기 위해 다음과 같이 간단한 에이브로 스키마를 작성했다.

440 4부 관련 프로젝트

CHAPTER

13

파케이

아파치 파케이 Apache Parquet 1는 중첩된 데이터를 효율적으로 저장할 수 있는 컬럼 기준 저장 포맷 이다. 컬럼 기준 포맷은 파일 크기와 쿼리 성능 측면 모두에서 효율성이 높은 장점이 있다. 이는 동일 한 컬럼의 값을 나란히 모아서 저장하기 때문에 인코딩 효율이 높다. 따라서 컬럼 기준 포맷의 파일 크기는 행 기반 포맷에 비해 일반적으로 작다. 예를 들어 타임스탬프 컬럼을 저장할 때 첫 번째 값과 다음 값과의 차이를 저장하는 방법으로 인코딩할 수 있다(거의 동시에 들어온 레코드 는 나란히 붙어서 저장되기 때문에 시간적 지역성이 매우 작은 경향이 있다). 또한 쿼리 엔진은 쿼리에 필요하지 않은 컬럼은 처리하지 않아도 되기 때문에 쿼리 성능도 높다(그림 5-4 ). 이 장에서는 파케이를 자세히 살펴볼 것이다. 하지만 하이브 프로젝트의 일부인 ORCFile Optimized Record Columnar File

과 같이 하둡에서 사용하는 다른 컬럼 기준 포맷도 있다.

파케이의 가장 큰 장점은 진정한 컬럼 기반 방식으로 중첩 구조의 데이터를 저장할 수 있다는 것 이다. 현실 세계의 시스템에는 여러 단계의 중첩 구조를 지닌 스키마가 흔히 있기 때문에 이러한 기능은 매우 중요하다. 파케이는 구글의 엔지니어가 드레멜 논문에서 소개한 ‘적은 오버헤드로 단층 컬럼 기준 포맷에 중첩된 구조를 저장하는’ 새로운 기술을 사용했다.2 그 결과 파케이는 중 첩된 필드를 다른 필드와 상관없이 독립적으로 읽을 수 있게 되었으며 따라서 상당한 성능 향상 을 얻을 수 있었다. 1 http://parquet.incubator.apache.org/ 2 세르게이 멜니크(Sergey Melnik) 공저 「드레멜: 웹-규모 데이터셋의 대화형 분석( Dremel : Interactive Analysis of Web-Scale Datasets )」( 2010년 제36회 VLDBVeryLargeDataBases 국제 컨퍼런스 논문집)

461

파케이의 또 다른 특징은 파케이 포맷을 지원하는 수많은 도구가 있다는 것이다. 파케이를 만든 트위터와 클라우데라의 엔지니어는 기존의 데이터를 쉽게 처리할 수 있는 새로운 도구를 원했 다. 따라서 프로젝트를 언어 중립 방식으로 파일 포맷을 정의하는 명세 부분과 다양한 언어(자 바와 C++)로 파케이 파일을 읽거나 쓰는 도구를 쉽게 만들 수 있는 명세의 구현체 부분으로 나 누었다. 사실 이 책에서 다루는 데이터 처리 컴포넌트(맵리듀스, 피그, 하이브, 캐스케이딩, 크 런치, 스파크)는 대부분 파케이 포맷을 지원한다. 또한 이러한 유연성은 인메모리 표현까지 확 장된다. 자바 구현체는 단일 표현에 얽매이지 않기 때문에 파케이 파일에서 데이터를 읽고 쓰는 데 에이브로, 쓰리프트, 프로토콜 버퍼의 인메모리 데이터 모델을 사용할 수 있다.

13.1 데이터 모델 파케이에는 [표 13-1]에서 볼 수 있는 것처럼 몇 개의 기본 자료형이 있다. 표 13-1 파케이 기본 자료형 타입

설명

boolean

바이너리 값

int32

부호 있는 32비트 정수

int64

부호 있는 64비트 정수

int96

부호 있는 96비트 정수

float

단정밀도(32비트) IEEE 754 부동소수점 숫자

double

배정밀도(64비트) IEEE 754 부동소수점 숫자

binary

순차 8비트 부호 없는 바이트

fixed_len_byte_array

고정길이 8비트 부호 없는 바이트

파케이 파일에 저장된 데이터는 루트에 필드 그룹을 포함한 message를 갖는 스키마로 정의된다. 각 필드는 반복자 repetition (required, optional 또는 repeated ), 타입, 이름으로 되어 있다. 다 음은 날씨 레코드에 대한 간단한 파케이 스키마다. message WeatherRecord { required int32 year; required int32 temperature; required binary stationId (UTF8); }

462 4부 관련 프로젝트

여기에 기본 문자열 자료형이 없다는 점을 주의하자. 대신 파케이는 기본 자료형에 대한 해석 방 식을 정의한 논리 자료형을 제공한다. 따라서 직렬화 표현(기본 자료형)과 애플리케이션에 특 화된 시맨틱(논리 자료형)은 차이가 있다. 문자열은 UTF-8 어노테이션을 가진 binary 기본 자료형으로 표현된다. [표 13-2]에서 파케이에 정의된 논리 자료형과 예제 스키마를 볼 수 있 다. 부호 있는 정수, 부호 없는 정수, 날짜와 시간 자료형, JSON과 BSON 문서 자료형에 대한 자세한 내용은 파케이 명세를 참고하라. 표 13-2 파케이 논리 자료형 논리 자료형 어노테이션

설명

UTF8

UTF-8 캐릭터 문자열. 표기: binary

message m { required binary a (UTF8); }

ENUM

명명된 값의 집합.

message m { required binary a (ENUM); }

표기: binary

DECIMAL( precision,scale )

부호 있는 임의 정밀도 십진수. 표기: int32, int64, binary,

fixed_len_byte_array DATE

시간 값이 없는 날짜. 표기: int32. 1970년 1월 1일 (Unix epoch) 이후의 일수로 표현

LIST

순서 있는 값의 집합. 표기: group

MAP

순서 없는 키-값 쌍의 집합. 표기: group

스키마 예제

message m { required int32 a (DECIMAL(5,2)); } message m { required int32 a (DATE); } message m { required group a (LIST) { repeated group list { required int32 element; } } } message m { required group a (MAP) { repeated group key_value { required binary key (UTF8); optional int32 value; } } }

13장 파케이 463

파케이의 복합 자료형은 중첩 계층이 추가된 group 자료형으로 생성한다.3 어노테이션이 없는 그룹은 단순한 중첩 레코드다. 리스트와 맵은 [표 13-2]와 같이 특이한 두 단계 그룹 구조의 그룹으로 만든다. 리스트는 element 필드가 포함된 (list라는 이름의) 중첩된 반복 그룹을 가진 LIST 그룹으로 표현된다. 예제에 서 32-비트 정수형리스트는 required int32 element 필드로 되어 있다. 맵은 MAP으로 표기된 외부의 그룹으로, 내부의 반복 그룹인 key_value를 포함하고 있다. 내부의 반복 그룹은 key와

value 필드로 되어 있다. 예제에서 value는 optional로 표시되어 있으므로 맵은 null 값을 가질 수 있다.

13.1.1 중첩 인코딩 컬럼 기준 저장 방식에서 동일한 컬럼의 모든 값은 함께 저장된다. 날씨 레코드 스키마와 같이 중첩과 반복이 없는 단층 테이블은 각 컬럼이 모두 동일한 개수의 값을 가지고 있기 때문에 각 값이 어떤 행에 속하는지 결정하는 것은 매우 간단하다. 일반적으로 맵 스키마와 같은 중첩 또는 반복이 있는 컬럼은 중첩 구조를 인코딩해야 하므로 처 리하기 힘들다. 일부 컬럼 기준 포맷은 구조 단층화 기법을 통해 이러한 문제를 피할 수 있다. 하 이브의 RC 파일에서 사용되는 이 기법은 최상위 컬럼만 컬럼 우선 방식으로 저장한다. 중첩된 컬럼이 있는 맵은 키와 값을 상호배치 interleave 방식으로 저장하므로 값을 메모리에 올리지 않고 키만 읽는 것은 불가능하다. 드레멜의 인코딩을 사용하는 파케이는 스키마의 모든 기본 자료형 필드의 값을 별도의 컬럼에 저장하고, 그 구조는 명세 수준과 반복 수준의 두 정수로 인코딩한다.4 세부적인 사항은 매우 복 잡하지만,5 단층 레코드는 null을 사용하고 중첩이나 반복 수준이 올라가면 null이 아닌 값을 사용해서 비트 필드를 인코딩하는 일반적인 기법으로 명세 수준과 반복 수준을 저장한다고 생각 하면 편하다. 3 프로토콜 버퍼( Protocol Buffers )( https://developers.google.com/protocol-buffers/)에서 사용된 모델을 기반으로 한다. 프로 토콜 버퍼는 리스트나 맵 같은 복합 자료형을 정의할 때 그룹을 사용한다. 4 옮긴이_ 명세 수준은 스키마의 루트 0에서 컬럼의 최대 수준까지 증가한다. 반복 수준은 새로운 레코드의 시작은 0, 레벨 1의 엔트리는 1, 레벨 2의 엔트리는 2와 같은 방법으로 표시한다. 반복이 없는 단층 스키마의 경우 반복 수준은 0이다. 5 줄리언 르 뎀(Julien Le Dem)은 트위터 블로그(https://blog.twitter.com/2013/dremel-made-simple-with-parquet )에 매우 훌륭한 상세한 해설을 작성했다.

464 4부 관련 프로젝트

CHAPTER

14

플룸

하둡은 대용량 데이터를 처리하기 위한 목적으로 만들어졌다. 보통 데이터가 이미 HDFS에 있 거나 대량의 데이터를 HDFS에 복사할 수 있다고 가정한다. 하지만 이 가정에 맞지 않는 시스 템도 많은데 하둡으로 수집, 저장, 분석하려는 데이터의 스트림을 만드는 시스템이 여기에 속한 다. 아파치 플룸 Apache Flume 1은 이러한 목적을 만족하는 가장 이상적인 시스템이다. 플룸은 이벤트 기반의 대용량 데이터를 하둡으로 수집하기 위해 개발되었다. 다수의 웹 서버에 서 로그파일을 수집하고 해당 파일의 로그 이벤트를 처리하기 위해 HDFS에 위치한 새로운 통 합 파일로 옮기는 것은 플룸을 사용하는 전형적인 예다. 일반적인 최종 목적지(또는 플룸의 싱 크)는 HDFS지만 플룸은 HBase나 솔라 Solr 와 같은 다른 시스템에도 이벤트를 기록할 수 있다. 플룸을 사용하려면 플룸 에이전트 agent 를 실행해야 한다. 플룸 에이전트는 채널 channel 로 연결된 소스 source 와 싱크 sink 를 실행하는 장기 실행 자바 프로세스다. 플룸에서 소스는 이벤트 event 를 만들고 이를 채널로 전달한다. 채널은 싱크로 전송할 때까지 이벤트를 저장한다. 소스-채널-싱 크의 조합이 플룸의 기본 구성요소 building block 다. 플룸은 분산형 토폴로지에서 실행되는 연결된 에이전트의 집합으로 구성된다. 시스템의 가장자 리에 있는 에이전트(웹 서버에서 실행되는)는 데이터를 수집한 다음 이를 집계하는 에이전트로 전송하고 마지막으로 최종 목적지에 데이터를 저장한다. 이를 위해서는 각 에이전트에 특정 소 스와 싱크의 집합이 실행되도록 설정해야 한다. 따라서 플룸을 사용할 때 핵심은 개별 요소가 함

1 http://flume.apache.org/

477

께 유기적으로 동작할 수 있도록 설정하는 것이다. 이 장에서는 하둡 파이프라인의 일부로 사용 할 수 있는 데이터 수집용 플룸 토폴로지를 구축하는 방법을 살펴보겠다.

14.1 플룸 설치 플룸 다운로드 페이지 2에서 플룸 바이너리 배포판의 안정 버전을 내려받아 적절한 위치에서 타 르볼을 푼다. % tar xzf apache-flume-x.y.z-bin.tar.gz

플룸을 쉽게 사용하도록 플룸 바이너리 경로를 환경변수인 PATH에 추가한다. % export FLUME_HOME=~/sw/apache-flume-x.y.z-bin % export PATH=$PATH:$FLUME_HOME/bin

플룸 에이전트는 flume-ng 명령으로 시작할 수 있다.

14.2 예제 이제부터 플룸의 사용법을 살펴보겠다. 시작 단계는 다음과 같다. 1 새로운 텍스트 파일을 처리하기 위한 로컬 디렉터리를 주시한다. 2 파일이 추가되면 파일의 각 행을 콘솔로 전송한다.

예제에서는 파일을 직접 추가하겠지만, 플룸이 계속해서 데이터를 수집할 수 있도록 웹 서버처 럼 새로운 파일을 생성하는 프로세스가 있다고 가정하자. 물론 실제 시스템에서는 파일 내용을 단순히 기록하기보다는 후처리를 위해 그 내용을 HDFS에 저장할 것이다. 후처리 방법은 이 장 뒷부분에서 살펴볼 것이다. 2 http://flume.apache.org/download.html

478 4부 관련 프로젝트

이 예제에서 플룸 에이전트는 자바 속성 파일을 사용해서 설정된 단일 소스-채널-싱크를 실행 한다. 설정은 사용할 소스, 싱크, 채널의 종류와 그들의 연결 방법을 제어한다. 예제에서는 [예제

14-1]의 설정을 이용할 것이다. 예제 14-1 스풀링 디렉터리 소스와 로거 싱크를 사용하는 플룸 설정

agent1.sources = source1 agent1.sinks = sink1 agent1.channels = channel1 agent1.sources.source1.channels = channel1 agent1.sinks.sink1.channel = channel1 agent1.sources.source1.type = spooldir agent1.sources.source1.spoolDir = /tmp/spooldir agent1.sinks.sink1.type = logger agent1.channels.channel1.type = file

속성 이름은 최상위 수준인 에이전트 이름을 시작으로 계층적으로 구성된다. 예제에는 agent1 이라는 단일 에이전트만 있다. 에이전트의 다른 구성요소의 이름은 그다음 수준에서 정의한다. 예제의 agent1.sources에는 agent1에서 실행될 소스의 이름을 나열한다(여기서는 단일 소스 인 source1 ). 이와 비슷하게 agent1은 싱크(sink1 )와 채널(channel1 )을 하나씩 갖는다. 각 컴포넌트의 속성은 계층의 다음 수준에서 정의한다. 컴포넌트에서 사용할 수 있는 설정 속성은 컴포넌트의 종류에 따라 다르다. 이 사례에서는 agent1.sources.source1.type을 spooldir로 설정했다. spooldir는 새로운 파일의 전송을 위해 스풀링 디렉터리를 검사하는

스풀링 디렉터리 소스다. spoolDir 속성에 스풀링 디렉터리 소스를 지정한다. 따라서 source1 의 전체 키는 agent1.sources.source1.spoolDir다. 소스의 채널로는 agent1.sources. source1.channels를 지정했다.

예제의 싱크는 콘솔에 이벤트를 기록하는 로거 싱크 logger sink 다. 싱크는 반드시 채널과 연결되어 야 한다(agent1.sinks.sink1.channel 속성으로).3 파일 채널을 사용하면 채널의 이벤트를 디 3 소스는 channels 속성을 가지나 싱크는 channel 속성을 가진다는 점을 주목하자. 소스는 하나 이상의 채널에 데이터를 공급할 수 있 으나( 14.5절 ‘분기’ 참조) 싱크는 오직 하나의 채널에서만 데이터를 받을 수 있기 때문이다. 여러 개의 싱크로 데이터를 전송하는 채널도 물론 가능하다. 자세한 내용은 14.7절 ‘싱크 그룹’에서 다룬다.

14장 플룸 479

스크에 저장하기 때문에 지속성 durability 을 보장할 수 있다. [그림 14-1]에 시스템을 나타냈다. 그림 14-1 파일 채널로 연결된 스풀링 디렉터리 소스와 로거 싱크가 있는 플룸 에이전트 로컬 파일시스템

플룸 에이전트

파일

spooldir 소스

이벤트

파일 채널

이벤트

로거 싱크

메시지

콘솔

예제를 실행하기 전에 로컬 파일시스템에 반드시 스풀링 디렉터리를 만들어야 한다. % mkdir /tmp/spooldir

그러면 flume-ng 명령어를 이용해서 플룸 에이전트를 시작할 수 있다. % flume-ng agent \ --conf-file spool-to-logger.properties \ --name agent1 \ --conf $FLUME_HOME/conf \ -Dflume.root.logger=INFO,console

[예제 14-1]의 플룸 속성 파일은 --conf-file 플래그로 지정한다. 에이전트 이름은 반드시 --name으로 전달해야 한다(플룸 속성 파일은 다수의 에이전트를 정의할 수 있기 때문에 어떤

것을 실행할 것인지 알려줘야 한다). --conf 플래그에는 환경 설정과 같은 일반적인 설정의 위 치를 지정한다. 새로운 터미널을 열고 스풀링 디렉터리에 파일을 하나 생성하자. 스풀링 디렉터리 소스는 이 파일의 내용이 절대 변경되지 않을 것으로 예상한다. 일부분만 쓰여진 파일을 소스가 읽어가는 것을 방지하기 위해 일단 숨김 파일에 전체 내용을 기록한다.4 그다음에 소스가 읽을 수 있도록 파일명을 변경한다.5 4 옮긴이_ 리눅스에서 앞에 .이 붙은 파일은 숨김 파일이다. 따라서 /tmp/spooldir/.file1.txt는 숨김 파일이 된다. 5 파일 내용이 계속 추가되는 로그파일은 주기적으로 회전시키고 오래된 파일은 스풀링 디렉터리로 옮겨서 해당 파일을 플룸이 읽도록 한다.

480 4부 관련 프로젝트

CHAPTER

15

스쿱

아론 킴벌 Aaron Kimball

하둡 플랫폼의 강력함은 다양한 데이터 타입을 다룰 수 있다는 데 있다. HDFS는 수많은 소스 의 로그와 데이터를 안정적으로 저장할 수 있다. 맵리듀스 프로그램은 다양한 비정형 데이터 포 맷을 파싱하여 적절한 정보를 추출하고 여러 데이터셋을 결합하여 우리가 원하는 결과를 얻을 수 있다. 하지만 HDFS 외부의 스토리지 저장소에 있는 데이터에 접근하려면 맵리듀스 프로그램은 외부

API를 이용해야 한다. 회사의 주요 데이터는 관계형 데이터베이스 관리 시스템 relational database management system Sqoop 1

(RDBMS )과 같은 구조적인 데이터 저장소에 주로 저장된다. 아파치 스쿱 Apache

은 구조화된 데이터 저장소에서 데이터를 추출해서 하둡으로 보내 처리할 수 있도록 해주

는 오픈 소스 도구다. 이러한 처리는 맵리듀스 프로그램이나 하이브 같은 다른 고차원 도구로도 할 수 있다. 또한 관계형 데이터베이스의 데이터를 HBase로 옮기는 데 스쿱을 사용할 수 있다. 분석 파이프라인을 거쳐 최종 산출물이 나오면 스쿱은 이 산출물을 다시 데이터 저장소로 보내 다른 사용자가 사용할 수 있도록 해준다. 이 장에서는 스쿱의 작동 방식과 데이터 처리 파이프라인에서 스쿱을 활용하는 방법을 살펴볼 것이다.

1 http://sqoop.apache.org/

501

15.1 스쿱 얻기 스쿱은 여러 곳에서 내려받을 수 있다. 스쿱은 아파치 소프트웨어 재단 Apache Software Foundation 의 최상위 프로젝트다. 이 레포지토리에는 모든 스쿱 소스 코드와 문서가 있다. 또한 현재 개발 중 인 버전의 소스 코드 뿐만 아니라 공식적인 릴리즈도 구할 수 있으며, 프로젝트를 컴파일하는 자 세한 방법도 포함하고 있다. 공식 프로젝트 사이트 외에 하둡 벤더 배포판에서도 스쿱을 얻을 수 있다. 아파치에서 릴리즈를 내려받은 후 /home/yourname/sqoop-x.y.z/와 같은 디렉터리에 저장한 다. 이 디렉터리를 $SQOOP_HOME이라고 하면 $SQOOP_HOME/bin/sqoop 스크립트로 스쿱을 실행 할 수 있다. 하둡 벤더 배포판으로 설치했다면 /usr/bin/sqoop과 같은 표준 위치에 스쿱 스크립트가 저장 되어 있을 것이다. 따라서 명령행에서 단순히 sqoop이라고 입력하면 스쿱을 실행할 수 있다. 스 쿱을 설치하는 방법과 상관없이 /usr/bin/ 디렉터리 밑에 스쿱 스크립트를 배치하는 것이 좋다.

스쿱 2 스쿱 2는 스쿱 1의 구조적 한계를 해결하기 위해 개발되었다. 예를 들어 스쿱 1은 명령행 도구 고 자바 API를 제공하지 않았기 때문에 다른 프로그램에 내장하기 어려웠다. 또한 스쿱 1의 모 든 커넥터는 모든 출력 포맷에 대한 정의를 포함해야 하므로 새로운 커넥터를 작성하는 것은 매 우 어려웠다. 스쿱 2는 잡을 실행하는 서버 컴포넌트뿐만 아니라 명령행 인터페이스 command-line interface

(CLI), 웹 UI, REST API, 자바 API 등 다양한 클라이언트를 제공한다. 또한 스쿱 2는 스

파크와 같은 대체 실행 엔진을 사용할 수도 있다. 스쿱 2의 명령행 인터페이스는 스쿱 1과 호환 되지 않는다는 점을 주의하자. 이 장에서는 스쿱 1의 안정적인 릴리즈를 사용할 것이다. 현재 스쿱 2의 개발은 매우 활발하나 스 쿱 1과 비교했을 때 부족한 점이 일부 있다. 따라서 스쿱 2를 사용할 때는 원하는 기능을 지원하는 지 반드시 확인해야 한다.

인자 없이 스쿱을 실행하면 아무것도 하지 않는다. % sqoop Try sqoop help for usage.

502 4부 관련 프로젝트

스쿱은 도구와 명령어의 집합으로 구성되어 있다. 도구를 선택하지 않으면 스쿱은 무엇을 해야 할지 모른다. help도 이러한 도구 중 하나며, 이는 다음과 같이 사용할 수 있는 도구의 목록을 보 여준다. % sqoop help usage: sqoop COMMAND [ARGS] Available commands: codegen create-hive-table eval export help import Import-all-tables job list-databases list-tables merge metastore version

Generate code to interact with database records Import a table definition into Hive Evaluate a SQL statement and display the results Export an HDFS directory to a database table List available commands Import a table from a database to HDFS Import tables from a database to HDFS Work with saved jobs List available databases on a server List available tables in a database Merge results of incremental imports Run a standalone Sqoop metastore Display version information

See 'sqoop help COMMAND' for information on a specific command.

help 도구는 특정 도구의 이름을 인자로 지정하면 해당 도구에 대한 구체적인 사용법을 알려

준다. % sqoop help import usage: sqoop import [GENERIC-ARGS] [TOOL-ARGS] Common arguments: --connect --driver --hadoop-home --help -P --password --username --verbose ...

Specify JDBC connect string Manually specify JDBC driver class to use Override $HADOOP_HOME Print usage instructions Read password from console Set authentication password Set authentication username Print more information while working

15장 스쿱 503

인자로 도구를 지정하는 방법 외에 스쿱은 도구별 스크립트도 제공하고 있다. 도구별 스크립트 는 sqoop-help, sqoop-import와 같이 ‘sqoop-도구명’으로 되어 있다. 명령행에서 이런 스 크립트를 실행하는 것은 sqoop help나 sqoop import를 실행했을 때와 같은 결과를 낸다.

15.2 스쿱 커넥터 스쿱은 대용량 데이터 전송 기능이 있는 외부 저장 시스템에 데이터를 임포트하고 익스포트하 는 확장 프레임워크다. 스쿱 커넥터는 이 프레임워크를 사용하여 스쿱이 임포트와 익스포트하 게 해주는 모듈식 컴포넌트다. 스쿱은 MySQL, PostgreSQL, 오라클, SQL 서버, DB2, 네티 자 Netezza 등 다양한 관계형 데이터베이스에서 작동하는 커넥터를 제공한다. 또한 자바의 JDBC 프로토콜을 지원하는 어떤 데이터베이스에도 연결할 수 있도록 제네릭 JDBC 커넥터도 제공한 다. 스쿱은 데이터베이스에 특화된 API를 사용하는 MySQL, PostgreSQL, 오라클, 네티자 커 넥터를 제공하므로 대량 전송을 효율적으로 수행할 수 있다. 자세한 사항은 15.5.4절 ‘직접 모 드 임포트’에서 다룬다. 내장 스쿱 커넥터 외에도 테라데이터, 오라클 등의 엔터프라이즈 데이터 웨어하우스 enterprise data warehouse

에서 Couchbase 같은 NoSQL 저장소에 이르기까지 다양한 데이터 저장소에서 동작

하는 서드파티 커넥터를 사용할 수 있다. 이러한 커넥터는 따로 내려받아야 하며 각 커넥터에 포 함된 지침에 따라 설치하면 스쿱에 추가할 수 있다.

15.3 임포트 예제 스쿱을 설치하면 하둡에 데이터를 임포트할 수 있다. 이 장의 예제에서는 다양한 플랫폼을 지원 하며 사용하기 쉬운 MySQL을 사용한다.

MySQL을 설치하고 설정하는 방법은 온라인 문서 2 를 참고하라. 특히 2장 ‘Installing and Upgrading MySQL’이 유용할 것이다. 데비안 기반의 리눅스 시스템(예를 들면 우분투) 사용

2 http://dev.mysql.com/doc/

504 4부 관련 프로젝트

CHAPTER

16

피그

아파치 피그 Apache Pig 1를 이용하면 대용량 데이터셋을 더 높은 추상 수준으로 처리할 수 있다. 맵리듀스는 개발자가 맵 함수 다음에 리듀스 함수가 오게 할 수 있다. 하지만 이러한 패턴으로 데이터를 처리하려면 여러 단계의 맵리듀스 잡을 순차적으로 처리해야 하므로 매우 어려운 작 업이 될 수 있다. 피그를 사용하면 다중값이나 중첩된 형태의 데이터 구조를 처리할 수 있고 데 이터 변환도 쉽게 할 수 있다. 예를 들어 피그는 조인 기능을 기본으로 포함하고 있는데, 이는 맵 리듀스에서는 쉽게 하기 어려운 기능이다. 피그는 크게 두 부분으로 이루어져 있다. ●

데이터의 흐름을 표현하기 위해 사용하는 피그 라틴 Pig Latin 언어



피그 라틴 프로그램을 수행하는 실행 환경. 단일 JVM에서의 로컬 실행 환경과 하둡 클러스터 상의 분산 실행 환경을 지원한다.

피그 라틴 프로그램은 입력 데이터를 처리하여 출력 결과를 생성하는 일련의 연산 operation 및 변 환 transformation 으로 구성되어 있다. 전체적으로 보면 각각의 연산은 데이터의 연속적인 흐름을 표 현하며, 피그의 실행 환경은 이를 실행 가능한 표현으로 변환한 후 실제 수행한다. 피그는 내부 적으로 이러한 과정을 일련의 맵리듀스 잡으로 변환한다. 개발자는 이러한 내용을 자세히 몰라 도 되며 실행 방식 자체보다는 데이터에 더욱 집중할 수 있다. 피그는 대용량 데이터셋을 다루는 스크립트 언어다. 맵리듀스는 개발 주기가 매우 길다는 단점 1 http://pig.apache.org/

529

이 있다. 매퍼와 리듀서를 작성해서 코드를 컴파일하고 패키징한 후 잡을 실행하고 그 결과를 확 인하려면 오랜 시간이 걸린다. 이는 컴파일과 패키징이 필요 없는 하둡 스트리밍 방식을 사용하 더라도 마찬가지다. 하지만 피그를 사용하면 콘솔 화면에서 대여섯 줄 정도의 피그 라틴 코드만 작성하면 수 테라바이트의 데이터를 곧바로 처리할 수 있다. 실제로 피그는 야후에서 연구원과 엔지니어가 대규모 데이터셋을 더 쉽게 분석할 수 있도록 만들었다. 피그는 개발자가 작성한 프 로그램의 데이터 구조를 자세히 검토할 수 있는 여러 명령어를 제공하므로 쿼리를 쉽게 작성할 수 있다. 피그는 입력 데이터를 대표하는 부분 집합에 대해 표본 실행을 수행하는 기능을 지원하 므로 전체 데이터셋을 처리하기 전에 오류가 있는지 미리 점검할 수 있다. 피그는 확장성이 높다. 처리 과정의 모든 부분(로딩, 저장, 필터링, 그룹핑, 조인)은 사용자 정의 함수 user-defined function (UDF )로 변경할 수 있다. 이러한 함수는 피그의 중첩 데이터 모델 위에 서 동작하므로 피그의 연산자와 매우 긴밀히 통합될 수 있다. 또한 UDF는 맵리듀스 프로그램을 위해 개발된 라이브러리보다 재사용성이 높은 장점이 있다. 경우에 따라서 피그가 맵리듀스로 작성된 프로그램만큼 좋은 성능을 내지 못하기도 한다. 하지 만 피그 팀은 피그의 관계형 연산의 구현체에 사용되는 알고리즘을 지능적으로 고도화하고 있기 때문에 새로운 릴리즈가 나올 때마다 그 성능의 차이는 줄어들고 있다. 자바 맵리듀스 코드의 최 적화에 많은 시간과 노력을 들일 생각이 없다면 피그 라틴으로 쿼리를 작성하는 편이 시간 절약 에 보탬이 될 것이다.

16.1 피그의 설치 및 실행 피그는 클라이언트 측 애플리케이션이다. 피그를 하둡 클러스터에서 실행할 때 추가로 다른 것 을 설치할 필요는 없다. 피그는 맵리듀스 잡을 구동시키고 HDFS나 다른 하둡 파일시스템과 상 호작용한다. 피그의 설치는 간단하다. 아파치 피그 2에서 안정 버전을 내려받고, 적절한 위치에서 타르볼 파일 을 풀면 된다.

2 http://pig.apache.org/releases.html

530 4부 관련 프로젝트

% tar xzf pig-x.y.z .tar.gz

다음과 같이 피그의 홈 디렉터리와 바이너리 디렉터리를 명령행 경로에 추가하는 것이 좋다. % export PIG_HOME=~/sw/pig-x.y.z % export PATH=$PATH:$PIG_HOME/bin

또한 정확한 자바 설치 경로를 환경변수인 JAVA_HOME에 지정해야 한다. 피그의 사용 방법은 pig -help 명령을 실행하면 알 수 있다.

16.1.1 실행 유형 피그는 로컬 모드와 맵리듀스 모드 등 두 종류의 실행 유형(또는 모드)이 있다. 아파치 테즈와 스파크(19장 참조)에서 실행하는 모드는 이 책을 쓰는 시점에 개발 중이다. 둘 다 맵리듀스 모 드에 비해 상당히 높은 성능을 보장하므로 가능하다면 현재 사용하고 있는 피그 버전에서 한번 시도해보자.

로컬 모드 로컬 모드에서 피그는 단일 JVM과 로컬 파일시스템에서 실행된다. 로컬 모드는 주로 작은 데 이터셋 또는 테스트를 위한 용도로 사용된다. 실행 유형은 -x 또는 -exectype 옵션으로 지정할 수 있다. 로컬 모드로 실행할 때는 옵션을 local로 지정하면 된다.

% pig -x local grunt>

이를 실행하면 피그의 대화형 쉘인 그런트 grunt 가 시작된다.

맵리듀스 모드 맵리듀스 모드에서 피그는 쿼리를 맵리듀스 잡으로 변환하고 이를 하둡 클러스터에서 실행한다. 16장 피그 531

여기서 클러스터는 의사분산 또는 완전분산 클러스터를 의미한다. 완전분산 클러스터에서 실행 되는 맵리듀스 모드는 대용량 데이터셋을 피그로 처리할 때 사용된다. 맵리듀스 모드를 사용하려면 먼저 피그와 사용하고 있는 하둡의 버전이 서로 호환되는지 확인 해야 한다. 피그는 특정 하둡 버전에서만 작동하며, 자세한 내용은 릴리즈 노트에서 확인할 수 있다. 피그는 실행할 하둡 클라이언트를 찾고자 HADOOP_HOME이란 환경변수를 참고한다. HADOOP_ HOME이 없으면 피그는 번들로 들어 있는 하둡 라이브러리를 사용한다. 현재 클러스터에서 실

행되는 하둡 버전과 맞지 않을 수도 있으므로 HADOOP_HOME을 명시적으로 지정하는 것이 좋다. 다음으로 피그에 클러스터의 네임노드와 리소스 매니저의 위치를 알려주어야 한다. HADOOP_HOME 에 하둡 설치 경로를 미리 설정했으면 이 작업은 필요 없다. 그렇지 않으면 fs.defaultFS, yarn. resourcemanager.address, mapreduce.framework.name을 정의한 하둡 사이트 파일을 포함한

디렉터리를 HADOOP_CONF_DIR로 지정하면 된다. 대안으로 피그의 conf 디렉터리(또는 PIG_CONF_DIR 환경변수에 지정된 디렉터리)에 있는

pig.properties 파일에 이러한 속성을 설정하는 방법이 있다. 다음은 의사분산 환경 설정의 예다. fs.defaultFS=hdfs://localhost/ mapreduce.framework.name=yarn yarn.resourcemanager.address=localhost:8032

피그와 하둡 클러스터가 연결되도록 설정했으면 피그를 시작할 수 있다. -x 옵션으로 mapreduce 를 지정하거나 옵션을 생략하면 기본 맵리듀스 모드로 시작된다. 로그파일에 타임스탬프를 생략 하려면 -brief 옵션을 사용하면 된다. % pig -brief Logging error messages to: /Users/tom/pig_1414246949680.log Default bootup file /Users/tom/.pigbootup not found Connecting to hadoop file system at: hdfs://localhost/ grunt>

위와 같이 피그는 연결된 파일시스템을 출력으로 보여준다(YARN의 리소스 매니저는 출력하 지 않는다). 532 4부 관련 프로젝트

맵리듀스 모드에서 옵션으로 자동 로컬 모드 auto-local mode (pig.auto.local.enabled를 true로 설정)를 지정할 수 있는데, 이 모드는 100MB (pig.auto.local.input.maxbytes로 지정, 기본 값은 100,000,000바이트)보다 적은 데이터나 리듀서가 1개일 때 로컬에서 잡을 실행할 수 있 도록 해준다.

16.1.2 피그 프로그램 실행 피그 프로그램을 실행하는 방법은 세 가지가 있으며, 로컬 모드 및 하둡 모드에서 작동한다. 스크립트



피그는 피그 명령어가 포함된 스크립트 파일을 실행할 수 있다. 예를 들어 리눅스 쉘에서 pig script.pig 명 령을 실행하면 피그는 로컬 파일인 script.pig에 포함된 명령어를 실행한다. 다른 방법으로, 명령행에서 -e 옵션으로 간단한 스크립트를 문자열로 지정하면 이를 실행할 수 있다. 그런트



그런트는 피그 명령어를 실행하는 대화형 쉘이다. 그런트는 피그가 실행할 스크립트 파일을 지정하지 않았거 나 -e 옵션을 사용하지 않았을 때 시작된다. run과 exec를 사용하면 그런트 내에서도 피그 스크립트 파일을 실행할 수 있다. 내장형



자바에서 JDBC로 SQL 프로그램을 실행하는 것처럼 PigServer 클래스를 사용하면 자바에서 피그 프로그 램을 실행할 수 있다. 또한 프로그램에서 그런트에 접근하려면 PigRunner를 이용하면 된다.

16.1.3 그런트 그런트에는 bash 쉘이나 다른 명령행 애플리케이션에서 주로 쓰는 GNU의 Readline과 같은 행 편집 기능이 있다. 예를 들어 Ctrl-E 키 조합은 커서를 행의 끝으로 이동시킨다. 또한 그런트 는 명령어 이력을 기억하므로3 Ctrl-P/Ctrl-N 키나 위/아래 화살표 키를 이용해서 이전과 이후 명령어를 각각 불러올 수 있다. 다른 편리한 특징으로 자동 완성 기능이 있다. 탭 키를 누르면 피그 라틴의 키워드를 완성해서 보여준다. 예를 들어 다음은 불완전한 문장이다. 3 이력은 사용자 홈 디렉터리의 .pig_history 파일에 저장된다.

16장 피그 533

grunt> a = foreach b ge

여기서 탭 키를 누르면 ge는 피그 라틴의 키워드인 generate로 확장된다. grunt> a = foreach b generate

자동 완성 방식을 설정하려면 autocomplete라는 이름의 파일을 피그의 클래스경로(피그 설 치 디렉터리의 conf 디렉터리 같은 곳) 또는 그런트를 호출한 디렉터리에 두면 된다. 이 파일은 행당 하나의 토큰으로 구성되어야 하고 공백 문자는 허용되지 않으며 대소문자도 구분되어야 한 다. 피그는 파일 이름에 대한 자동 완성은 지원하지 않는다. 따라서 주로 사용하는 파일 경로를 추가하거나 생성한 사용자 정의 함수의 이름을 추가하면 매우 편리하다. help 명령을 사용하면 명령어의 목록을 볼 수 있다. 그런트 세션은 quit 명령어나 단축키인 \q

로 종료할 수 있다.

16.1.4 피그 라틴 편집기 이클립스 Eclipse, 인텔리J IntelliJ, 이데아 IDEA, 빔 Vim, 이맥스 Emacs, 텍스트메이트 TextMate 등 다양한 피그 라틴 편집기가 있다. 자세한 내용은 피그 위키 4를 참고하라. 많은 하둡 배포판은 피그 스크립트를 편집하고 구동할 수 있는 Hue 웹 인터페이스 5를 제공하고 있다.

16.2 예제 2장 맵리듀스의 예제와 동일하게 날씨 데이터셋에서 연도별 최고 기온을 계산하는 프로그램을 피그 라틴으로 다시 작성해보겠다. 프로그램의 전체 코드는 겨우 몇 줄 밖에 되지 않는다.

4 https://cwiki.apache.org/confluence/display/PIG/PigTools 5 http://gethue.com/

534 4부 관련 프로젝트

CHAPTER

17

하이브

제프 해머바처 Jeff Hammerbacher 는 ‘정보 플랫폼과 데이터 과학자의 출현’ 1에서 정보 플랫폼을 ‘정 보를 획득하고 처리하고 생성하기 위한 노력의 소산’으로 기술했고, 나아가 ‘데이터 과학자가 경 험적인 데이터로부터 학습 진행을 가속화하는 방법’까지 정보 플랫폼의 범주에 넣었다. 페이스북에서 일하는 제프의 팀이 개발한 정보 플랫폼 중 가장 중요한 구성요소가 바로 아파치 하이브 Apache Hive 2다. 하이브는 하둡 기반의 데이터 웨어하우징 프레임워크로, 빠른 속도로 성 장하는 페이스북의 소셜 네트워크에서 매일같이 생산되는 대량의 데이터를 관리하고 학습하기 위해 개발되었다. 제프의 팀은 여러 시스템을 검토한 후 데이터를 저장하고 처리하는 용도로 하 둡을 선택했는데, 하둡은 비용이 저렴하고 확장성도 높았기 때문이다. 하이브는 자바 프로그래밍 기술은 부족하지만 강력한 SQL 기술을 가진 분석가가 페이스북의

HDFS에 저장된 대량의 데이터를 분석할 수 있도록 개발되었다. 현재 하이브는 많은 조직에서 범용의 확장성 있는 데이터 처리 플랫폼으로 채택된 성공적인 아파치 프로젝트가 되었다. 물론 모든 빅데이터 문제에 SQL이 이상적인 것은 아니다. 예를 들어 복잡한 머신러닝 알고리 즘을 구현하기에는 적합하지 않다. 하지만 다양한 분석을 하는 데 제격이고 산업계에 매우 유명 한 기술이라는 큰 장점을 지니고 있다. 더욱이 SQL은 비즈니스 인텔리전스 분야의 도구에서 사 용되는 공통 언어 lingua franca 이기 때문에(예를 들어 ODBC는 공통 인터페이스다) 해당 분야의 상용 제품과 쉽게 통합할 수 있다. 1 토비 세가란(Toby Segaran), 제프 해머바처(Jeff Hammerbacher) 공저 『아름다운 데이터: 우아한 데이터 솔루션 뒤에 숨은 이야기 (Beautiful Data : The Stories Behind Elegant Data Solutions)』(오라일리, 2009 ) 2 https://hive.apache.org/

587

이 장에서는 하이브를 사용하는 방법을 다룬다. 따라서 SQL에 대한 실전 경험과 일반적인 데이 터베이스 구조에 대한 지식이 요구된다. 또한 하이브의 특성과 전통적인 RDBMS와의 비교도 다 룰 것이다.

17.1 하이브 설치하기 일반적으로 하이브는 사용자의 워크스테이션에서 실행되고, 작성된 SQL 쿼리는 일련의 맵리듀 스 잡으로 변환되어 하둡 클러스터에서 구동된다. 하이브는 HDFS에 저장된 데이터(디렉터리/ 파일)에 구조(스키마)를 입히는 방식으로 데이터를 테이블로 구조화시킨다. 테이블 스키마와 같은 메타데이터는 메타스토어 metastore 라 불리는 데이터베이스에 저장된다. 하이브를 처음 사용할 때는 사용자의 로컬 머신에서 메타스토어를 실행하는 것이 좋다. 이러한 로컬 메타스토어 방식은 사용자가 만든 하이브 테이블 명세가 로컬 머신에 있으므로 다른 사용 자와 그 명세를 공유할 수 없다. 실제 운영 환경에서 주로 사용되는 공유 원격 메타스토어에 대 한 설정 방법은 17.3.3절 ‘메타스토어’에서 다룰 것이다. 하이브를 설치하는 작업은 단순하다. 현재 운영 중인 클러스터에 설치된 것과 동일한 버전의 하 둡이 사용자의 로컬 워크스테이션에 설치되어 있으면 된다.3 물론 하이브를 처음 다룰 때는 로 컬 머신에서 하둡을 독립 또는 의사분산 모드로 실행할 수 있다. 이러한 옵션은 부록 A에서 다 룬다.

하이브와 하둡 버전의 호환성 하이브의 모든 배포판은 여러 버전의 하둡과 문제없이 작동하도록 설계되었다. 일반적으로 하이 브는 릴리즈 목록에 열거된 예전 버전을 지원할 뿐만 아니라 안정된 최신 하둡 배포판에서도 잘 동작한다. 하이브에 사용할 하둡의 버전을 굳이 알려주지 않아도 되며, 단지 하둡의 실행 파일이 실행 경로 PATH 에 있고 HADOOP_HOME 환경변수가 설정되어 있으면 된다.

3 사용자 워크스테이션과 하둡 클러스터는 네트워크로 연결되어 있어야 한다. 하이브를 실행하기 전에 로컬 머신에 하둡을 설치하고 hadoop fs 명령어로 일부 HDFS 명령어를 수행해보면 제대로 연결되었는지 확인할 수 있다.

588 4부 관련 프로젝트

하이브를 내려받고,4 사용자 워크스테이션의 적절한 위치에서 타르볼 파일을 푼다. % tar xzf apache-hive-x.y.z-bin.tar.gz

사용자 경로에 하이브를 넣어두면 실행하기 편리하다. % export HIVE_HOME=~/sw/apache-hive-x.y.z-bin % export PATH=$PATH:$HIVE_HOME/bin

다음과 같이 hive 명령어를 실행하여 하이브 쉘을 구동하자. % hive hive>

17.1.1 하이브 쉘 하이브 쉘은 HiveQL 명령어로 하이브와 상호작용하는 하이브의 기본 도구다. HiveQL은 SQL 과 유사한 하이브의 질의 언어다. HiveQL은 MySQL에 큰 영향을 받았기 때문에 MySQL에 익숙한 사용자는 하이브가 쉽게 느껴질 것이다. 처음 하이브를 사용할 때는 테이블 목록을 조회하는 명령을 수행하여 하이브의 동작 여부를 확 인하는 것이 좋다. 처음에는 어떤 테이블도 없는 것이 정상이다. 명령어는 반드시 세미콜론(;) 으로 끝나야 하며, 세미콜론을 만나면 하이브는 그 명령어를 실행한다. hive> SHOW TABLES; OK Time taken: 0.473 seconds

SQL처럼 HiveQL은 일반적으로 대소문자를 구분하지 않는다(문자열 비교는 제외). 따라서 show tables;라고 입력해도 문제없이 작동한다. 탭 키를 사용하면 하이브가 제공하는 예약어

와 함수를 자동 완성할 수 있다. 4 http://hive.apache.org/downloads.html

17장 하이브 589

처음 설치하고 이 명령어를 실행하면 사용자 머신에 메타스토어 데이터베이스를 만들기 때문에 수 초가 걸린다. 데이터베이스는 사용자가 hive 명령어를 실행한 위치에 metastore_db라는 디 렉터리를 만들어 필요한 파일을 저장한다. 사용자는 하이브 쉘을 비대화식 모드로 실행할 수도 있다. 다음과 같이 -f 옵션을 사용하면 지정 한 파일에 대해서만 hive 명령어가 실행된다(여기서는 script.q 파일을 지정했다). % hive -f script.q

간단한 스크립트는 -e 옵션을 이용하여 명령행에 직접 입력하는 방법도 있다. 이 경우 스크립트 끝에 세미콜론을 붙이지 않아도 된다. % hive -e 'SELECT * FROM dummy' OK X Time taken: 1.22 seconds, Fetched: 1 row(s)

NOTE_ SELECT 구문의 기능을 간단한 문자 데이터로 테스트할 때 쿼리 검증을 위한 작은 데이터 테이블이

있으면 매우 유용하다(17.5.2절 ‘연산자와 함수’ 참조). 다음은 단일 행으로 이뤄진 작은 테이블을 생성하는 방법이다. % echo 'X' > /tmp/dummy.txt % hive -e "CREATE TABLE dummy (value STRING); \ LOAD DATA LOCAL INPATH '/tmp/dummy.txt' \ OVERWRITE INTO TABLE dummy"

하이브는 실행 과정에서 부수적으로 발생하는 정보(쿼리를 실행할 때 소요된 시간)를 대화형과 비대화형 모드에서 모두 표준 에러로 출력한다. 실행 시 -S 옵션을 붙이면 불필요한 메시지의 출 력을 막아 쿼리에 대한 출력 결과만 볼 수 있다. % hive -S -e 'SELECT * FROM dummy' X

그 밖에 다른 유용한 하이브 쉘의 특성으로 명령어 앞에 !를 붙여 호스트 운영체제의 명령어를 실행하는 기능과 dfs 명령어로 하둡 파일시스템을 조작하는 기능이 있다.

590 4부 관련 프로젝트

17.2 예제 앞에서 사용한 기상 데이터셋을 하이브로 다루는 방법을 살펴보자. 먼저 하이브의 관리 저장소 로 데이터를 옮겨야 한다. 여기서는 하이브의 저장소로 로컬 파일시스템을 사용할 것이다. 나중 에 테이블을 HDFS에 저장하는 방법도 볼 것이다.

RDBMS와 마찬가지로 하이브는 데이터를 테이블로 관리한다. CREATE TABLE 구문으로 기상 데이터를 저장하기 위한 테이블을 생성하자. CREATE TABLE records (year STRING, temperature INT, quality INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

첫 번째 줄은 year, temperature, quality 컬럼으로 구성된 records 테이블을 선언한다. 각 컬럼의 자료형을 반드시 지정해야 한다. 여기서 year는 문자열, 다른 두 컬럼은 정수형이다.

HiveQL에서만 사용되는 ROW FORMAT 절을 제외하면 지금까지 사용된 SQL은 매우 익숙할 것 이다. 이 선언문은 데이터 파일의 각 행은 탭으로 분리된 텍스트임을 의미한다. 하이브는 탭과 개행 문자로 필드와 행을 각각 구분하고, 각 행에는 세 개의 필드(테이블의 컬럼에 상응하는)가 존재한다고 가정한다. 이제 하이브로 데이터를 다룰 수 있다. 다음은 하이브를 소개하기 위한 간단한 예제다. LOAD DATA LOCAL INPATH 'input/ncdc/micro-tab/sample.txt' OVERWRITE INTO TABLE records;

이 명령어를 실행하면 지정된 로컬 파일을 하이브의 웨어하우스 디렉터리에 로드한다. 이 명령 은 단순한 파일시스템 조작이다. 여기서 하이브는 특별한 파일 포맷을 요구하지 않기 때문에 파 일을 파싱하고 그것을 내부 데이터베이스 포맷으로 저장하는 방식의 시도는 전혀 하지 않는다. 파일은 그대로 저장되고 하이브는 아무것도 변경하지 않는다. 이 예제는 하이브 테이블을 로컬 파일시스템(fs.defaultFS 속성의 값을 기본값인 file:///로 설정)에 저장한다. 테이블은 하이브의 웨어하우스 디렉터리(hive.metastore.warehouse.dir 속성으로 설정하며, 기본값은 /user/hive/warehouse )의 하위 디렉터리로 저장된다.

17장 하이브 591

따라서 records 테이블의 데이터 파일은 로컬 파일시스템의 /user /hive /warehouse /

records 디렉터리에서 찾을 수 있다. % ls /user/hive/warehouse/records/ sample.txt

이 예제에서는 sample.txt라는 하나의 파일만 존재하지만 더 많은 파일이 존재할 수도 있다. 하이브는 특정 테이블을 질의할 때 모든 파일을 읽는다. LOAD DATA 구문의 OVERWRITE 키워드는 해당 테이블의 디렉터리에 존재하는 모든 파일을 삭제

하는 기능이다. OVERWRITE를 생략하면 새로운 파일은 단순히 그 테이블의 디렉터리에 추가된 다. 이때 동일한 이름의 파일이 있으면 이전 파일을 덮어쓴다. 이제 하이브에 데이터가 준비되었고, 쿼리를 실행할 수 있다. hive> SELECT year, MAX(temperature) > FROM records > WHERE temperature != 9999 AND quality IN (0, 1, 4, 5, 9) > GROUP BY year; 1949 111 1950 22

위 SQL 쿼리는 매우 평범하다. 연도별 최고 기온을 구하기 위해 MAX ( ) 집계 함수를 사용하고, year를 기준으로 그룹 짓기 위해 GROUP BY와 SELECT 구문을 사용한다. 하이브가 이 쿼리를 사

용자 대신 맵리듀스 잡으로 변환하여 실행하고 그 결과를 콘솔에 출력한다는 사실에 주목하자. 이 예제는 하이브가 지원하는 SQL 구조와 사용자가 쿼리를 통해 요청할 수 있는 데이터의 포맷 과 같은 일부 제약사항을 보여주지만(이 장에서는 그 일부를 확인해볼 것이다) 이것이 바로 원 시 데이터를 대상으로 SQL 쿼리를 실행하는 하이브의 능력이다.

17.3 하이브 실행하기 이 절에서는 하둡 클러스터와 공유 메타스토어를 대상으로 하이브를 설정하는 방법과 하이브 실 행에 필요한 실무적인 내용을 다룬다. 따라서 하이브의 아키텍처를 자세히 살펴볼 필요가 있다.

592 4부 관련 프로젝트

CHAPTER

18

크런치

아파치 크런치 Apache Crunch 1는 맵리듀스 파이프라인을 작성하는 고수준 API다. 맵리듀스 대신 크런치를 사용하면 String이나 POJO plain old Java object 와 같은 프로그래머에게 익숙한 자바 자 료형, 풍부한 데이터 변환 기능, 여러 단계의 파이프라인에 집중할 수 있는 장점이 있다(워크플 로에 있는 개별 맵리듀스 잡을 직접 관리할 필요가 없다). 이러한 관점에서 크런치는 피그의 자바 버전과 상당히 유사해 보인다. 피그에서 사용자 정의 함 수는 자바나 파이썬과 같은 언어로 작성하고 피그 스크립트는 피그 라틴 언어로 작성한다. 따라 서 두 개의 서로 다른 표현과 언어를 그때마다 전환해야 하는 분리된 개발 경험을 가지게 되므 로 피그를 사용하면 매일 소스 코드의 마찰이 생긴다. 하지만 크런치는 이를 피할 수 있다. 피 그와 달리 크런치 프로그램과 UDF는 모두 단일 언어(자바 또는 스칼라)로 작성되고 프로그램 속에 UDF를 바로 넣을 수 있다. 크런치를 보면 분산 프로그램이 아닌 일반적인 프로그램과 같 은 느낌이 든다. 크런치는 피그와 여러 면에서 비슷하지만 정확히 말하면 FlumeJava에서 영 감을 얻었다. FlumeJava는 맵리듀스 파이프라인을 구축하기 위해 구글에서 개발한 자바 라이 브러리다.2 NOTE_ FlumeJava와 14장에서 다룬 스트리밍 이벤트 데이터를 수집하는 시스템인 아파치 플룸 Apache Flume

을 혼동해서는 안 된다. FlumeJava에 관한 자세한 내용은 크레이그 챔버 Craig Chambers 공저 「FlumeJava : 쉽고 효율적인 데이터 병렬 파이프라인 FlumeJava: Easy, Efficient Data Parallel Pipelines」 2 에서 볼 수 있다.

1 https://crunch.apache.org/ 2 http://bit.ly/data -parallel_pipelines

645

고수준의 크런치 파이프라인은 복잡한 구성이 가능하고 공통 함수는 라이브러리로 추출하여 다 른 프로그램에서 다시 사용할 수 있다. 이 점이 코드의 재사용이 어려운 맵리듀스와의 차이점이 다. 식별 함수나 간단한 집계(LongSumReducer ) 함수를 호출하는 단순한 사례를 제외한 맵리듀 스 프로그램의 대부분은 사용자가 직접 구현한 매퍼와 리듀서로 되어 있다. 정렬이나 조인과 같 은 다른 유형의 변환 작업을 위해 매퍼와 리듀서 라이브러리를 작성하는 것은 맵리듀스에서는 쉽지 않지만 크런치에서는 굉장히 편하다. 예를 들어 org.apache.crunch.lib.Sort 라이브러 리 클래스는 전달된 모든 크런치의 컬렉션을 정렬할 수 있는 sort ( ) 메서드를 포함하고 있다. 크런치는 초기에 하둡의 맵리듀스 실행 엔진을 수행하기 위해 작성되었다. 그러나 맵리듀스에만 국한되지 않고 지금은 분산 실행 엔진인 아파치 스파크(19장 참조)를 사용하여 크런치 파이프 라인을 실행할 수 있다. 엔진마다 그 특성이 다른데 예를 들어 스파크는 잡과 잡 사이에 전달되 는 중간 데이터가 많을 때 맵리듀스보다 더 효율적이다. 스파크는 데이터를 디스크에 쓰는 맵 리듀스와 달리 메모리에 보관할 수 있기 때문이다. 프로그램을 변경하지 않고 동일한 파이프라 인을 여러 엔진에서 실행할 수 있다는 것은 매우 강력한 기능이다. 이러한 기능을 활용하면 실행 효율성의 문제는 별개로 두고 프로그램에만 집중할 수 있다(일반적으로 시간이 지나면서 엔진 의 성능도 좋아지기 때문). 이 장에서는 크런치로 데이터 처리 프로그램을 작성하는 방법을 다룬다. 자세한 정보는 크런치 사용자 가이드 3에서 얻을 수 있다.

18.1 예제 기본 개념을 설명하기 위해 간단한 크런치 파이프라인 예제를 하나 살펴보자. [예제 18-1]은 2장 에 나온 날씨 데이터셋에서 연도별 최고 기온을 계산하는 프로그램을 크런치 버전으로 다시 작성 한 것이다. 예제 18-1 크런치를 사용해서 최고 기온을 구하는 애플리케이션

public class MaxTemperatureCrunch {

3 http://crunch.apache.org/user-guide.html

646 4부 관련 프로젝트

public static void main(String[] args) throws Exception { if (args.length != 2) { System.err.println("Usage: MaxTemperatureCrunch "); System.exit(-1); } Pipeline pipeline = new MRPipeline(getClass()); PCollection records = pipeline.readTextFile(args[0]); PTable yearTemperatures = records .parallelDo(toYearTempPairsFn(), tableOf(strings(), ints())); PTable maxTemps = yearTemperatures .groupByKey() .combineValues(Aggregators.MAX_INTS()); maxTemps.write(To.textFile(args[1])); PipelineResult result = pipeline.done(); System.exit(result.succeeded() ? 0 : 1); } static DoFn toYearTempPairsFn() { return new DoFn() { NcdcRecordParser parser = new NcdcRecordParser(); @Override public void process(String input, Emitter emitter) { parser.parse(input); if (parser.isValidTemperature()) { emitter.emit(Pair.of(parser.getYear(), parser.getAirTemperature())); } } }; } }

명령행의 인자를 먼저 확인한 후 원하는 계산 코드가 들어간 크런치 Pipeline 객체를 생성하는 순으로 프로그램이 시작된다. 이름에서도 알 수 있듯이 파이프라인은 여러 단계로 될 수 있다. 이 예제는 단일 단계의 파이프라인이지만 다수의 입력과 출력, 가지(분기), 반복 연산이 모두 가능하다. 여기서는 파이프라인을 실행하기 위해 맵리듀스를 사용할 것이므로 MRPipeline을 생성하지만 테스트 목적으로 메모리상에서 파이프라인을 실행할 수 있는 MemPipeline이나 동 일한 계산을 스파크에서 수행하는 SparkPipeline을 선택할 수도 있다.

18장 크런치 647

파이프라인은 하나 이상의 입력 소스로부터 데이터를 전달받을 수 있다. 예제에서 입력 소스는 명령행의 첫 번째 인자인 args[0]의 이름을 가진 텍스트 파일 하나다. Pipeline 클래스는 텍 스트 파일을 String 객체의 PCollection으로 변환하는 편의 메서드인 readTextFile ( )를 제 공한다. 여기서 String 객체는 텍스트 파일의 한 행이다. PCollection는 크런치의 가장 핵 심적인 자료형이며, 불변하고 정렬되지 않았으며 분산된 S 타입 항목의 컬렉션으로 표현된다. PCollection는 실체화되지 않은(항목을 메모리에 읽어 들이지 않기 때문) java.util. Collection과 동일하다고 볼 수 있다. 이 예제에서 입력은 텍스트 파일에 있는 행의 분산 컬렉

션이며 PCollection으로 표현된다. 크런치는 PCollection에 대해 계산을 수행한 후 새로운 PCollection을 만든다. 가장 먼저 해야 할 일은 입력 파일의 각 행을 파싱하고 부적합한 레코드를 걸러내는 것이다. 이를 위해 PCollection의 parallelDo ( ) 메서드를 사용하면 PCollection의 모든 항목에 함수를 적용

하고 새로운 PCollection을 돌려받게 된다. 메서드 원형은 다음과 같다.

PCollection parallelDo(DoFn doFn, PType type);

S 타입의 인스턴스를 하나 이상의 T 타입 인스턴스로 변환하는 DoFn 구현체를 작성하면 크런

치는 PCollection의 모든 항목에 이 함수를 적용한다. 이러한 동작은 맵리듀스 잡의 맵 태스크 에서 병렬로 수행된다. parallelDo ( ) 메서드의 두 번째 인자는 T에 사용될 자바 자료형과 이 자료형을 직렬화하는 방법을 크런치에 알려주는 PType 객체다. 실제로는 PCollection을 확장한 PTable를 생성하는 parallelDo ( )의 오버로드 버전 을 사용할 것이다. PTable는 키-값 쌍의 분산 다중맵 multi-map (중복 키-값 쌍을 가질 수 있는 맵)이다. 따라서 연도를 키로 기온을 값으로 표현할 수 있고 파이프라인의 후반부에서 그 룹별로 집계하는 데 활용될 것이다. 이 메서드의 원형은 다음과 같다. PTable parallelDo(DoFn doFn, PTableType type);

이 예제에서 DoFn은 입력 행을 파싱하고 연도-기온 쌍을 내보낸다. static DoFn toYearTempPairsFn() { return new DoFn() {

648 4부 관련 프로젝트

NcdcRecordParser parser = new NcdcRecordParser(); @Override public void process(String input, Emitter emitter) { parser.parse(input); if (parser.isValidTemperature()) { emitter.emit(Pair.of(parser.getYear(), parser.getAirTemperature())); } } }; }

함수를 적용한 후에 연도-기온 쌍 테이블을 얻을 수 있다. PTable yearTemperatures = records .parallelDo(toYearTempPairsFn(), tableOf(strings(), ints()));

parallelDo ( ) 의 두 번째 인자는 PTableType 객체로 크런치의 Writables 클래스의

정적 메서드를 사용해서 생성된다(크런치가 작성하는 중간 데이터를 하둡 Writable 직렬화 로 선택했기 때문). tableOf ( ) 메서드는 주어진 키와 값 타입으로 PTableType을 생성한다. strings ( ) 메서드는 키를 메모리의 자바 String 객체로 표현하고 하둡 Text로 직렬화되도록

선언한다. 그 값은 자바 정수형이며 하둡 IntWritable로 직렬화된다. 이 시점에서 더욱 구조적인 형태의 데이터를 가지게 된다. 그리고 입력 파일의 모든 행이 yearTem peratures 테이블의 항목과 일치하므로 레코드의 수는 변함이 없다. 데이터셋에서 연도별 최

고 기온을 계산하려면 테이블 항목을 연도별로 그룹화한 후 최고 기온을 찾으면 된다. 다행히 크런치는 이러한 기능을 PTable의 API로 제공한다. groupByKey ( ) 메서드는 키별로 항목을 그 룹짓기 위해 맵리듀스 셔플을 수행하고 세 번째 PCollection 타입인 PGroupedTable를 반환한다. PGroupedTable는 맵리듀스의 리듀서처럼 키별로 모든 값의 집계를 수행하는 combineValues ( ) 메서드를 가진다.

PTable maxTemps = yearTemperatures .groupByKey() .combineValues(Aggregators.MAX_INTS());

combineValues ( ) 메서드는 일련의 값을 집계할 수 있는 모든 종류의 표현을 제공하는 단순한

18장 크런치 649

인터페이스인 크런치 Aggregator 인스턴스를 전달받는다. 그러면 정수 집합에서 최댓값을 찾 을 수 있는 Aggregators 클래스의 내장 집계기인 MAX_INTS를 사용할 수 있다. 파이프라인의 마지막 단계는 To라는 정적 팩토리를 이용하여 생성한 텍스트 목표 파일 객체를 인자로 갖는 write ( ) 메서드를 호출하여 maxTemps 테이블의 내용을 파일에 기록하는 것이다. 크런치는 실제로 이 작업에서 하둡의 TextOutputFormat을 사용한다. 즉, 각 출력 행의 키와 값 은 탭으로 구분된다. maxTemps.write(To.textFile(args[1]));

지금까지는 파이프라인 구축에만 관심을 두어 프로그램을 작성했다. 이제 파이프라인을 실행하 기 위해 done ( ) 메서드를 호출해야 한다. 이 시점에 프로그램은 파이프라인이 종료될 때까지 기다리게 된다. 크런치는 파이프라인에서 수행된 잡에 대한 다양한 통계와 파이프라인의 성공 여부를 포함한 PipelineResult 객체를 반환한다. 프로그램의 종료 코드를 설정할 때 후자의 정 보를 활용할 수 있다. 샘플 데이터셋으로 프로그램을 수행하면 다음 결과를 얻는다. % hadoop jar crunch-examples.jar crunch.MaxTemperatureCrunch \ input/ncdc/sample.txt output % cat output/part-r-00000 1949 111 1950 22

18.2 크런치 핵심 API 이 절에서는 크런치의 핵심 인터페이스를 다룰 것이다. 크런치의 API는 고수준으로 설계되었기 때문에 프로그래머는 세부적인 실행 방식보다는 계산을 위한 논리 연산에만 집중할 수 있다.

18.2.1 기본 연산자 크런치의 핵심 데이터 구조는 PCollection로, 불변하고 정렬되지 않았으며 분산된 S 타입

650 4부 관련 프로젝트

CHAPTER

19

스파크

아파치 스파크 Apache Spark 1는 대용량 데이터 처리를 위한 클러스터 컴퓨팅 프레임워크다. 이 책 에서 다루는 다른 데이터 처리 프레임워크와 달리 스파크는 실행 엔진으로 맵리듀스를 사용하지 않는다. 대신 스파크는 클러스터 기반으로 작업을 실행하는 자체 분산 런타임 엔진이 있다. 하지 만 스파크는 이 장에서 살펴볼 API와 수행 측면 모두에서 맵리듀스와 매우 비슷하다. 스파크는 하둡과 밀접하게 통합되어 있어서 YARN 기반으로 실행할 수 있고, 하둡 파일 포맷과 HDFS 같은 기반 저장소를 지원한다. 스파크는 잡 사이의 대용량 작업 데이터셋을 메모리상에 유지할 수 있는 것으로 잘 알려져 있다. 스파크는 이런 특성이 있어서 동일한 기능을 수행하지만 매번 디스크에서 데이터셋을 읽는 맵리 듀스 워크플로에 비해 10배 혹은 어떤 경우에는 더 빠른 성능을 보인다.2 스파크의 처리 모델로 큰 효과를 얻을 수 있는 두 가지 애플리케이션이 있다. 하나는 반복적 알고리즘(종료 조건을 만 족할 때까지 데이터셋에 함수를 반복해서 적용)이고 다른 하나는 대화형 분석(사용자가 데이 터셋에 일련의 대화식 쿼리를 생성)이다. 인메모리 캐싱을 사용하지 않더라도 스파크는 DAG 엔진과 사용자 경험 등을 제공하기 때문에 큰 매력이 있다. 맵리듀스와 달리 스파크의 DAG 엔진은 연산자 중심의 파이프라인을 처리해서 사용자를 위한 단일 잡으로 변환한다. 1 https://spark.apache.org/ 2 마테이 자하리아( Matei Zaharia ) 공저 「탄력적인 분산 데이터셋 : 인메모리 클러스터 컴퓨팅을 위한 내고장성 추상화( Resilient Distributed Datasets : A Fault-Tolerant Abstraction for In-Memory Cluster Computing )」(제9회 USENIX 컨퍼런스 네트 워크 시스템 설계 및 구현 논문집, 2012년)

681

스파크의 사용자 경험은 독보적이다. 조인과 같은 다양한 일반적인 데이터 처리 작업을 수행하 는 풍부한 API를 제공한다. 이 글을 작성하던 시점에 스파크는 스칼라, 자바, 파이썬 등 세 가지 언어의 API를 지원한다. 이 장에 나오는 대부분의 예제는 스칼라 API를 사용하는데 물론 다른 언어로도 쉽게 변환할 수 있다. 스파크는 또한 파이썬과 스칼라를 위한 REPL read-eval-print loop 환 경을 제공하므로 빠르고 편리하게 데이터셋을 탐색할 수 있다. 스파크는 또한 분석 도구를 만들기 적합한 플랫폼을 제공한다. 이를 위해 머신러닝 MLlib, 그래 프 처리 GraphX, 스트림 처리 Spark Streaming, SQL Spark SQL 등의 모듈을 아파치 스파크 프로젝트에 포함했다. 이 장에서는 스파크의 이러한 모듈은 다루지 않는다. 관심이 있다면 아파치 스파크 웹 사이트 3를 참고하기 바란다.

19.1 스파크 설치 스파크 다운로드 페이지 4에서 스파크 바이너리 배포판의 안정 버전을 내려받는다(현재 사용하 는 하둡의 버전에 맞는 배포 버전을 선택). 그리고 적합한 위치에서 압축을 푼다. % tar xzf spark-x.y.z-bin-distro.tgz

스파크 바이너리 경로를 환경변수인 PATH에 추가하면 편리하다. % export SPARK_HOME=~/sw/spark-x.y.z-bin-distro % export PATH=$PATH:$SPARK_HOME/bin

이제 스파크 예제를 실행할 준비가 되었다.

19.2 예제 스파크를 시작하기 위해 먼저 스파크가 제공하는 스칼라 REPL인 spark-shell로 대화형 세션 3 http://spark.apache.org/ 4 https://spark.apache.org/downloads.html

682 4부 관련 프로젝트

을 구동하자. 다음과 같이 쉘을 시작하면 된다. % spark-shell Spark context available as sc. scala>

콘솔 출력을 통해 쉘이 자동으로 스칼라 변수인 sc를 생성한 것을 알 수 있다. 여기서 sc는 SparkContext 인스턴스를 저장한다. 이는 스파크의 대화 창구로 다음과 같이 sc를 이용하여

텍스트 파일을 읽을 수 있다. scala> val lines = sc.textFile("input/ncdc/micro-tab/sample.txt") lines: org.apache.spark.rdd.RDD[String] = MappedRDD[1] at textFile at :12

여기서 lines 변수는 탄력적인 분산 데이터셋 Resilient Distributed Dataset (RDD )을 참조한다. 이는 스파크에서 가장 중요한 개념으로, 클러스터에 있는 다수의 머신에 분할되어 저장된 읽기 전용 컬렉션이다. 전형적인 스파크 프로그램은 하나 또는 그 이상의 RDD를 입력받고, 일련의 변환 작업을 거쳐 목표 RDD 집합으로 변형된다. 이 과정에서 결과를 계산하거나 그 결과를 영구 저 장소에 저장하는 액션이 수행된다. ‘탄력적인 분산 데이터셋’에서 ‘탄력적’이란 단어는 유실된 파티션이 있을 때 스파크가 RDD의 처리 과정을 다시 계산하여 자동으로 복구할 수 있다는 의 미다. NOTE_ RDD로 데이터를 로드하거나 트랜스포메이션 transformation (변형 연산)을 수행해도 실제로 데

이터는 처리되지 않는다. 단지 계산을 위한 수행 계획이 만들어질 뿐이다. 실제 계산은 RDD를 처리하는 foreach()와 같은 액션을 호출할 때 수행된다.

프로그램으로 다시 돌아가자. 수행할 첫 번째 변환 작업은 각 행의 필드를 분할하는 것이다. scala> val records = lines.map(_.split("\t")) records: org.apache.spark.rdd.RDD[Array[String]] = MappedRDD[2] at map at :14

19장 스파크 683

RDD의 모든 항목에 함수를 적용하기 위해 RDD에 map ( ) 메서드를 적용했다. 예제에서는 각 라인(String )을 분할하여 스칼라 String 배열을 만들었다. 그다음에 잘못된 레코드를 제거하는 필터를 적용했다. scala> val filtered = records.filter(rec => (rec(1) != "9999" && rec(2).matches("[01459]"))) filtered: org.apache.spark.rdd.RDD[Array[String]] = FilteredRDD[3] at filter at :16

RDD의 filter ( ) 메서드는 조건절을 매개변수로 받고 불린값 Boolean 을 반환하는 함수다. 이 메서

드는 레코드를 검증하여 9999로 표기된 누락 기온이나 잘못된 특성 코드를 갖는 레코드를 제거 한다. 연도별 최고 기온을 찾기 위해서는 각 연도의 모든 기온값을 처리해야 하므로 연도 필드를 기준 으로 그룹짓는 연산을 먼저 수행해야 한다. 스파크는 이를 위해 reduceByKey ( ) 메서드를 제공 하지만, 이 메서드는 스칼라 Tuple2로 정의된 키-값 쌍의 RDD만 가능하다는 제약이 있다. 따 라서 RDD를 다른 map ( ) 메서드를 이용해서 Tuple2로 변환하는 작업을 먼저 수행해야 한다. scala> val tuples = filtered.map(rec => (rec(0).toInt, rec(1).toInt)) tuples: org.apache.spark.rdd.RDD[(Int, Int)] = MappedRDD[4] at map at :18

그다음에 집계 작업을 수행한다. reduceByKey ( ) 메서드의 인자는 값의 쌍을 입력으로 받아 이 를 단일 값으로 결합하는 함수다. 예제에서는 자바의 Math.max 함수를 사용했다. scala> val maxTemps = tuples.reduceByKey((a, b) => Math.max(a, b)) maxTemps: org.apache.spark.rdd.RDD[(Int, Int)] = MapPartitionsRDD[7] at reduceByKey at :21

foreach ( ) 메서드를 호출하고 각 항목을 콘솔에 출력해주는 println ( ) 을 인자로 넘기면 maxTemps의 내용을 화면에서 확인할 수 있다.

684 4부 관련 프로젝트

scala> maxTemps.foreach(println(_)) (1950,22) (1949,111)

foreach ( ) 메서드는 List와 같은 표준 스칼라 컬렉션과 동일하며, RDD의 각 항목에 적용되

는 함수다. 이 함수를 호출하면 스파크는 RDD의 값을 계산하는 잡을 바로 실행할 수 있으며, println ( ) 메서드를 통해 그 값을 볼 수 있게 된다.

화면에 출력하는 대신 RDD를 파일시스템에 저장할 수도 있다. scala> maxTemps.saveAsTextFile("output")

이 명령을 실행하면 파티션 파일을 포함한 output 디렉터리가 생성된다. % cat output/part-* (1950,22) (1949,111)

saveAsTextFile ( ) 메서드는 스파크 잡을 즉시 실행한다. 차이점은 반환값이 없다는 것이다.

대신 RDD를 계산하여 결과 파티션을 output 디렉터리에 파일로 기록한다.

19.2.1 스파크 애플리케이션, 잡, 스테이지, 태스크 예제에서 살펴본 바와 같이 스파크는 맵리듀스와 유사하게 잡이라는 개념이 있다. 스파크의 잡 은 맵리듀스의 잡보다 훨씬 일반적이다. 하나의 맵과 하나의 리듀스로 구성된 단일 맵리듀스의 잡과 달리 스파크의 잡은 임의의 방향성 비순환 그래프 directed acyclic graph (DAG )인 스테이지 stage 로 구성된다. 스파크가 실행될 때 스테이지는 다수의 태스크로 분할되고, 각 태스크는 맵리듀스의 태스크와 같이 클러스터에 분산된 RDD 파티션에서 병렬로 실행된다. 잡은 항상 RDD 및 공유변수를 제공하는 애플리케이션(SparkContext 인스턴스로 표현되는) 의 콘텍스트 내에서 실행된다. 하나의 애플리케이션은 하나 이상의 잡을 수행할 수 있으며, 직렬

19장 스파크 685

또는 병렬로 실행되며, 동일한 애플리케이션에서 수행된 이전 잡에서 캐싱된 RDD에 접근할 수 있는 메커니즘을 제공한다(RDD 캐싱 방법은 19.3.3절 ‘지속성’에서 설명함). spark-shell 세 션과 같은 대화형 스파크 세션은 애플리케이션을 위한 인스턴스 중 하나에 불과하다.

19.2.2 스칼라 독립 애플리케이션 스파크 쉘에서 프로그램을 개선한 후 이를 여러 번 실행할 수 있는 독립 프로그램으로 패키징할 수 있다. [예제 19-1]은 이러한 방법을 보여주는 스칼라 프로그램이다. 예제 19-1 스파크에서 최고 기온을 찾는 스칼라 애플리케이션

import org.apache.spark.SparkContext._ import org.apache.spark.{SparkConf, SparkContext} object MaxTemperature { def main(args: Array[String]) { val conf = new SparkConf().setAppName("Max Temperature") val sc = new SparkContext(conf) sc.textFile(args(0)) .map(_.split("\t")) .filter(rec => (rec(1) != "9999" && rec(2).matches("[01459]"))) .map(rec => (rec(0).toInt, rec(1).toInt)) .reduceByKey((a, b) => Math.max(a, b)) .saveAsTextFile(args(1)) } }

독립 프로그램을 실행할 때는 SparkContext를 제공하는 쉘이 없기 때문에 직접 만들어주어야 한다. 그리고 다양한 스파크의 속성 값을 애플리케이션에 전달할 수 있는 SparkConf라는 새로 운 인스턴스도 만들어야 한다. 예제에서는 애플리케이션의 이름만 설정했다. 작은 변경사항이 있다. 첫 번째는 입력과 출력 경로를 지정하는 명령행 인자를 사용한 것이고, 두 번째는 각 RDD의 임시 변수 생성을 피하기 위해 메서드를 연결한 것이다. 이렇게 하면 프로 그램을 좀 더 단순화시킬 수 있다. 필요하면 스칼라 IDE에서 각 변환 과정의 타입 정보도 확인 할 수 있다.

686 4부 관련 프로젝트

CHAPTER

20

HBase

조나단 그레이 Jonathan Gray 마이클 스택 Michael Stack

20.1 HBase 개요 HBase는 HDFS 기반으로 구현한 컬럼 기반 분산 데이터베이스 distributed column-oriented database 다. HBase는 대규모 데이터셋에서 실시간으로 읽고 쓰는 랜덤 액세스가 필요할 때 사용할 수 있는 하둡 애플리케이션이다. 데이터베이스의 저장과 검색에 관한 무수한 전략과 구현 방식이 존재하지만, 관계형 데이터베이 스와 같은 대부분의 솔루션은 대규모 확장성과 분산을 염두에 두고 개발된 것이 아니다. 많은 벤더에서 단일 노드의 한계를 뛰어넘는 데이터베이스로 발전시키기 위해 복제와 분할 기능을 제공하지만, 이러한 부가 기능은 나중에 고려된 것이며 설치와 유지보수도 매우 어렵다. 또한

RDBMS의 일부 기능에 심각한 문제를 초래하기도 한다. 예를 들어 확장된 RDBMS에서 조인, 복합 쿼리, 트리거, 뷰, 외부키 제약을 실행하면 엄청난 비용이 발생하거나 전혀 작동하지 않을 수도 있다.

HBase는 완전히 다른 방향에서 확장성 문제에 접근했다. 단지 노드만 추가하면 선형으로 확장 할 수 있는 기반부터 구축했다. HBase는 관계형 구조가 아니며 SQL을 지원하지 않지만 1 특정 1 17.4.3절 ‘SQL-on -Hadoop 대안’에서 언급한 아파치 포닉스(Apache Phoenix) 프로젝트와 HBase를 기반으로 만든 트랜잭션 SQL 데이터베이스인 트라포디온(Trafodion)(https://wiki.trafodion.org/)을 참고하라.

715

영역에서는 RDBMS가 할 수 없는 문제를 해결해준다. HBase를 이용하면 상용 하드웨어로 구 성된 클러스터에서 대용량의 산재된 테이블을 관리할 수 있다.

HBase의 대표적인 활용 사례는 수집된 웹페이지와 그 속성(언어, MIME 형식 등)을 가진 웹 테이블 webtable 이다. 웹테이블의 키는 웹페이지의 URL이다. 웹테이블은 매우 크며, 로우의 수가 수십억에 달하는 경우도 있다. 통계치를 얻고 검증된 MIME 형식을 위해 새로운 컬럼을 추가 하고 검색 엔진을 위한 색인을 구축하기 위해 텍스트를 파싱하는 등 웹테이블을 대상으로 일괄 분석이나 파싱을 수행하는 맵리듀스 잡이 지속적으로 수행된다. 동시에 다양한 속도로 동작하 는 크롤러가 무작위로 웹테이블에 접근하고 임의의 행을 갱신한다. 또한 사용자가 웹사이트의 캐시된 페이지를 클릭하면 실시간으로 임의의 웹페이지도 보여준다.

20.1.1 배경 HBase 프로젝트는 2006년 말 파워셋 Powerset 회사의 채드 월터스 Chad Walters 와 짐 캘러맨 Jim Kellerman

이 시작했다. HBase는 그 당시에 발표된 구글의 빅테이블 2을 모델로 하여 만들었다.

2007년 2월 마이크 카파렐라 Mike Cafarella 는 대부분의 기능이 작동하는 시스템의 초기 코드를 배 포하였으며, 짐 캘러맨이 이어서 발전시켰다.

2007년 10월 HBase의 첫 배포판이 하둡 0.15.0 버전에 포함되어 출시되었다. 그리고 2010년 5월 HBase는 하둡의 서브프로젝트에서 졸업하여 아파치 최고 수준의 프로젝트가 되었다. 오늘 날 HBase는 광범위한 산업 분야에서 상용으로 활용되는 성숙한 기술이다.

20.2 개념 이 절에서는 HBase의 핵심 개념을 간략하게 살펴볼 것이다. 대충 읽어보기만 해도 이어지는 내용을 이해하는 데 도움이 될 것이다.

2 페이 장( Fay Chang ) 공저 「빅테이블 : 구조화된 데이터용 분산 저장 시스템( Bigtable : A Distributed Storage System for Structured Data )」( http://research.google.com/archive/bigtable.html ) 2006년 11월

716 4부 관련 프로젝트

20.2.1 데이터 모델 둘러보기 애플리케이션은 테이블에 데이터를 저장한다. 테이블은 로우와 컬럼으로 이루어져 있다. 테이 블의 셀(로우와 컬럼의 교차점)은 버전별로 관리된다. 버전은 셀이 생성되거나 갱신될 때마다

HBase가 자동으로 할당하는 타임스탬프다. 셀의 내용은 바이트 배열이다. [그림 20-1]에서 사 진을 저장하는 HBase 테이블의 예를 볼 수 있다. 그림 20-1 사진을 저장하는 테이블을 도식화한 HBase 데이터 모델

컬럼 패밀리

컬럼 패밀리

로우 키 증가

버전



또한 테이블 로우 키도 바이트 배열이므로, 이론적으로 문자열부터 long 형의 바이너리 표현, 심지어 직렬화된 데이터 구조까지 어떠한 것도 로우 키로 사용할 수 있다. 테이블의 로우는 테이 블의 주 키 primary key 인 로우 키로 정렬된다. 정렬은 바이트 순서다. 모든 테이블은 주 키를 통해 접근할 수 있다.3 로우의 컬럼들은 컬럼 패밀리 column family 로 그룹지어진다. 모든 컬럼 패밀리의 멤버는 공통 접 두사를 가지는데, 예를 들어 info:format과 info:geo 컬럼은 모두 info 컬럼 패밀리의 멤버 며, 반면 contents:image는 contents 컬럼 패밀리에 속한다. 컬럼 패밀리의 접두사는 출력 가 능한 문자로 이루어져야 한다. 끝부분의 식별값, 즉 컬럼 패밀리 식별값은 임의의 바이트로 만들 수 있다. 컬럼 패밀리와 식별값은 항상 콜론 문자(: )로 나뉜다.

3 HBase는 테이블의 다른 컬럼에 대한 인덱스( 2차 인덱스 또는 보조 인덱스라고도 한다)를 지원하지 않는다. 그러나 2차 인덱스가 제공 하는 쿼리의 형태를 지원하는 여러 전략이 있는데, 이들은 저장 공간, 처리 부하, 쿼리 실행 시간 사이에 서로 다른 트레이드오프 관계가 존재한다. 자세한 사항은 HBase 레퍼런스(http://hbase.apache.org/book.html )를 참고하라.

20장 HBase 717

테이블의 컬럼 패밀리는 테이블 스키마를 정의할 때 미리 지정되어야 하지만, 새로운 컬럼 패밀 리 멤버는 언제든지 추가할 수 있다. 예를 들어 컬럼 패밀리 info가 테이블에 이미 존재한다면 클라이언트는 새로운 컬럼 info:camera와 저장할 값을 업데이트 동작으로 넣을 수 있다. 물리적으로 모든 컬럼 패밀리 멤버는 파일시스템에 함께 저장된다. 그래서 앞서 HBase를 컬럼 기반 저장소로 설명했지만 사실 컬럼 패밀리 기반 저장소로 기술하는 것이 더 정확할 것이다. 튜닝과 저장소 명세는 컬럼 패밀리 수준에서 이루어지기 때문에 모든 컬럼 패밀리 멤버는 동일 한 접근 패턴과 비슷한 크기를 갖는 것이 낫다. 사진 테이블에서 이미지 데이터는 보통 크기 때 문에(메가바이트) 이보다 더 작은 크기(킬로바이트)의 메타데이터와 다른(분리된) 컬럼 패밀 리에 저장된다. 요약하면 HBase 테이블은 RDBMS와 유사하지만, 셀은 버전별로 관리되고, 로우는 정렬되며, 컬럼이 속할 컬럼 패밀리가 미리 존재하는 한 언제든지 클라이언트는 컬럼을 추가할 수 있다.

리전 HBase는 테이블을 자동으로 리전 region 단위로 수평 분할한다. 각 리전은 테이블의 로우의 부 분집합으로 구성된다. 리전은 자신이 속한 테이블, 첫 번째 로우(포함), 마지막 로우(제외)로 정의된다. 초기에 테이블은 단일 리전만 존재하지만, 리전이 점차적으로 커지면서 설정된 임계 크기를 넘어서면 하나의 로우를 경계로 대략 동일한 크기의 새로운 리전 두 개로 분할된다. 처 음 분할될 때까지 모든 로딩은 초기 리전을 호스팅하는 단일 서버에서 일어난다. 테이블이 커 지면서 리전의 개수도 증가한다. 리전은 HBase 클러스터에 분산되는 단위다. 이런 식으로 하 나의 서버에겐 너무 큰 테이블도 서버 클러스터에서 다뤄질 수 있으며, 각 서버는 테이블의 전 체 리전의 일부분을 호스팅한다. 이것이 바로 테이블의 데이터 로드를 분산시키는 방식이다. 가 동되고 있는 정렬된 리전 집합은 테이블의 전체 내용을 나눠서 보관한다.

락킹 로우 업데이트는 로우 수준 트랜잭션에 포함된 로우 컬럼의 개수와 상관없이 원자적 atomic 이다. 이로 인해 락킹 locking 모델은 단순하다.

718 4부 관련 프로젝트

CHAPTER

21

주키퍼

지금까지 이 책에서 대용량 데이터 처리를 배웠다. 이 장에서는 하둡의 분산 코디네이션 Coordination 서비스인 주키퍼 ZooKeeper 를 이용해서 분산 애플리케이션을 구축하는 방법을 알아보겠다. 분산 애플리케이션을 작성하는 것은 매우 어려운 일이다. 가장 큰 이유는 부분 실패 partial failure 때 문이다. 네트워크로 연결된 두 노드 사이에 메시지가 전송된 후 네트워크가 끊겼을 때 송신자는 수신자가 메시지를 수신했는지 여부를 모르게 된다. 네트워크가 끊기기 전에 잘 도착했을 수도 있고 그렇지 않을 수도 있다. 어쩌면 수신자 프로세스가 메시지는 제대로 받았지만 처리 도중에 죽었을 수도 있다. 어떤 일이 일어났는지 송신자가 알 수 있는 유일한 방법은 수신자에게 다시 연결해서 물어보는 것이다. 이것이 바로 부분 실패, 다시 말해 작업의 실패 여부조차 모르게 되 는 상황이다. 분산 시스템에 있어서 부분 실패는 절대 피할 수 없기 때문에 주키퍼를 사용한다고 해도 부분 실 패가 완전히 사라지는 것은 아니며 완벽히 감출 수도 없다.1 그러나 주키퍼는 부분 실패를 안전 하게 처리할 수 있는 분산 애플리케이션을 구축하기 위한 도구를 제공한다. 주키퍼는 다음과 같은 특징이 있다.

1 이 내용은 짐 왈도(Jim Waldo) 공저 「분산 컴퓨팅에 대한 메모(A Note on Distributed Computing)」(http://www.eecs.harvard. edu/~waldo/Readings/waldo-94.pdf )( Sun Microsystems, November 1994 )에서 주장한 것이다. 분산 프로그래밍은 본질적 으로 로컬 프로그래밍과 다른데, 그 차이점은 단순히 덮고 넘어갈 수준이 아니다.

749

단순하다



주키퍼는 몇 개의 기본 기능을 핵심으로 제공하고 명령 및 통지와 같은 추상화 기능을 추가로 제공하는 간소화 된 파일시스템이다. 제공하는 기능이 풍부하다



주키퍼 프리미티브 primitive 는 대규모 데이터 구조와 프로토콜의 코디네이션에 사용되는 풍부한 구성요소를 제 공하고 있다. 코디네이션의 대표적인 예로는 분산 큐, 분산 락, 피어 peer 그룹의 대표 선출과 같은 것이 있다. 고가용성을 제공한다



주키퍼는 다수의 머신에서 실행되며 고가용성을 보장하도록 설계되었기 때문에 애플리케이션은 주키퍼의 이 러한 특성을 전적으로 신뢰하고 사용할 수 있다. 주키퍼는 시스템에서 발생할 수 있는 단일 장애점 single points of failure

(SPOF ) 문제를 해결하는 데 도움을 주므로 신뢰성 높은 애플리케이션을 개발할 수 있다.

느슨하게 연결된 상호작용에 도움을 준다



주키퍼가 동작할 때 참여자들은 서로에 대해 몰라도 상관없다. 예를 들어 랑데부 rendezvous 메커니즘으로 주키 퍼를 사용하면 프로세스가 상대방의 존재(또는 네트워크의 세부사항)를 모르더라도 서로 발견하고 소통할 수 있다. 심지어 코디네이션에 포함된 참여자들이 동시에 존재할 필요도 없다. 하나의 프로세스가 종료되기 전에 또 다른 프로세스가 읽을 수 있도록 주키퍼에 메시지를 남길 수 있기 때문이다. 라이브러리다



주키퍼는 일반적인 코디네이션 패턴에 대한 구현체와 구현 방법을 공유 저장소에 오픈 소스로 제공한다. 각 프 로그래머는 공통 프로토콜을 직접 개발(보통 제대로 개발하기 어렵다)해야 하는 부담에서 벗어날 수 있다. 오 픈 소스 커뮤니티는 기존 라이브러리를 꾸준히 향상시켜 모든 사람에게 이익이 되도록 할 것이다.

또한 주키퍼는 성능이 뛰어나다. 주키퍼를 만든 야후에서 테스트해본 결과 수백 개의 클라이언 트가 만들어내는 쓰기 위주의 작업 부하 벤치마크에서 초당 10,000개가 넘는 처리량을 보였다. 일반적인 사례인 읽기 위주의 작업 부하에서는 그보다 몇 배 높은 처리량을 보였다.2

21.1 주키퍼 설치와 실행 주키퍼를 처음 배울 때는 단일 머신에서 독립 모드로 실행하는 것이 좋다. 예를 들어 일단 단일 개발 머신에서 실행해보는 것이다. 주키퍼를 실행하려면 자바가 필요하므로 먼저 설치되어 있는 지 확인해야 한다. 2 벤치마크의 자세한 결과는 패트릭 헌트( Patrick Hunt ) 공저 「주키퍼: 인터넷 규모의 시스템을 위한 대기 시간 없는 코디네이션 (ZooKeeper : Wait-free coordination for Internetscale systems )」 논문(USENIX Annual Technology Conference, 2010 ) 에서 확인할 수 있다.

750 4부 관련 프로젝트

아파치 주키퍼 릴리즈 페이지 3에서 안정된 릴리즈 버전을 내려받은 다음 적당한 위치에서 압축 을 푼다. % tar xzf zookeeper-x.y.z.tar.gz

주키퍼는 서비스를 실행하고 상호작용할 수 있는 몇 개의 실행 파일을 제공하는데, 실행 파일이 포함된 디렉터리를 다음과 같이 명령행 경로에 포함하면 사용하기 편하다. % export ZOOKEEPER_HOME=~/sw/zookeeper-x.y.z % export PATH=$PATH:$ZOOKEEPER_HOME/bin

주키퍼 서비스를 시작하기 전에 환경 설정 파일을 구성해야 한다. 이 파일은 보통 서브디렉터리

conf 내에 있는 zoo.cfg다(/etc/zookeeper 또는 환경변수 ZOOCFGDIR에 지정한 디렉터리에 둘 수 있다). 다음 예제를 보자. tickTime=2000 dataDir=/Users/tom/zookeeper clientPort=2181

이것은 표준 자바 속성 파일이고, 이 예제에 정의된 세 개의 속성은 주키퍼를 독립 모드로 실행 할 때 필요한 최소한의 속성이다. 간략히 설명하면 tickTime은 주키퍼의 기본 시간 단위(밀리 초)고, dataDir는 주키퍼가 영속적인 데이터를 저장할 로컬 파일시스템의 위치며, clientPort 는 클라이언트의 연결을 기다리는 포트(일반적으로 2181 )다. dataDir는 사용자 시스템 환경 에 맞게 적절하게 변경해야 한다. 적절한 환경 설정을 정의했으면 이제 로컬 주키퍼 서비스를 실행할 준비가 되었다. % zkServer.sh start

주키퍼 실행 여부를 확인하기 위해 nc를 사용하여(telnet 역시 동작함) 클라이언트 포트로 ruok 명령(‘Are you OK?’)을 전송한다. 3 http://zookeeper.apache.org

21장 주키퍼 751

% echo ruok | nc localhost 2181 imok

imok은 주키퍼가 ‘I’m OK.’라고 응답한 것이다. [표 21-1]에서 ‘네 글자 단어’로 된 주키퍼 관

리 명령어를 볼 수 있다. 표 21-1 주키퍼 명령어 분류

명령어

설명

서버 상태

ruok

서버가 에러가 아닌 상태로 실행 중이면 imok 출력

conf

서버의 구성 정보 출력(zoo.cfg로부터)

envi

주키퍼 버전, 자바 버전, 그 외의 시스템 속성 등의 서버 환경 정보 출력

srvr

지연 시간, znode 개수, 서버 모드(독립 모드, 대표, 추종자) 등의 서버 통계 정보 출력

stat

서버 통계 정보와 연결된 클라이언트 출력

srst

서버 통계 정보 초기화

isro

서버가 읽기 전용(ro) 모드인지(네트워크 분할 때문에) 읽기/쓰기(rw) 모드인지 출력

클라이언트 연결

dump

앙상블의 모든 세션과 임시 znode를 나열. 이 명령어는 대표(srvr 참조)와 반드시 연 결해야 함

감시

cons

서버의 모든 클라이언트에 대한 연결 통계 정보를 나열

crst

연결 통계 정보 리셋

wchs

서버 감시에 대한 요약 정보 나열

wchc

연결 단위로 서버의 모든 감시 나열(주의: 많은 수의 감시는 서버 성능에 지장을 줄 수 있음)

wchp

znode 경로 단위로 서버의 모든 감시 나열(주의: 많은 수의 감시는 서버 성능에 지장을 줄 수 있음)

모니터링

mntr

갱글리아 Ganglia 와 나기오스 Nagios 같은 모니터링 시스템에 적합한 자바 속성 포맷으로 서버 통계 정보 나열

mntr 명령어와 더불어 주키퍼는 JMX로 통계 정보를 제공한다. 자세한 사항은 주키퍼 문서 4 를

참고하기 바란다. 또한 주키퍼 배포판의 src/contrib 디렉터리에서 모니터링 도구와 사용법을 살펴볼 수 있다. 주키퍼 3.5.0 버전부터는 ‘네 글자 단어’와 동일한 정보를 제공하는 내장 웹서버가 포함되어 있 다. 명령어 목록은 http://localhost:8080/commands에서 확인할 수 있다. 4 http://zookeeper.apache.org/

752 4부 관련 프로젝트

CHAPTER

22

서너의 구조적 데이터

라이언 브러시 Ryan Brush 미카 휘태커 Micah Whitacre

헬스케어 정보 기술의 이슈는 기존의 프로세스를 자동화하는 것이다. 하지만 변화가 일어나고 있다. 품질을 높이고 비용을 제어하기 위해서는 지금보다 더 좋은 시스템이 필요하다. 이 장에서 는 서너 Cerner 가 이러한 문제를 해결하기 위해 헬스케어 분야에 하둡 에코시스템을 어떻게 적용 했는지 살펴보겠다.

22.1 CPU에서 시맨틱 통합까지 서너는 전자 의료 기록 분야에서 시작하여 최근 헬스케어 기술까지 오랜 전통을 가진 기업으로 유명하다. 기존과 다른 접근 방법이 필요한 새로운 문제 때문에 서너는 하둡에 관심을 가지게 되 었다.

2009년 의료 기록의 검색 색인을 빠르게 만들 수 있는 기술이 필요했다. 하둡이 아닌 다른 아키 텍처로는 이 문제를 쉽게 해결할 수 없었다. 문서에서 단어를 추출하고 다른 단어와의 관계를 해 석하는 등 의료 문서를 처리하는 데 상당한 비용이 들기 때문에 검색 색인이 반드시 필요했다. 예를 들어 ‘심장질환’이라는 키워드를 입력하면 ‘심근경색’과 관련된 문서가 검색되어야 한다.

797

이러한 작업은 비용이 많이 든다. 대용량 문서 하나를 처리할 때 수 초가 걸리는데, 서너가 처리 할 문서는 수백만 개가 넘었다. 간단히 말하면 엄청난 CPU 파워가 필요했기 때문에 비용 대비 효 율이 높은 새로운 시스템이 요구되었다. 대용량 문서를 해석하기 위해 SEDA staged event-driven architecture 방식을 검토한 적도 있었다. 하지 만 수백만 개의 문서를 빠른 시간 안에 처리하는 작업이 매우 빈번했는데 하둡은 이런 면에서 큰 장점이 있었다. 의료 문서에서 지식을 추출하는 로직은 매우 빨리 발전했고 세상에 빨리 전해야 할 의무가 있었다. 하둡은 이미 존재하는 데이터에 새로운 맵리듀스 잡을 개발하여 실행하면 그 만이었다. 처리된 문서는 애플리케이션 질의를 제공하는 아파치 솔라 Solr 서버 클러스터로 로드 했다. 이러한 성공은 다음 단계의 프로젝트로 도약할 수 있는 초석이 되었다. 이런 방식의 시스템과 데 이터는 비용을 줄이고 전국민을 상대로 헬스케어 서비스를 제공하는 데 실증적인 근거가 될 수 있었다. 헬스케어 분야의 데이터는 시스템이나 조직에 따라 파편화되는 경향이 있기 때문에 가 장 먼저 시도한 작업은 전체 데이터를 모으고 그것을 이해하는 것이었다. 데이터의 출처와 포맷도 많았지만 이를 해석하는 표준 데이터 모델도 많았기 때문에 시맨틱 통 합 semantic integration 이란 엄청난 문제에 직면하게 되었다. 데이터의 크기는 사실 큰 문제가 되지 않았다. 하둡은 이미 우리가 원하는 확장성을 제공하고 있었지만, 데이터의 정제, 관리, 변환과 같은 작업은 너무 복잡했다. 이러한 복잡성을 해결할 수 있는 고수준의 도구가 절실히 필요했다.

22.2 아파치 크런치의 도입 이질적인 데이터셋을 통합하고 분석하기 위해서는 다음과 같은 요구사항을 만족해야 한다. 수많은 처리 과정을 각 모듈로 분리하고 이를 정교한 파이프라인으로 결합해야 한다.



맵리듀스보다 고수준의 프로그래밍 모델이 필요하다.



수백 개의 필드가 있고 여러 단계의 중첩 구조로 된 복잡한 의료 레코드 구조를 처리할 수 있어야 한다.



우리는 피그, 하이브, 캐스케이딩 등 다양한 도구를 검토해보았다. 각각은 잘 작동했고 추가로 비정형 분석을 위해 하이브도 사용했다. 하지만 복잡한 데이터 구조를 유연하게 처리하기에는 모든 도구가 부적합했다. 그러던 중 우리는 조쉬 윌스 Josh Wills 가 주도하는 크런치(18장 참조)

798 5부 사례 연구

프로젝트를 알게 되었다. 크런치는 구글의 FlumeJava 시스템과 유사하다. 크런치는 단순한 자 바 기반 프로그래밍 모델과 정적인 레코드 타입 검증 기능을 제공한다. 따라서 회사의 자바 개발 자도 좋아하고 다루는 데이터에도 적합했다.

22.3 완전한 설계도의 제작 대규모의 헬스케어 시스템을 이해하고 관리할 때 중요한 점은 엄청난 양의 데이터를 정제하고 정규화하고 관계를 맺는 작업이 필요하다는 것이다. 이러한 형태의 데이터는 많은 출처에 널려 있기 때문에 이를 통합하는 작업은 매우 어렵고 오류도 많다. 병원, 의사 사무실, 처방실, 클리닉 은 개인 의료 기록을 따로 보유하고 있으며, 그 데이터는 CCD Continuity of Care Document, HL7 Health Level 7

(헬스케어 데이터 공유 포맷), CSV 파일과 같은 업계 표준 파일 포맷 또는 소프트웨어 의

존 포맷 proprietary format 으로 되어 있다. 우리의 첫 번째 과제는 이러한 데이터를 확보한 후 정제되고 통합된 형태로 변환하는 것이었다. 그다음에는 이 데이터를 이용하여 환자의 특별한 상태를 관리하고 헬스케어 운영에 필요한 정보 를 측정하고 다양한 분석을 지원하는 것이다([그림 22-1] 참조). 그림 22-1 운영 데이터 흐름 원본 데이터

애플리케이션

청구

의료 기록

전자 의료 기록

건강상태

시맨틱 통합

운영 정보 측정

분석

여기서 핵심 단계는 정제된 시맨틱 통합 기초를 세우는 작업으로, 이 사례 연구에서 가장 중점을 두는 부분이다. 먼저 데이터를 공통 구조로 정규화하는 것부터 시작한다. 이 시스템의 초기 버전 은 다른 모델을 사용했으나, 지금은 에이브로를 이용하여 각 처리 과정 사이에 데이터를 저장하

22장 서너의 구조적 데이터 799

거나 공유하는 시스템으로 이전되었다. [예제 22-1]은 공통 구조를 보여주기 위한 간단한 에이 브로 IDL이다. 예제 22-1 공통 자료형을 위한 에이브로 IDL

@namespace("com.cerner.example") protocol PersonProtocol { record Demographics { string firstName; string lastName; string dob; ... } record LabResult { string personId; string labDate; int labId; int labTypeId; int value; } record Medication { string personId; string medicationId; string dose; string doseUnits; string frequency; ... } record Diagnosis { string personId; string diagnosisId; string date; ... } record Allergy { string personId; int allergyId; int substanceId;

800 5부 사례 연구

CHAPTER

23

생물학의 데이터 과학: 소프트웨어로 생명 구하기

매트 매시 Matt Massie

맵리듀스 논문1이 OSDI ’04에 나온 지 벌써 10년이 지났다는 사실이 믿기지 않는다. 맵리듀스 논문이 첨단 산업에 미친 영향은 과장해도 지나치지 않는다. 맵리듀스 패러다임은 비전문가도 분산 프로그래밍을 할 수 있고 일반 하드웨어로 구축된 클러스터에서 대규모 데이터를 처리할 수 있게 해주었다. 오픈 소스 커뮤니티는 아파치 하둡 및 스파크와 같은 오픈 소스 맵리듀스 기 반 시스템을 만들어 데이터 과학자 및 엔지니어가 예전에는 상상도 못했던 규모의 문제를 규정 하고 해결할 수 있도록 지원하고 있다. 첨단 산업이 맵리듀스 기반 시스템으로 발전하는 동안 생물학 분야는 2세대(또는 차세대) 시퀀 싱 기술로 인해 스스로 변화하고 있었다([그림 23-1] 참조). 시퀀싱 머신은 인간 유전 물질의 완 전한 집합인 게놈 genome 을 구성하는 화학 기호 문자(A, C, T, G )를 해독하는 과학 기계다. 맵 리듀스 논문이 발표된 2004년에 게놈의 염기서열을 얻으려면 약 2천만 달러가 들었고 수개월 의 시간이 걸렸다. 하지만 오늘날에는 불과 수천 달러면 충분하고 단 며칠밖에 걸리지 않는다. 최초의 인간 게놈을 만드는 작업은 수십 년이 걸렸지만, 2014년에만 전 세계에서 228,000개의 게놈이 시퀀싱되었다.2 이 추정치는 2014년에 약 20페타바이트의 시퀀싱 데이터가 전 세계에 서 만들어졌음을 의미한다. 1 http://research.google.com/archive/mapreduce.html 2 안토니오 레가라도(Antonio Regalado)의 「엠테크: 일루미나는 올해 228,000명의 인간 게놈이 시퀀싱될 것으로 예상한다(EmTech : Illumina Says 228,000 Human Genomes Will Be Sequenced This Year )」( 2014년 9월 24일)를 참고하라.

809

그림 23-1 빅데이터 기술과 게놈 시퀀싱 비용의 연대표

두 기술의 진화 게놈당 비용

2008년 차세대 시퀀싱 출현 2014년 일루미나는 전세계에서 228,000개의 게놈이 생성된 것으로 예상

2003년 인간 게놈 프로젝트에서 최초의 완전한 인간 게놈 발표

2014년 데이토나 그래이 정렬에서 아파치 스파크는 EC2 206개 노드에서 100TB를 23분에 정렬하여 세계 신기록 수립

2004년 2005년 아파치 구글 하둡 맵리듀스 논문

2009년 버클리에서 스파크 연구 시작 출처: 미국 국립 보건원(NIH) 국립 게놈 연구소(ganome.gov)

향후 몇 년 동안 시퀀싱 비용의 급감으로 게놈 데이터의 초고속 성장이 예상된다. DNA 데이터 의 홍수로 인해 생물학 분야의 데이터 과학자들은 최신 게놈 소프트웨어를 이용하여 적시에 확 장 가능한 방식으로 데이터를 처리하려고 매우 노력하고 있다. UC 버클리 대학의 컴퓨터 과학 분야 연구실인 AMPLab3은 독창적인 빅데이터 시스템과 애플리케이션을 개발하는 데 집중하 고 있다. 예를 들어 아파치 스파크(19장 참조)는 AMPLab에서 성장한 시스템 중 하나다. 스파 크는 최근 데이토나 그래이 정렬 Daytona Gray Sort 에서 100TB의 데이터를 불과 23분 만에 정렬하 여 세계 기록을 갱신했다. 또한 세계 기록을 깨뜨린 데이터브릭스 Databricks 4의 팀은 1PB의 데이 터를 4시간 이내에 정렬할 수 있다는 것도 입증했다. 오늘날 우리는 2014년에 수집된 모든 게놈을 수백 대의 머신에서 일 단위로 분석할 수 있는 기 술을 보유하고 있다는 엄청난 가능성을 고려하라.

AMPLab은 기술적인 이유로 게놈 연구를 빅데이터 애플리케이션의 최적의 대상으로 선택했지 만, 사실 더 중요한 이유는 인간애 때문이었다. 우리가 생물학 데이터를 적시에 처리할 수 있으면

3 https://amplab.cs.berkeley.edu/ 4 http://databricks.com/

810 5부 사례 연구

CHAPTER

24

캐스케이딩

크리스 K. 웬슬 Chris K. Wensel

캐스케이딩 Cascading 은 오픈 소스 자바 라이브러리로, 맵리듀스의 추상화 계층을 제공하는 API 다. 개발자는 캐스케이딩으로 하둡 클러스터에서 동작하는 복잡하고 중요한 데이터 처리 애플리 케이션을 만들 수 있다. 캐스케이딩 프로젝트는 2007년 여름에 시작되었다. 2008년 1월에 첫 번째 버전 0.1이, 2009 년 1월에 버전 1.0이 공개되었다. 프로젝트 웹 사이트 1에서 바이너리, 소스 코드, 애드온 모듈 을 내려받을 수 있다. 맵과 리듀스 연산은 강력한 프리미티브를 제공한다. 그러나 그들은 서로 다른 개발자들이 공유 해야 하는 복잡하고 고도로 합성 가능한 코드를 작성할 때 세분화 수준을 잘못 선택할 가능성이 높다. 게다가 많은 개발자는 실제 문제에 맞닥뜨렸을 때 맵리듀스 관점에서 ‘사고’하는 것을 어 려워한다. 첫 번째 문제를 해결하기 위해 캐스케이딩은 맵리듀스에서 사용되는 키와 값을 간단한 필드 이름 과 데이터 튜플 모델로 대체했다. 여기서 튜플은 단순히 값의 목록이다. 두 번째 문제를 해결하기 위한 대안으로 캐스케이딩은 더 높은 수준의 추상화 개념인 함수( Function ), 필터( Filter ), 집계자(Aggregator ), 버퍼(Buffer )를 도입하여 맵과 리듀스 연산에서 탈피했다. 1 http://www.cascading.org/

827

캐스케이딩 프로젝트의 초기 공개 릴리즈가 나올 무렵에 다른 대안들도 나타나기 시작했다. 그 러나 캐스케이딩은 이러한 다른 대안들의 문제점을 보완하는 데 중점을 두었다. 이러한 대안 프 레임워크가 만족시킨 사전 및 사후 조건, 기타 요구사항을 대부분 고려해서 개발되었다. 예를 들어 몇몇 다른 맵리듀스 도구는 애플리케이션을 실행하기 전에 사전 포맷, 필터 또는 하둡 분산 파일 시스템으로 데이터를 불러들이는 작업을 해야 한다. 즉, 프로그래밍 추상화 외에도 데 이터를 준비하는 단계를 수행해야 한다. 그에 반해 캐스케이딩은 데이터를 준비하고 관리하는 방법을 프로그래밍 추상화의 내장 요소로 제공한다. 이 장에서는 캐스케이딩의 주요 개념을 소개하는 것으로 시작해서, 쉐어디스 ShareThis 2의 인프라 에서는 캐스케이딩을 어떻게 사용하고 있는지 전체적으로 살펴볼 것이다. 캐스케이딩 처리 모델의 자세한 사항을 알고 싶으면 프로젝트의 웹 사이트에서 캐스케이딩 사용 자 안내서 3를 보기 바란다.

24.1 필드, 튜플, 파이프 맵리듀스 모델은 입력 데이터를 맵 함수로, 맵 함수에서 리듀스 함수로, 그리고 리듀스 함수에서 출력 데이터로 보내기 위해 키와 값을 사용한다. 하지만 알다시피 실제 하둡 애플리케이션은 보통 하나 이상 연결된 맵리듀스 잡으로 구성된다. 맵리듀스로 구현한 기본적인 단어 수 세기 예제의 결과를 내림차순으로 정렬하려 한다면 두 번 째 맵리듀스 잡이 필요하다. 요약하면 키와 값은 맵을 리듀스에 바인딩하고 리듀스를 그다음 맵에, 그리고 그다음 리듀스 등 으로 계속 연결할 때 필요하다([그림 24-1] 참조). 즉, 입력 파일에서 키-값 쌍을 가져와서 일 련의 맵과 리듀스 연산을 거쳐 마지막으로 출력 파일에 저장된다. 다수의 연결된 맵리듀스 애플 리케이션을 구현하려면 키-값 데이터 스트림을 수정하기 위해 반복해서 사용되는 잘 정의된 일 련의 키-값 조작을 면밀히 검토해야 한다.

2 http://www.sharethis.com/ 3 http://www.cascading.org/documentation/

828 5부 사례 연구

그림 24-1 맵리듀스에서 단어 수 세기와 정렬



리듀스



리듀스

소스 싱크

소스

싱크

키와 값의 쌍 키와 관련된 값의 모음

캐스케이딩은 키와 값을 사용하지 않고 상응하는 필드 이름이 있는 튜플로 대체하여 일련의 맵 리듀스 연산을 단순화시켰다. 튜플과 필드 이름은 관계형 데이터베이스의 테이블과 컬럼 이름과 유사한 개념이다. 작업을 수행하는 동안 필드와 튜플 스트림은 파이프로 연결된 사용자 정의 연 산을 거치면서 순서대로 처리된다([그림 24-2] 참조). 그림 24-2 필드와 튜플로 연결된 파이프

파이프

소스

파이프

파이프

필드 이름을 가진 튜플

파이프

싱크

캐스케이딩에서 맵리듀스의 키와 값은 다음과 같이 변경되었다. 필드



필드는 문자형 이름(예를 들면 ‘first_name’)이나 수치형 위치(예를 들면 세 번째와 마지막 위치를 각각 2와 -1로 표현) 중 하나 또는 둘의 조합으로 된 집합이다. 따라서 필드는 튜플에 있는 값의 이름을 정의할 때 사용 되며, 원하는 튜플의 값을 조회할 수 있다. 튜플의 값을 조회하는 것은 SQL의 select 호출과 유사하다.

24장 캐스케이딩 829

튜플



튜플은 단순한 java.lang.Comparable 객체의 배열이다. 튜플 하나는 데이터베이스의 한 행이나 레코드와 매우 유사하다.

그리고 맵과 리듀스 연산은 하나 이상의 파이프 인스턴스로 추상화된다([그림 24-3] 참조). 그림 24-3 파이프 종류

파이프

Each



Each 파이프는 한 번에 하나의 입력 튜플을 처리한다. 입력 튜플에 함수나 필터 연산을 적용할 수 있다. GroupBy



GroupBy 파이프는 그룹 필드를 기준으로 튜플을 그룹화한다. 이것은 SQL의 GROUP BY 절과 유사하게 동작 한다. 또한 여러 개의 입력 튜플 스트림이 같은 필드 이름을 공유하고 있다면 하나의 스트림으로 병합할 수 있 다. CoGroup



CoGroup 파이프는 여러 개의 튜플 스트림을 공통 필드 이름으로 조인하고, 또한 공통 그룹 필드를 기준으로 튜플을 그룹화한다. 둘 또는 그 이상의 튜플 스트림에 모든 표준 조인(내부, 외부 등)과 사용자 지정 조인을 사 용할 수 있다. Every



Every 파이프는 한 번에 하나의 튜플 그룹을 처리한다. 여기서 사용되는 그룹은 GroupBy나 CoGroup 파이 프로 그룹화된 것이다. Every 파이프는 각 그룹에 집계자나 버퍼 연산을 적용할 수 있다. SubAssembly



SubAssembly 파이프는 하나의 파이프 내부에 어셈블리 중첩을 허용한다. 또한 반복적인 중첩도 가능하다.

830 5부 사례 연구

개발자는 이러한 모든 파이프를 함께 연결하여 파이프 어셈블리를 만들고, 각 어셈블리는 많은 입력 튜플 스트림(소스)과 많은 출력 스트림(싱크)을 가질 수 있다([그림 24-4] 참조). 그림 24-4 간단한 파이프 어셈블리 파이프 어셈블리 소스

싱크

소스

얼핏 보기에는 이러한 방식이 전통적인 맵리듀스 모델보다 더 복잡해보일 수 있다. 그리고 확실 히 맵, 리듀스, 키, 값보다 더 많은 개념이 있다. 하지만 실제로는 서로 협력할 수 있는 개념이 많 을수록 더 다양한 동작을 제공할 수 있다. 예를 들어 리듀서의 값을 ‘2차 정렬’하려는 개발자는 맵, 리듀스, ‘합성’ 키(하나의 부모 키에 내 포된 두 개의 키), 값, 파티셔너, ‘출력값 그룹화’ 비교기, ‘출력키’ 비교기 모두를 서로 다른 방 식으로 조합해야 한다. 이러한 특성 때문에 차후의 애플리케이션에서 예전에 만든 코드를 다시 사용하는 것은 매우 어렵다. 캐스케이딩에서 이것은 다음과 같이 한 줄의 코드로 표현한다. new GroupBy(, , )

여기서 는 전 단계에서 온 파이프다.

24.2 연산 앞서 언급했듯이 캐스케이딩은 개별 튜플이나 튜플 그룹에 적용하는 대체 연산을 도입하여 맵리 듀스에서 벗어났다([그림 24-5]).

24장 캐스케이딩 831

함수



함수는 개별 입력 튜플에 동작하고, 모든 입력에 대해 0 또는 하나 이상의 출력 튜플을 반환한다. 함수는 Each 파이프에 의해 적용된다. 필터



필터는 특별한 종류의 함수로, 튜플 스트림에서 현재 입력 튜플의 제거 여부를 가리키는 불린값을 반환한다. 이런 목적을 위해 그냥 함수를 사용할 수도 있지만 필터는 이러한 경우에 좀 더 최적화되어 있다. 그리고 많은 필터는 AND, OR, XOR, NOT과 같은 ‘논리적’ 필터로 그룹화할 수 있어서 복잡한 필터링 연산을 빠르게 수행할 수 있다. 집계자



집계자는 공통의 필드 값(예를 들면 동일한 ‘last -name’ 값을 가진 모든 튜플)으로 그룹화된 튜플에 적용되 는 연산이다. 일반적인 집계자로는 Sum, Count, Average, Max, Min 등이 있다. 버퍼



버퍼는 유일한 그룹의 모든 튜플에 걸쳐 ‘슬라이딩 윈도우 sliding window ’처럼 동작하는 데 최적화되어 있다는 점 을 제외하면 집계자와 비슷하다. 버퍼는 개발자가 순서가 있는 튜플 안에 누락된 값을 추가할 필요가 있을 때 (누락된 날짜 혹은 기간과 같은)나 수행 평균 running average 을 생성할 때 유용하다. 보통 집계자는 튜플 그룹을 처리할 때 사용하는 연산으로 많은 집계자를 연결해서 함께 사용하면 매우 효율적이다. 하지만 가끔은 버퍼가 더 적합할 때도 있다. 그림 24-5 연산의 종류

연산

함수

필터

집계자

버퍼

연산은 파이프 어셈블리가 생성되었을 때 파이프와 결합된다([그림 24-6] 참조).

832 5부 사례 연구

w w w. h a n b i t . c o . k r

이것이 프로그래밍이다! 저자 직강 동영상 제공!

이것이 안드로이드다

이것이 C언어다

이것이 자바다

진정한 안드로이드 개발자로 이끌어줍니다.

세상에 없던 새로운 C언어 입문서 탄생!

가장 중요한 프로그래밍 언어를 하나 배워야 한다면, 결론은 자바다!

SDK 5.0 롤리팝 호환!

삼성, LG에서 펼쳐졌던 전설의 명강의를 풀타임 동영상 강좌로!

중급 개발자로 나아가기 위한 람다식, JavaFX, NIO 수록

이보다 더 확실한 방법은 없다, 칠판강의

책만 보고, 동영상 강좌로도 만족하지 못했다면 Daum 카페 '슈퍼드로이드'에서 만나요

전체 동영상 강좌 유투브 전격 공개!

자바의 모든 것을 알려주는 인터넷 강의 궁금한 것은 카페에서!

cafe.daum.net/superdroid

http://goo.gl/tJK3Tu

cafe.naver.com/thisisjava

박성근 저 | 1,164쪽 | 45,000원

서현우 저 | 708쪽 | 25,000원

신용권 저 | 1,224쪽 | 30,000원

w w w. h a n b i t . c o . k r

지금은 모던 웹 시대! 모던 웹 디자인을 위한

모던 웹을 위한

HTML5 + CSS3 입문 HTML5 분야 부동의 1위 도서

JavaScript + jQuery 입문

HTML5 표준안 확정에 맞춘 완전 개정판의 귀환!

자바스크립트에서 제이쿼리, 제이쿼리 모바일까지 한 권으로 끝낸다!

HTML5 권고안과 최신 웹 브라우저 환경 대응

시대의 흐름에 맞춰 다시 쓴 자바스크립트 교과서

윤인성 저 | 624쪽 | 30,000원

윤인성 저 | 980쪽 | 32,000원

모던 웹을 위한

HTML5 + CSS3 정복

Node.js

프로그래밍 페이스북, 월마트, 링크드인은 왜 Node.js를 선택했는가?

필요한 것만 배워 바로 현장에서 쓰는 HTML5

이 물음에 대한 답은 Node.js가 보여주는 빠른 처리 능력 때문이다.

순서대로 읽으며 실습할 수 있는 HTML5 자습서

윤인성 저 | 484쪽 | 25,000원

김상형 저 | 700쪽 | 32,000원

w w w. h a n b i t . c o . k r

Hanbit eBook

Realtime w w w. h a n b i t . c o . k r / e b o o k

DRM free! 어떤 디바이스에서도 자유롭게

eBook Oriented! 전자책에 꼭 맞는 최적의 내용과 디자인

Hanbit eBook

Hanbit eBook

Realtime 70

Realtime 89 49

MFC 프로그래밍 주식분석 프로그램 만들기 김세훈 지음

Hanbit eBook

Hanbit eBook

Realtime 90

Realtime 92 49

자바 개발자를 위한

Vert.x JavaScript Promise​ azu​지음 /​주우영​옮김

애플리케이션 개발 모바일/웹 메시징 STOMP와 MQTT로 개발하는 IoT 모바일/웹 애플리케이션 Mobile and Web Messaging 제프 메스닐 지음 / 조건희 옮김

이연복 지음

w w w. h a n b i t . c o . k r

즐거운 상상이 가득! 2015년 화제의 신간

즐거운 상상이 가득! 2015년 화제의 신간

전자부품 백과사전 vol.1 찰스 플랫 지음 / 배지은 옮김 / 30,000원

취미공학에 필요한 핵심 전자부품을 사전식으로 정리한 안내서.

전자부품 백과사전 vol.1 찰스 플랫 지음 / 배지은 옮김 / 30,000원

처음 시작하는 센서

취미공학에 필요한 핵심 전자부품을 사전식으로 정리한 안내서.

전자부품 백과사전 vol.2

찰스 플랫 지음 / 가격미정

키모 카르비넨, 테로 카르비넨 지음 임지순 옮김 / 13,000원

세상을 수치로 읽어내는

시리즈의 두 번째 도서다.

부품인 센서를 알려주 는 책. 이 책을 통해 자신 만의 프로젝트에 다양한 처음 센서를 사용해보자.

Zero to Maker

: 누구나 메이커가 될 수 있다 데이비드 랭 지음 / 장재웅 옮김 / 14,000원

전자부품 백과사전 vol.2

찰스 플랫 지음 / 가격미정

일반인에서 메이커로. 날백수에서 무인 잠

시리즈의 수정 회사 CEO 가 된 사나이, 데이비드두 번째 도서다. 랭의 메이커 도전기.

Make: 센서

시작하는 센서

키모 카르비넨, 테로 카르비넨 지음 임지순 옮김 / 13,000원

세상을 수치로 읽어내는 부품인 센서를 알려주

키모 카르비넨, 테로 카르비 넨, 빌 발토카리 지음 는 책. 이 책을 통해 자신 / 가격미정

만의 프로젝트에 다양한

필수 전자부품인 센서를

센서를 사용해보자. 마이크로 컨트롤러 보드

Zero to Maker

: 누구나 메이커가 될 수 있다

에 응용하는 방법을 담

데이비드 랭 지음 / 장재웅 옮김 / 14 ,000원 Maker Pro

았다.

베이첼 지음 / 가격미정 일반인에서 메이커로.존날백수에서 무인 잠

메이커라면 반드시 읽어야 할 필수 계발

수정 회사 CEO가 된 사나이, 데이비드 서. 프로 메이커들과의 인터뷰 및 에세이 랭의 메이커 도전기. 수록.

프로젝트로 배우는 라즈베리 파이

도날드 노리스 지음 / 임지순 옮김

다양한 실전 프로젝트를 통해 라즈베리 파이를 쉽고 재미있게 배워본다.

Maker Pro 존 베이첼 지음 / 가격미정

메이커라면 반드시 읽어야 할 필수 계발

Make: 센서 키모 카르비넨, 테로 카르비 넨, 빌 발토카리 지음 / 가격미정

필수 전자부품인 센서를 마이크로 컨트롤러 보드 에 응용하는 방법을 담 았다.

신뢰성과 확장성을 갖춘 분산 시스템을 구축하고 관리하는 방법 H a d o o p

T h e

D e f i n i t i v e

데이터의 숨겨진 힘을 끌어내는 최고의 클라우드 컴퓨팅 기술

G u i d e

프로젝트 예제와, 헬스케어 시스템과 유전체 분석 사례가 새로이 추가되었다. 대규모 데이터셋을 분석하 는 개발자와 하둡 클러스터를 구축하고 실행하는 시스템 관리자를 위한 최고의 지침서다.

•맵리듀스, HDFS, YARN

•하둡 클러스터 관리 및 설정

•애플리케이션 개발

•에이브로로 데이터 직렬화하기

•피크, 하이브, 크런치, 스파크

•파케이로 중첩 데이터 처리하기

•분산 데이터베이스 HBase

•플룸으로 데이터 수집하기

•분산 설정 서비스 주키퍼

•스쿱으로 데이터 일괄 전송하기

4판

여러분은 진정한 고수에게서 하둡의 기술적인 측면뿐만 아니라 상식적이고 일반적인 개발 방법까지도

Hadoop The Definitive Guide

의 바이블로 손꼽히는 책으로서, 이번 4판에서는 하둡 2.0 기반 YARN과 파케이, 플룸, 크런치, 스파크

하둡 완벽 가이드

하둡은 신뢰성과 확장성을 갖춘 분산 시스템을 구축하고 관리하는 최선의 선택이다. 이 책은 하둡 분야

배울 기회를 얻었습니다. 더그 커팅, 하둡 창시자, 클라우데라

오픈스택 인 액션

클라우드 시스템을 관리하는 기술

처음 시작하는 AWS 람다

예제 소스 www.hanbit.co.kr/src/2459

톰 화이트 지음

장형석, 장정호, 임상배, 김훈동 옮김

관련 도서

하둡 완벽 가이드

4판

시스템 관리 / 클라우드

93000

9 788968 484599

ISBN 978-89-6848-459-9

정가 55,000원

톰 화이트 지음 장형석, 장정호, 임상배, 김훈동 옮김

Get in touch

Social

© Copyright 2013 - 2024 MYDOKUMENT.COM - All rights reserved.