원리금 균등분할 상환이라는 이름의 덫

이 글은 크몽 재능인, nathan.ree님이 원고를 기고하셨습니다.

약탈적 대출이라는 용어가 있다. 일반적으로 판단하는 약탈적 대출이란, 부족한 채무상환능력을 지닌 사람에게 빼앗을 자산 (담보, 급여압류) 을 보증케 하거나 또는 보증인을 정하는 방식으로 상환능력 이상의 돈을 빌려주는 것을 말한다. 특히 경기가 안 좋은 최근의 대출은 투자나 기타 구입비용 보다는 생계를 위한 대출이 대부분을 차지하고 있다고 해도 과언이 아닌지라 대출을 하면 할 수록 점점 소득대비 과도한 상환비율을 갚아나가야 하는 악순환을 거치게 되므로 대부분 약탈적 대출에 속한다.

소득이 없는 대학생에게 신용카드를 발급해주거나, 1금융권에서 대출이 어려운 서민들에게 말도 안 되는 과도한 이자율을 내세워 울며 겨자 먹기로 대출을 사용하게끔 만드는 2,3 금융권의 어이없는 행태 역시 약탈적 대출에 포함된다.

4년제 대학 졸업자의 40%가 졸업과 동시에 1,000 만원 이상의 빚을 지게 된다는 설문조사 결과 또한 현재 우리나라의 대출구조가 얼마나 소비자 보호와는 거리가 먼 지 알려주는 데이터다. 특히 2금융권에서 의무적으로 원리금균등분할상환방식을 채택하고 있는 것이 얼마나 무서운 것인가에 대해 논술하고자 한다.

원리금균등분할상환이란

상환초기 원금은 거의 상환되지 않고, 대부분 이자만 납부하게 되며, 대출 후기로 갈 수록 이자부담이 적어지면서 원금이 많이 상환되는 방식을 말한다.

예를 들어보자

신용등급이 6등급 이하로 안 좋은 편에 속하거나 기존 대출이 연 소득수준에 육박하는 경우, 국내 시중은행인 1금융권에서는 대출이 거의 불가능하다. 따라서 대부분의 대출 신청자들은 국내 저축은행 및 캐피탈권, 심지어 대부업체를 이용하게 되는데 여기서부터 두 가지 문제가 발생한다

  1. 평균 20% 이상의 살인적인 고금리 (심지어 30%대도 즐비하다, 현재 대한민국의 법정 최고금리는 39%)
  2. 원리금균등분할상환방식만을 선택할 수 있음
  3. 높은 조기상환 수수료 (평균 1%에서 많게는 4%까지)

해당 대출기관이 원리금균등분할상환방식만을 고집할 때 올 수 있는 가장 치명적인 덫은 대출자의 조기상환심리(여유자금이 생길 때마다 부담스러운 빚을 일찍 갚아버리기 위한 심리) 를 역이용하여 대출 초기에 이자를 많이 부담시킴으로써 해당 대출기관의 수익을 극대화시킨다는 점이다.

신용등급 6~7등급에 해당하는 대출자가 3,000 만원을 울며 겨자 먹기로 29.9% 금리 약정한 후 5년간 원리금 균등분할 상환시에 아래에 나와있는 일정대로 상환하게 된다.

:: 계산 결과

pyo1

pyo2

본 표에 나와있듯이 상환초기부터 무려 33개월까지는 납입해야 하는 이자가 원금보다 많다. 33개월이 지나면서 납입원금이 이자보다 겨우 많아지기 시작하는데 바로 여기서 문제가 발생한다. 현재 국내 가계대출자 1,200만명 중 평균 대출 납입완료 시점은 대출기간 중간 이전에 끝나는 경우가 70%에 육박할 정도로 많다 (금융연구원 자료, 2009)

그렇다면 원리금균등상환방식을 강제로 채택 당하고 있는 대부분의 상환자들은 대출 초기 여유자금이 생겨 돈을 갚으려 해도 생각보다 너무나 비싼 조기상환 수수료에 한 번 울고 상환방식의 특성상 중반까지 원금보다는 이자만 잔뜩 납부했기에 생각보다 엄청나게 남아있는 원금 때문에 또 한 번 울게 된다

게다가 현재 시중의 2금융권 대출기관 (저축은행, 캐피탈) 들은 원리금균등분할상환방식이 그 어떤 상환방식보다 이자를 덜 낼 수 있는 상환방법이라고 공공연하게 홍보마저 하고 있으니 이 것이 바로 약탈적 대출이 아니고서야 무엇일까?

사람이 살면서 갑자기 어려운 일이 생겨 돈을 필요로 하는 경우는 쉽게 찾아볼 수 있다. 지푸라기라도 잡고 싶은 대출자의 심리를 교묘하게 역이용하여 원리금균등분할상환방식만을 강요하여 조기 상환하려는 대출자에게 최대의 수익을 뽑아내는 금융권들은 지금이라도 정책을 수정하여 다양한 대출상환방식 중 대출자에게 유리한 방식을 본인 스스로 선택하게끔 해주어야 한다고 생각한다.

아울러 저렇게 살인적인 금리를 부과하는 이유 또한 소득수준을 넘어선 위험한 대출이기 때문이라는 은행의 리스크 관리 차원에서 비싼 금리를 부과할 수 밖에 없다는 말도 안 되는 명분 또한 당장 폐지하여 선진국처럼 2금융권 대출금리를 10% 중반대로 끌어내려야 한다고 생각한다. 그 것이 현재 말 못하고 가슴을 치며 매 달 금융기관의 이자놀음에 멍들어가는 수많은 서민들을 구하는 길이다.

크몽 재능

수트 무비(Suit Movie)

이 글은 크몽 재능인, perot님이 원고를 기고하셨습니다.

사무엘 L.잭슨 주연의 영화 ‘샤프트(Shaft, 1999)’에서는 한 악당이 주인공 샤프트를 밀치는 장면이 나온다. 이때 기분이 나빠진 샤프트가 소리치는 한 마디!

“내 아르마니에 함부로 손대지 마!”

그렇다. 그가 입은 옷은 구겐하임 미술관에 상당한 기부금을 내고 전시 공간 대부분을 자신의 작품(?)들로 채워 넣은 아르마니의 것이었다.

  • 깔끔한 수트,
  • 빳빳한 와이셔츠의 칼라,
  • 은은한 컬러의 넥타이,
  • 자켓 소매 사이로 간간히 보이는 반짝이는 커프스 링크…

영화 속의 남자 주인공들과 주변 인물들이 이러한 모습을 하고 등장하는 경우가 종종 있다. 남자 영화, OO 느와르 등으로 불리면서, 다소 딱딱하면서도 차가운 분위기가 전반적인 영화의 이미지로 각인되는 것들이다. 물론 이 외에도 다양한 장르 속에서 이런 모습의 남자 주인공과 주변 인물들이 다양한 모습으로 나타나고 있다. 이처럼 깔끔한 수트 차림의 주인공과 주변 인물들이 영화 속의 스토리를 이끌어 나가는 영화 장르를 수트 무비(Suit Movie)라는 하나의 또 다른 장르로 분류해서 보면, 수트 무비가 가지고 있는 특징들이 몇 가지 있다는 것을 알 수 있다.

 

수트 무비, 남성미를 찬양하다!

수트 무비는 남성적인 미가 가장 잘 표현되어 있는 장르다. 수트라는 의상 자체가 남성의 미를 가장 아름답게 표현할 수 있는 아이템이기도 하거니와, 영화의 내용 또한 남성미를 부각시키는 과정을 그리고 있는 경우가 대부분이기 때문이다. 가장 대표적인 수트 무비라고 할 수 있는 말론 브란도와 알 파치노 주연의 영화 “대부(Mario Puzo’s The Godfather, 1972)” 시리즈에서 보여주는 남성들의 여러 모습들은 여성 못지않게 남성 또한 아름다워질 수 있다는 것을 잘 말해 준다.

미국에 대부가 있다면 아시아에서는 바로 홍콩 느와르라고 불리는 주윤발표 액션 영화가 있었다. 블랙 코디네이션에 선글라스, 그리고 이쑤시개를 물고 있는 홍콩 느와르에 표현된 주윤발은 남성미에 대한 찬양을 넘어, 폭력 미학에 대한 논란까지 불러 일으키면서 수트 무비란 이런 것이다라는 것을 잘 말해 주었다. 이러한 홍콩 느와르는 마이클 만 감독의 영화 “히트(Heat, 1995)”로 이어져, 선악의 대결 구도에서 보여지는 남성미를 극도의 차가움으로 표현하는 데에 크게 일조했다.

국내에서는 조폭 영화에서 주로 수트 무비 스타일이 다루어지고 있지만, 헐리우드나 홍콩은 수트 무비 스타일을 통해서, 수트 무비이기 때문에 가능한 시나리오와 아름다운 남성에 대한 다양한 영상미들로 가득 채우면서 관객들의 가슴을 설레게 하고 있다. 그리고 바로 수트 무비의 남성미에 대한 찬양의 중심에는 많은 디자이너가 서 있다. 수트 무비는 남성복 디자이너의 수트 아이템을 가장 아름답게 표현할 수 있는 가장 남성적인 매체이기 때문이다.

수트 무비, 디자이너를 만나다!

서두에 예를 든 영화 샤프트가 아니더라도 많은 수트 무비에는 디자이너의 수트들이 등장한다. 화려한 캐스팅이 압권인 영화 “언터처블(The Untouchable, 1987)”은 디자이너 아르마니가 최고의 전성기를 누릴 수 있게 만든 수트 무비의 대표작이다. 깔끔한 수트와 트렌치 코드, 그리고 우수에 젖은 듯한 눈빛으로 악과 대결하는 주인공들의 모습에서 수트 무비 스타일은 극에 달했으며, 그와 함께 아르마니의 수트 또한 크게 빛났다.

untouchables
[Figure 1] 영화 언터처블의 포스터
깔끔한 아르마니의 수트가 크게 돋보인 영화. 이는 곧 아르마니가 세계적으로 큰 명성을 얻으며 전성기를 누리게 되는 가장 큰 요인이 되었다.

이처럼 수트 무비는 스타일에 있어서 차별화되는 요소가 거의 없는 남성복 디자이너의 수트 아이템에 미묘한 이미지를 부각시키는 효과적인 역할을 한다. 그러므로 아르마니의 성공 이후 많은 남성복 디자이너들이 헐리우드에 러브콜을 외치면서 수트 무비의 남성미를 자신의 수트 아이템에 부여하려는 노력을 쉬지 않고 있다. 수트 무비 속에 그려진 남성미의 이미지가 곧 디자이너 브랜드의 이미지에 각인되기 때문이다. 그리고 수트 무비에서 남성미의 아름다운 선을 잘 표현할 수 있는 디자이너의 수트가 필수적인 영화 소품이 되면서, 수트 무비와 디자이너 수트는 상호 보완적인 길을 걷게 된다.

수트 무비, 배우를 만들다!

수트 무비와 디자이너가 이처럼 필연적인 관계를 갖게 되면서 진정한 남성미를 가진 배우의 존재가 점점 부각되기 시작했다. 대부의 알 파치노와 007시리즈의 숀 코네리 등이 1대 수트 무비 배우라면, 오션스 일레븐(Ocean’s Eleven, 2001)의 조지 클루니와 브래드 피트는 2대 수트 무비 배우라고 할 수 있다. 이들은 수트 차림이 너무나도 잘 어울리며, 수트를 통해서 남성미를 가장 잘 표현할 수 있는 배우들이다. 수트 무비가 가진 남성미를 극대화하는 영상과 디자이너의 수트, 그리고 이 수트가 잘 어울리는 배우의 만남은 바로 진정한 수트 무비를 만들어 내고 있는 것이다.

수트 무비의 중심에 선 배우들은 그 시대의 가장 닮고 싶은 남성상에 자신의 이름이 거론되는 것을 즐기면서 진정한 남성미에 대한 표본이 되어 간다. 스타일리시(Stylish)라는 말이 잘 어울리는 배우가 되며, 섹시(Sexy)한 남성, 깔끔하고 세련된 이미지 등을 가진 배우라는 평가를 받으며, 수트 무비의 진화와 함께 배우 또한 진화하게 되는 것이다. 이처럼 수트 무비는 그 시대의 가장 남자다운 배우를 만들어 나가면서 그 기준을 제시하고, 메트로섹슈얼(Mertosexual)이라는 미명하에 점점 양성화되어 가고 있는 성에 대한 모호한 구분의 추세 속에서도 진정한 남성의 아름다움을 보여 주면서 남성을 지켜 주는 역할을 하고 있다.

수트 무비는 진화한다!

snatch
[Figure 2] 영화 스내치의 등장 인물
유머러스한 시나리오와 다양한 색감의 브리티시 룩이 돋보이는 스타일이 특징인 가이 리치 감독의 영화 스내치는 수트 무비의 진화된 모습을 잘 보여 준다.

예전의 수트 무비는 깔끔한 블랙 수트에 선글라스, 차가운 영상과 우수에 젖은 듯한 눈빛, 그리고 폭력 등이 주요 키워드였다면, 최근에는 그 트렌드가 다소 변하고 있다. 가이 리치 감독의 “록 스탁 앤 투 스모킹 배럴즈(Lock, Stock and Two Smoking Barrels, 1999)”와 “스내치(Snatch, 2001)”에서 보여지는 브리티시 룩(British Look)의 다양한 컬러감과 소재감이 특징인 수트와 덥수룩한 수염, 유머러스한 미소와 눈빛, 오션스 일레븐과 같은 다소 부담이 덜한 시나리오 등이 최근 수트 무비의 큰 트렌드라고 할 수 있다.

그리고 이러한 수트 무비의 진화와 함께 많은 남성복 디자이너의 수트 또한 브리티시 룩을 반영한 스타일이 많아지고 있으며, 그 시대의 남성상을 대표하는 배우의 기준 또한 수트가 잘 어울리면서도 유머러스하고 여유를 가진 인물로 변하고 있다. 영화 “나를 책임져, 알피(Alfie, 2004)”에서 깔끔한 수트를 입고 많은 여성들과 유머러스한 잡담을 나누면서 분위기를 이끌어 가는 주드 로가 바로 그러한 인물이다. (벌써 주드 로는 세계에서 가장 섹시한 남자 1위에 등극했다!) 이처럼 수트 무비는 점점 진화하면서 이 시대의 가장 세련된 스타일과 가장 남성다운 미를 한 발 앞서서 뭇 남성들에게 새로운 미에 대한 기준을 말해 주고 있는 것이다.

알피

[Figure 3] 영화 나를 책임져, 알피의 포스터
현재 주드 로는 수트 무비의 가장 진화된 모습을 보여 주는 배우이며, 세계에서 가장 섹시한 남자이다.

 

한국형 수트 무비를 말한다!

한국의 영화 산업은 아주 급속도로 발전해 왔다. 영화 “쉬리(1998)”의 흥행 이후, 기적과도 같은 관객 동원 1,000만을 돌파한 “실미도(2003)”, “태극기 휘날리며(2003)” 등까지 정말로 쉬지 않고 달려 왔다. 그러는 과정에서 이런 저런 많은 장르적인 시도와 한국 영화만의 독특한 색깔 찾기가 있었지만, 수트 무비에서는 그다지 큰 진화의 모습은 보여 주지 않고 있는 것 같다.

초기에는 주로 조폭 스타일이 수트 무비에 반영되면서 폭력물의 대표적인 스타일로 자리잡기 시작하더니, 그 후 학원 폭력물에 조폭 스타일이 더해 지면서 전혀 엉뚱한 길로 나가고 있는 듯 한 느낌을 주고 있다. 바로 “두사부일체(2001)”가 그 대표작이라고 할 수 있다. 이러한 수트 무비의 성숙하지 못 한 모습은 한국의 남성미에 대한 모멸감을 느끼게 해 주는 것이며, 한국 영화의 발전에 있어서도 큰 방해 요소가 아닌가 하는 생각이다.
그때 그사람

[Figure 4] 영화 그 때 그 사람들의 포스터
늘 같은 모습만 보여 주었던 한국의 대표적인 수트 무비 배우 한석규가 이번 영화 “그 때 그 사람들(2005년 2월 개봉 예정작)에서는 좀 더 진화된 모습으로 한국형 수트 무비의 가능성을 보여 주었으면 하는 바람이다..

사실 수트 무비는 그 시대의 남성상을 상징적으로 표현할 수 있는 문화의 집합체이다. 그러므로 헐리우드의 수트 무비는 바로 세계의 남성미를 하나의 서구화된 기준으로 묶어 가고 있는 남성 문화의 중심이라고 볼 수 있다. 우리는 헐리우드의 수트 무비를 접하면서 주인공의 직업, 주인공의 옷, 주인공의 행동 하나하나까지 동경하고 닮아 가기 위해 노력한다. 그리고 점점 서구의 남성미에 대한 기준에 동화되어 간다. 이는 결코 바람직한 현상이 아니다. 우리는 우리 나름대로의 남성미를 가지고 있으며, 또한 이를 지켜야 할 의무가 있다.

한국형 수트 무비의 존재는 한국적인 남성미가 존재하며, 남성의 아름다운 선을 살릴 수 있는 남성복 디자이너가 존재하며, 남성 문화의 정체성을 가지고 있다는 것을 의미한다. 그리고 앞으로 한국이 가질 수 있는 세계적인 경쟁력이 바이오 산업과 영화로 대표되는 문화 산업임을 봤을 때, 한국형 수트 무비의 존재는 반드시 필요한 장르라고 할 수 있다. 이는 곧 한국적인 남성 문화를 지키는 길이기 때문이다.

크몽 재능

 

 

[독후감] 거침없이 하둡 활용해 보기

이 문서는 [거침없이 배우는 하둡(Chuck Lam 지음 / 이현남, 강택현 옮김 / 지앤선 출판사)]을 읽고 쓴 독후감이다.

hadoop_in_action_face

가장 기본적인 내용은 간단히 정리해보고, 지금까지 미처 활용하지 못했던 몇가지 팁을 작성하고자 한다.

하둡이란

하둡(Hadoop)은 빅데이터를 처리할 수 있는 분산 응용 프로그램을 작성하고, 실행하기 위한 오픈 소스 프레임워크다. 분산 컴퓨팅 플랫폼은 하둡 외에도 다양하게 존재하지만, 하둡은 아래와 같은 차이점을 갖는다.

  • 접근성(Accessibility)
    하둡은 다수의 범용 컴퓨터를 이용하여 쉽게 클러스터를 구성할 수 있다. 또는 아마존의 EC2(Elastic Compute Cloud)와 같은 클라우드 인프라를 간단히 활용할 수도 있다.
  • 견고함(Robust)
    하둡은 범용 컴퓨터로 구성된 클러스터상에서 실행되도록 설계되었기 때문에, 하드웨어가 고장이 나더라도 쉽게 복구할 수 있다.
  • 확장가능성(Scalability)
    처리 속도나 저장 용량을 늘리고자 할 때, 단순히 컴퓨터를 더 추가함으로써 선형적으로 확장이 가능하다.
  • 단순함(Simplicity)
    분산된 컴퓨터에서 병렬적으로 처리되는 프로그램을 손쉽게 개발할 수 있다.

<하둡의 설계 철학>

프로그램은 일반적으로 데이터를 프로그램이 있는 컴퓨터에 가져와서 처리하게 된다. 반면 하둡의 경우, 데이터가 있는 컴퓨터에 프로그램을 전송해서 그 곳에서 데이터를 처리한다. 따라서 실제 데이터가 저장되어 있는 컴퓨터에서 데이터가 처리된다. 데이터가 대용량이라는 점을 감안해 볼 때, 데이터를 옮기는 것보다 프로그램을 옮기는 것이 당연하며, 하둡은 이러한 철학을 따라 만들어졌다.

MapReduce 살펴보기

MapReduce 프로그램은 map과 reduce, 2단계로 이루어진다. map 단계에서는 입력 데이터를 필터링하여 reduce 단계에서 처리할 수 있는 형태로 변경한다. reduce는 map의 출력 값을 입력 값으로 받은 후, 데이터를 통합한다.

하둡의 구성 요소

하둡은 아래의 데몬들로 구성된다.

  • NameNode(네임노드)
  • DataNode(데이터노드)
  • Secondary NameNode(세컨데리 네임노드)
  • Job Tracker(잡 트래커)
  • TaskTracker(태스크 트래커)

hadoop_diagram

  •  NameNode
    하둡은 마스터/슬레이브 구조를 가진다. 네임노드는 HDFS에서 마스터 역할을 하며, 슬레이브 역할을 하는 데이터 노드에게 I/O 작업을 할당한다. 네임노드는 현재 이중화 구성을 할 수 없어서, 하둡 클러스터를 운영할 때 단일 장애 지점이 된다.
    * 네임노드 백업 및 이중화에 대해서는 조금 후에 살펴보도록 하겠다.
  •  DataNode
    실제 데이터는 데이터노드에 저장된다. 클라이언트가 HDFS에 파일을 읽거나 쓰기 위해 네임노드에게 요청을 날리면, 네임노드는 어느 데이터노드의 어디 블록에 파일이 있는지(또는 쓸지)를 알려준다. 그러면 클라이언트는 데이터노드와 직접 통신하여, 파일을 읽거나 쓰게된다. 다시 말해, 데이터노드와 블록 위치가 정해지면 클라이언트는 네임노드와는 전혀 통신하지 않고, 해당 데이터 노드와 직접 통신한다.
    클러스터가 처음 시작될 때, 각 데이터 노드에서 자신의 블록 정보를 네임노드에게 알려준다. 그런 후 데이터 노드는 자신의 로컬 디스크에 변경사항이 발생할 때마다 네임노드에게 변경사항을 알려주게된다.
  •  Secondary Name Node
    세컨데리 네임노드는 HDFS의 블록이 변경되더라도 실시간으로 변경정보를 갱신하지 않는다. 세컨데리 네임노드는 네임노드의 블록정보를 병합할 때 사용하기 위한 노드이며, 백업 노드도 아니고 stand by 네임 노드는 더더욱 아니다.
    하지만 네임노드에 장애가 발생할 경우를 대비해서 백업용 노드로 활용할 수 있다. 그리고 네임노드가 장애가 난 경우, 세컨데리 네임노드를 네임노드로 활용할 수도 있다. 이러한 작업은 모두 자동화 되지 않으며, 수작업으로 처리해야 한다.
    * 네임노드 백업 및 이중화에 대해서는 조금 후에 살펴보도록 하겠다.
  •  JobTracker
    클라이언트가 요청한 작업(job)에 대한 실행을 관리한다. 일반적으로 잡트래커는 마스터 노드, 즉 네임노드가 설치된 노드에서 실행한다.
  •  TaskTracker
    작업을 실제로 처리하는 일은 태스크트래커가 맡는다. 슬레이브 노드, 즉 데이터 노드에는 하나의 태스크트래커만이 존재하며, 여러개의 JVM을 생성해서 다수의 map과 reduce를 실행하게 된다.
    mapreduce

Job Chaining

복잡한 문제가 있을 때 하나의 프로그램으로 처리할 수도 있지만, 작은 책임만을 가지도록 프로그램을 나누면 프로그램을 유지보수하기가 쉬워진다. MapReduce에서도 여러개의 작은 Job을 연결하여 복잡한 문제를 처리할 수 있다.

  • Job Pipeline(잡 파이프라인)
    Job A와 Job B가 있고, A 작업이 끝난 후 A 작업의 출력을 B 작업의 입력으로 사용해야 한다고 해보자. 수작업으로 A 작업이 끝난뒤, B 작업을 실행할 수도 있지만, 파이프라인을 이용하면 여러개의 Job을 서로 연결할 수 있다.
    job_A | job_B위와 같이 실행한 경우, job_A의 드라이버가 실행 된 후, job_B의 드라이버가 실행된다. 그리고 job_A의 결과 파일이 job_B의 입력파일로 설정된다.
  • Job Dependency(잡 의존성)
    여러가지 Job이 있고, 각 Job이 모두 순차적으로 실행되지는 않을 경우 단순히 파이프라인만으로는 실행 순서를 결정할 수 없다. 예를 들어 job_A, job_B, job_C가 있고, job_A와 job_B는 job_C보다 먼저 실행되어야 하지만, job_A와 job_B는 어느 순서로 실행되어도 되는(또는 동시에 실행되어도 관계 없는) 경우를 가정해보자. 이 경우 아래와 같이
    job_A | job_B | job_C
    또는
    job_B | job_A | job_C와 같이 실행해도 원하는 결과를 얻을 수 있다. 하지만 처리속도는 최적화되지 않는데, job_A와 job_B는 동시에 실행하는 편이 낫기 때문이다. 이러한 경우 의존성을 직접 설정하여 처리 순서를 결정할 수 있다.예를 들어 job_C에 대해 아래와 같이 설정할 수 있다.
    job_C.addDependingJob(job_A);
    job_C.addDependingJob(job_B);이렇게 설정하면, job_A와 job_B가 종료된 후 job_C가 실행되는 것을 보장한다.
    이처럼 의존성이 결정된 job은 모두 JobControl 객체에 등록해야하며, 이때 addJob() 메서드를 이용한다.
    의존성과 job 등록이 완료되면, JobControl.run() 메서드를 실행하여 job을 실행할 수 있다.
    JobControl에는 allFinished() 메서드와, getFailedJobs() 메서드가 있어 job들의 실행상태를 모니터링할 수 있다.
  • ChainMapper와 ChainReducer
    데이터를 처리할 때 두가지 책임을 갖는 매퍼를 만드는 경우가 있다. 예를 들어 웹로그를 읽어서 사용자 접근 유형을 분석하는 MapReduce를 개발한다고 해보자. 이경우 아래와 같은 처리흐름을 따라 처리할 수 있다.
    – 로그 정규화 및 유효하지 않은 라인 제거 : 입력 파일의 로그 중에서, 정해진 로그 포맷에 맞지 않는 라인을 걸러낸다.
    – 클라이언트 Ip별로 매핑 : 클라이언트 IP를 키로, 상태가 200인 접근 로그를 값으로 매핑한다.
    – 클라이언트 IP별 접근 유형 리듀싱 : 클라이언트 IP별로 접근 로그를 분석하여 결과파일로 리듀싱한다.
    – 리듀싱된 결과 DB에 로드 : 리듀싱된 결과를 DB에 로드한다.하나의 Job으로도 위의 로직을 모두 구현할 수 있으나, 첫번째 유효성 검사 작업과 마지막 DB 로드 작업은 다른 Job에서도 공통적으로 필요한 모듈이므로 별도의 모듈로 관리하면 재사용이 용이하다. 따라서 아래와 같이 Job을 구조화해볼 수도 있다.
    Job_A | Job_B | Job_CJob_A
    – mapper : 웹로그의 입력을 읽어 정규화한다. 키는 라인번호, 값은 로그 라인 전체를 매핑한다.
    – reducer : IdentityReducer를 사용한다.Job_B
    – mapper : 클라이언트 Ip별로 매핑. 키는 클라이언트 IP, 값은 접근 로그
    – reducer : 클라이언트 IP별 접근 유형 리듀싱. 키는 클라이언트 IP, 값은 분석 결과Job_C
    – mapper : 분석 결과를 DB로 로드한다. 출력은 없음
    – reducer : 없음
    이처럼 파이프라인을 활용하면 책임에 따라 Job을 하위 모듈로 구조화할 수 있지만, 각 단계마다 중간 결과를 처리해야 하므로 I/O가 발생하게 된다.이와는 달리 아래와 같이 구조화할 수도 있다.
    Job_A_mapper | job_B | job_C_mapper
    (Job_A_mapper | job_B_mapper | job_B_reducer | job_C_mapper)즉, 전처리 단계는 모두 매퍼에서 실행하고, 후처리 단계는 리듀서 이후에 실행하는 방식이다. 이때 ChainMapper와 ChainReducer를 사용할 수 있다. 위의 로직을 의사 코드로 작성해보면 아래와 같다.

    ChainMapper.addMapper(Job_A_mapper);
    ChainMapper.addMapper(Job_B_mapper);
    ChainReducer.setReducer(Job_B_reducer);
    ChainReducer.addMapper(Job_C_mapper);

IsolationRunner을 활용한 태스크 재실행

TDD를 바탕으로 MapReduce를 개발하더라도, 실행단계에서는 예외가 발생하기 마련이다. 이러한 경우 스택 트레이스를 눈으로 확인해서 디버깅을 하게 되는데, 그 과정이 상당히 번거로울 뿐만 아니라 버그를 찾기도 쉽지 않다. 이를 위해 하둡에서는 ISolationRunner라는 유틸리티를 제공한다. ISolationRunner를 사용하면 실패한 태스크에 대해, 실패할 당시의 데이터를 사용하여 해당 태스크만 독립적으로 실행할 수 있다.

ISolationRunner를 사용하려면 keep.failed.tasks.files 속성을 true로 설정해야 한다. true로 설정한 후 Job을 실행하면, 태스크가 실패한 경우 해당 데이터를 보관하게 된다.

자세한 사용법은 하둡 ISolationRunner튜토리얼을 참고한다.

MapReduce 성능 향상을 위한 팁

컴바이너(Combiner)의 활용

매퍼의 결과값이 큰 경우, 매퍼의 결과를 모두 리듀서로 전달할 때 네트워크 I/O에서 병목이 발생할 수 있다. 이러한 경우에는 컴바이너를 활용하면 성능이 향상될 수 있다. 별도의 컴바이너 프로그램을 구현하기보다는, 리듀서를 매퍼 단계에서 적용하여 매핑의 결과를 줄이는 효과를 내기 위해서 사용한다.

압축하기

컴바이너를 활용하더라도, 매퍼의 결과인 중간 단계의 데이터가 클 수 있다. 이러한 경우 중간 데이터를 압축하면 성능을 개선할 수 있다. 매퍼의 결과를 압축하기 위해서는 아래의 속성을 설정해야 한다.

속성 설명

  • mapred.compress.map.output
    매퍼의 출력을 압축하지 여부
  • mapred.map.output.compression.codec
    매퍼의 출력을 압축할 때 사용할 코덱 클래스

이 두 속성은 설정파일에 전역 속성으로 설정하기보다는, Job의 성격에 따라 JobConf 객체에 설정하는 편이 낫다.

압축할 때 사용할 수 있는 코덱에는 DefaultCodec, GzipCodec, BZip2Codec 등이 있다.

리듀스의 출력 데이터는 중간단계의 데이터가 아닌 최종 결과물인 경우가 많다. 따라서 리듀스의 출력을 압축하는 경우 문제가 된다. 출력값이 하둡의 블록 사이즈(보통 64MB)보다 큰 경우, 압축된 출력 결과가 2개 이상의 블록으로 분할되게 된다. 대다수의 압축형식에서 이처럼 분할된 압축 파일을 개별적으로 압축 해제할 수 없다. 결국 리듀서의 출력 값을 입력 값으로 사용하는 또다른 Job이 있는 경우, 각 블록마다 태스크가 실행되는 대신 하나의 태스크만 실행되므로 병렬 처리라는 장점을 잃게 된다.

이를 위해 하둡에서는 SequenceFile이라는 특별한 형태의 파일을 지원한다.

JVM의 재사용

태스크트래커는 매퍼와 리듀서에 대해, 별도의 JVM을 새로 할당하여 자식 프로세스로 실행한다. 따라서 초기화 작업이 복잡한 경우, JVM을 실행하는데 시간이 오래 걸린다. 이처럼 JVM을 새로 시작하는데 시간이 오래 걸린다면, Job을 실행하는 전체 시간도 오래 걸린다.

하둡 0.19 버전에서는 동일한 Job의 여러 태스크에 대해 JVM을 재사용할 수 있다. JVM을 재사용하면 태스크의 시작 비용을 줄일 수 있다. JVM을 재사용하려면, mapred.job.reuse.jvm.num.tasks 속성을 변경한다. 또는 JobConf 객체의 setNumTasksToExecutePerJvm(int) 메서드를 활용할 수도 있다.

추론적 실행(Speculative Execution)

맵리듀스 프레임워크는 맵 태스크나 리듀스 태스크가 실패한 경우, 자동으로 태스크를 재실행한다. 이처럼 재실행할 수 있는 이유는 동일한 태스크가 여러번 실행되더라도 동일한 결과가 나오도록 보장하기 때문이다. 이는 수학적 용어로 “멱등성이 보장된다”라고 부른다.

태스크가 실패하지 않더라도 동일한 태스크가 여러번 실행될 수 있다. 예를 들어 특정 노드에서만 태스크가 느리게 진행될 수 있다. 이는 자원 상황(CPU, I/O 등)에 따라 해당 시점에만 발생할 수 있는 경우다. 이 경우 하둡은 동일한 태스크를 다른 노드에서도 실행하게 되며, 가장 빨리 완료된 태스크의 결과를 최종 결과로 사용하며 종료되지 않은 나머지 태스크는 종료시킨다. 이러한 기능을 추론적 실행이라고 부른다.

기본적으로 추론적 실행은 true로 설정되어 있으며, 맵과 리듀서에 대해 개별적으로 설정할 수 있다.

  • mapred.map.tasks.speculative.execution : 매퍼에 대한 설정
  • mapred.reduce.tasks.speculative.execution : 리듀서에 대한 설정

태스크가 모두 완료되어야만 Job이 완료되므로, 특정 태스크가 느리게 처리되는 경우 Job의 전체 실행시간 또한 느려지게된다. 따라서 추론적 실행을 사용하면, 특정 상황에 종속되지 않고 Job의 실행시간이 평균적으로 빠르게 처리된다는 점을 보장한다.

하지만 일반적으로는 추론적 실행을 사용하지 않는다. 이는 태스크가 멱등성을 가지지 않는 경우가 많기 때문이다. 예를 들어 분석 결과를 DB에 저장하는 경우, 추론적 실행을 사용하면 동일한 데이터가 DB에 저장되므로 중복 저장되는 결과를 낳게 된다. 따라서 실행하려는 Job의 특성에 따라 추론적 실행을 설정해야 한다.

DB와의 상호작용

맵리듀스 프로그램의 입력 데이터가 DB에 있거나, 맵리듀스의 결과를 DB에 저장해야 하는 경우가 있을 수 있다. 이 중에서 입력 데이터를 DB에서 가져와야 하는 경우에는 매퍼에서 DB 커넥션을 얻어서 처리하는 방식은 지양해야 한다. 입력 데이터가 많은 경우, 매퍼의 개수는 그에 맞게 늘어나게 되며 결국 DB 커넥션의 수도 그만큼 증가하게 된다. 이 경우 DB에 과부하가 걸리며 전체 Job의 실행 속도가 늦어지거나, DB 자체에 장애가 발생할 수도 있다.

따라서 입력 데이터를 DB로부터 읽어야하는 경우에는 드라이버 클래스에서 DB 커넥션을 하나만 얻어와서 입력 데이터를 파일로 만든 후, 각 맵에서는 해당 파일을 사용하도록 구현해야 한다.

반대로 맵 리듀스의 결과를 DB에 저장해야하는 경우에는 각 리듀서에서 DB 커넥션을 얻어와서 처리할 수 있다. 리듀스는 매퍼에 비해 동시에 실행되는 수가 아주 적으므로, DB 커넥션 또한 많이 사용하지 않기 때문이다. 하둡에서는 이를 위해 DBOutputFormat 클래스를 제공한다.

DBOutputFormat

먼저 드라이버에서 출력 포맷을 DBOutputFormat으로 설정한 후, DB 커넥션 정보는 DBConfiguration 클래스의 configureDB() 메서드를 활용해서 설정한다. 그리고 출력할 데이터를 DBOutputFormat 클래스의 setOutput() 메서드를 활용해서 설정한다.


conf.setOutputFormat(DBOutputFormat.class);
DBConfiguration.configureDB(job, drvierClass, dbUrl, userId, userPass);
DBOutputFormat.setOutput(job, tableName, col1, col2, col3, ...);

태스크 개수 할당 규칙

태스크트래커는 동시에 실행할 수 있는 맵과 리듀서의 최대 개수를 설정할 수 있으며, 기본값은 4개다(맵 2개, 리듀서 2개). 일반적으로 코어 하나당 2개의 태스크를 할당한다. 따라서 쿼드 코어라면 총 6개의 태스크를 설정할 수 있다(맵 3개, 태스크 3개). 태스크 트래커와 데이터노드가 각각 하나의 태스크를 사용하므로, 결국 총 8개의 태스크가 실행되게 된다. 이 경우 전제사항은 해당 태스크에서 CPU를 많이 사용하기 보다는 I/O 작업이 많은 경우다. 만약 CPU 사용이 많은 태스크라면, 설정은 조금 낮추어야 한다.

동시에 실행할 맵과 리듀서의 개수는 각 Job별로 설정할 수도 있다. 맵의 경우 입력 데이터의 크기에 따라 자동으로 설정되며, 리듀서의 개수는 직접 설정이 가능하다. 별도로 설정하지 않는 경우 각 Job별로 하나의 reduce 태스크만 할당된다. 일반적으로 클러스터에서 리듀서 태스크트래커 최대 개수에 0.95 또는 1.75를 곱한 값을 사용한다.

fsck

하둡은 파일 시스템의 상태를 검사할 수 있는 fsck 유틸리티를 제공한다.

bin/hadoop fsck /path/to/directory

fsck

over-replicated 블록 또는 under-replicated 블록의 경우, 시간이 지나면 자동으로 정상으로 돌아온다. 하지만 mis-replicated 블록, corrupt 블록, missing replicas의 경우에는 자동으로 복구가 불가능하다. 이 경우 문제가 된 블록을 삭제하려면, fsck 명령어에 -delete 옵션을 사용한다. 또는 -move 옵션을 사용해 일단 /lost-found로 옮긴 후, 이후에 복구작업을 수행할 수도 있다.

권한 관리

하둡은 일반적으로 하둡이 실행된 시스템의 사용자 권한 체계를 그대로 따른다. 주의할 점은 하둡을 실행한 사용자는 하둡 파일 시스템에서 슈퍼유저로 분류된다. 만약 슈퍼유저 권한을 또다른 사용자에게 주고자한다면, dfs.permissions.supergroup 파라미터를 설정한다.

데이터노드 제거 및 추가

특정 데이터노드가 장애가 난 경우, 단순히 노드를 클러스터에서 네트워크 연결을 끊더라도 HDFS은 정상적으로 운영된다. 그리고 장애가 난 데이터노드에 있던 블록을 복제 계수를 맞추기 위해 자동으로 복제작업을 시작한다. 하지만 좀더 안정적으로 제거하고자 한다면 디커미션(decommsion) 기능을 사용해야 한다.

먼저 네임노드가 설치된 노드에서 dfs.hosts.exclude 파일에 제거할 노드를 “호스트명 IP” 형태로 추가한다. 그런후 네임노드에서 아래의 명령어를 실행한다.

bin/hadoop dfsadmin -refreshNodes

그러면 네임노드는 디커미션 작업을 실행하여 해당 노드를 제거하게 된다.

데이터노드 추가 작업 또한 간단하다. 단순히 데이터노드 데몬과 태스크트래커 데몬을 실행하면 된다. 네임노드가 재실행될 경우를 대비해서, 네임노드의 conf/slaves 파일에 추가할 데이터노드를 추가하는 것도 잊지 말자.

이보다 중요한 작업은 데이터를 옮기는 일이다. 추가된 새로운 노드에는 디스크가 비어 있으므로, 기존의 데이터노드에서 블록을 복제하여 새로운 노드에 복사해야 한다. 이를 위해 밸런서를 실행해야 한다.

bin/start-balancer.sh

위의 명령어는 백그라운드에서 실행되며, 데이터 분포가 균형을 이룰때까지 실행된다.

클러스터가 균형을 이룬다는 말은 각 데이터노드의 사용률이 시스템의 평균 사용률의 임계치 내에 들어왔다는 말이다 일반적으로 임계치는 10%이다. 밸런서를 실행할 때, 임계치를 설정할 수 있다. 아래는 임계치를 5%로 설정하여 밸런서를 실행하는 경우다.

bin/start-balancer.sh -threshold 5

네임노드와 세컨데리 네임노드

네임노드는 시스템의 메타데이터와 블록에 대한 위치정보를 메모리에 유지한다. 네임노드는 드라이브 문제로 인한 데이터 손실을 막기 위해서 RAID 드라이브를 사용해야 한다.

네임노드는 HDFS에 저장된 파일의 블록에 대한 매핑정보를 메모리에 유지하므로, 블록이 많아질수록 성능이 느려질 수 있다. 따라서 블록 사이즈를 크게 하면 매핑정보가 그만큼 줄어들게 된다. 반면에 블록 사이즈가 커지면, 맵리듀스에서 병렬적으로 처리할 수 있는 태스크의 개수가 작아지므로, 입력 파일의 사이즈가 작은 경우 Job 프로그램의 실행속도가 느려질 수도 있다.

기본적으로 블록 사이즈는 64MB이며, 경우에 따라 128MB로 설정하기도 한다. 블록 사이즈는 dfs.block.size 속성을 설정하면 된다.

세컨데리 네임노드로 구동할 노드는 반드시 네임노드와 동일한 하드웨어 스펙을 사용해야 한다. 이를 이해하려면 네임노드와 세컨데리 네임노드 사이의 관계에 대해 이해하여야 한다.

secodary-name-node

네임노드는 fsimage와 edlits 로그 파일을 이용하여 파일 시스템의 상태정보를 관리한다. fsimage 파일은 파일 시스템 전체의 특정 시점에 대한 스냅샷이며, edits 로그 파일은 해당 시점 이후의 변경사항을 기록한 로그 파일이다. 따라서 두 개의 파일을 이용하면 파일 시스템의 현재 상태를 정확히 알 수 있다.

네임노드가 구동될 때 네임노드는 두 파일을 병합하여 현재 시점에 대한 스냅샷을 fsimage 파일에 기록한다. 그리고 비어 있는 edits 로그 파일이 만들어진다. 이후의 변경사항은 모두 edits 로그 파일에 기록된다. 네임노드는 파일 시스템의 상태 정보에 대한 복사본(fsimage와 edits 로그 파일이 병합된 정보)을 메모리에 상주시켜, 클라이언트 요청에 빠르게 응답한다.

이때 문제는 edits 로그 파일이 너무 커질 경우, 네임노드를 재기동할 때 병합하는 시간이 오래 걸리므로 재기동하는 시간 또한 오래 걸리게 된다. 이를 위해 fsimage 파일과 edits 로그 파일을 병합하는 작업을 주기적으로 실행하게 된다. 네임노드의 경우 파일 시스템 전체에 대한 마스터 역할을 수행하므로, 병합 작업과 같이 자원을 많이 차지하는 작업은 별도의 노드에서 수행하게 되는데, 바로 이 서버가 세컨데리 네임 노드다. 즉 세컨데리 네임노드는 네임 노드로부터 fsimage 파일과 edits 로그 파일을 fs.checkpoint.dir 디렉토리로 주기적으로 가져와서 병합하여, 해당 시점의 스냅샷을 기록한다. 그리고 병합된 fsimage 파일은 다시 네임노드로 복사하며, 네임노드는 병합된 fsimage 파일을 저장하게 된다.

따라서 세컨데리 네임노드는 백업용 노드가 아닌, 현재 상태의 파일 시스템 정보를 기록하기 위한 체크포인트 서버로 이해해야 한다. 결국 세컨데리 네임노드는 네임 노드와 동일한 파일을 관리해야 하므로 최소한 동일한 크기의 메모리를 보장받아야 한다.

네임노드 장애복구

현재 네임노드는 이중화 구성을 할 수 없다. 네임노드는 하둡 파일 시스템에서 단일 장애지점에 해당한다. 일반적으로 세컨데리 네임노드를 백업용 노드로 활용하여, 네임노드에 장애가 발생했을 때를 대비한다. 물론 장애가 발생한다고 해서 세컨데리 네임노드가 자동으로 네임노드의 역할을 수행하는 것은 아니며, 약간의 수고를 들여야한다. 하지만 데이터는 손실되지 않도록 보장할 수 있게 된다.

다수의 디스크를 활용한 장애복구

네임노드에 디스크가 2개 이상인 경우, dfs.name.dir 속성에 해당 디스크를 모두 설정한다. 따라서 첫번째 디스크에 장애가 발생한다면, 네임노드는 두번째로 지정된 디스크를 자동으로 사용하게 된다.

세컨데리 네임노드를 활용한 장애복구

디스크 뿐만 아니라 네임노드가 설치된 머신 자체가 장애가 난 경우를 대비해서 세컨데리 네임노드를 백업 노드로 활용할 수 있다. 마찬가지로 dfs.name.dir 속성에 세컨데리 네임노드의 디스크를 추가한다. 그리고 네임노드에 장애가 발생한 경우, 세컨데리 네임노드의 IP의 네임노드의 IP로 변경한 후 네임노드를 재실행한다. 각 데이터 노드는 IP를 기반으로 네임노드와 통신하므로 반드시 IP를 변경해야만 한다.

네임노드 이중화

현재 네임노드를 Active / Stand-by 형태로 이중화할 수 있는 작업이 진행중인 듯하다.

Job 스케쥴링

기본적으로 하둡은 FIFO 스케쥴러를 사용한다. 즉 모든 Job은 실행된 순서대로 차례차례 실행되게 된다. 따라서 한번에 한개의 Job만을 실행할 수 있다.

하지만 경우에 따라 2개 이상의 Job을 동시에 실행하길 원할 수도 있다. 이를 위해 페이스북에서는 Fair 스케쥴러를, 야후에서는 Capacity 스케쥴러를 구현했다.

페어(Fair) 스케쥴러

페어 스케쥴러에서 중요한 개념은 태스크 풀(task pool)이다. 각 Job은 모두 특정 풀에 속하며, 각 풀은 모두 최소한의 맵과 리듀스 개수를 보장받는다. 또한 Job마다 우선순위를 설정할 수 있으며, 우순 선위가 더 높은 Job은 더 많은 태스크 개수를 할당받는다.

페어 스케쥴러를 사용하려면 설정파일을 아래와 같이 수정해야 한다.


<property>
    <name>mapred.jobtracker.taskScheduler</name>
    <value>org.apache.hadoop.mapred.FairScheduler</value>

</property>
<property>
    <name>mapred.fairscheduler.allocation.file</name>
    <value>HADOOP_CONF_DIR/pools.xml</value>

</property>
<property>
    <name>mapred.fairscheduler.assignmultiple</name>
    <value>true</value>

</property>
<property>
    <name>mapred.fairscheduler.poolnameproperty</name>
    <value>pool.name</value>

</property>
<property>
    <name>pool.name</name>
    <value>${user.name}</value>

</property>

위의 설정 파일을 좀더 자세히 살펴보자. 먼저 사용할 스케쥴러의 클래스명을 수정한다.

<property>
    <name>mapred.jobtracker.taskScheduler</name>
    <value>org.apache.hadoop.mapred.FairScheduler</value>
</property>

태스크 풀에 대한 설정정보를 저장한 파일의 경로를 설정한다.

<property>
    <name>mapred.fairscheduler.allocation.file</name>
    <value>HADOOP_CONF_DIR/pools.xml</value>
</property>

Job이 실행될 때 어느 풀을 사용할지 결정하는 기준을 설정한다. 여기에서는 pool.name, 즉 풀의 이름을 기준으로 선택하도록 설정한다.

<property>
    <name>mapred.fairscheduler.poolnameproperty</name>
    <value>pool.name</value>
</property>

pool.name의 기본값을 ${user.name}으로 설정하면, job을 실행한 사용자 계정을 기준으로 사용할 풀을 선택하게 된다.

아래는 풀에 대한 설정을 담고 있는 pools.xml 파일이다.

<?xml version="1.0">
<allocations>
    <pool name="hadoop">
        <minMaps>2</minMaps>
        <minReduces>2</minReduces>
    </pool>

    <pool name="hive">
        <minMaps>2</minMaps>
        <minReduces>2</minReduces>
        <maxRunningJobs>2</maxRunningJobs>
    </pool>
    <user name="bulk">
        <maxRunningJobs>5</maxRunningJobs>
    </user>
    <userMaJobsDefault>3</userMaxJobsDefault>
</allocations>

pools.xml 파일은 매 15초마다 자동으로 다시 읽히므로, 변경사항은 바로바로 반영되게 된다. 이 파일에 정의되지 않은 pool은 최소한의 태스크 수를 보장받지 못하게 된다.

페어 스케쥴러를 사용한 경우 최대 이점은 웹 모니터링 UI 화면이다. http://masternode:50030/scheduler 로 접속해보면, 페어스케쥴러에서만 사용할 수 있는 기능을 확인할 수 있다.

hadoop_mapreduce_fair_scheduler

웹 UI 상에서 풀에 대한 정보 및, Job의 우선순위를 바꿀수도 있다.

 

크몽 재능