반응형

안녕하세요 오늘은 하둡의 네임노드와 데이터노드에 대해서 정리해 보도록 하겠습니다.


해당 내용은 '하둡 완벽 가이드(4판)'에 대한 정리 내용입니다. 


[ HDFS 클러스터 구성 방식 ]

HDFS 클러스터는 마스터-워커(master-worker) 패턴으로 동작하는 두 종류의 노드(마스터인 하나의 네임노드(namenode)와 워커인 여러 개의 데이터노드(datanode)로 구성되어 있다. HDFS 클라이언트가 사용자를 대신해서 네임노드와 데이터노드 사이에서 통신하고 파일시스템에 접근한다. HDFS 클라이언트는 POXIS(Portable Operation System Interface)와 유사한 파일시스템 인터페이스를 제공하기 때문에 사용자는 네임노드와 데이터노드에 관련된 함수를 몰라도 코드를 작성할 수 있다.


[ 네임노드(NameNode) ]

네임노드(namenode)는 파일시스템의 네임스페이스를 관리한다. 네임노드는 파일시스템 트리와 그 트리에 포함된 모든 파일과 디렉터리에 대한 메타데이터를 유지한다. 이 정보는 네임스페이스 이미지(namespace image)와 에디트 로그(edit log)라는 두 종류의 파일로 로컬 디스크에 영속적으로 저장된다. 네임노드는 또한 파일에 속한 모든 블록이 어느 데이터노드에 있는지 파악하고 있다. 하지만 블록의 위치 정보는 시스템이 시작할 때 모든 데이터노드로부터 받아서 재구성하기 때문에 디스크에 영속적으로 저장하지는 않는다. 


[ 데이터노드(DataNode) ]

데이터노드는 파일시스템의 실질적인 일꾼이다. 데이터노드는 클라이언트나 네임노드의 요청이 있을 때 블록을 저장하고 탐색하며, 저장하고 있는 블록의 목록을 주기적으로 네임노드에 보고한다. 


[ 네임노드의 중요성 ]

네임노드가 없으면 파일시스템은 동작하지 않는다. 네임노드를 실행하는 머신이 손상되면 파일시스템의 어떤 파일도 찾을 수 없다. 데이터노드에 블록이 저장되어 있지만 이러한 블록 정보를 이용하여 파일을 재구성할 수는 없기 때문이다. 따라서 네임노드의 장애복구 기능은 필수적이다.


[ 네임노드 장애복구를 위한 하둡 메커니즘 ]

1. 네임노드 로컬 디스크와 원격의 NFS 마운트 두 곳에 동시에 백업하는 것이다.

파일시스템의 메타데이터를 지속적인 상태로 보존하기 위해 파일로 백업해야한다. 

2. 보조 네임노드(Secondary namenode)를 운영

보조 네임노드의 주 역할은 에디트 로그가 너무 커지지 않도록 주기적으로 네임스페이스 이미지를 에디트 로그와 병합하여 새로운 네임스페이스 이미지를 만드는 것이다. 병합 작업을 수행하기 위해 보조 네임노드는 충분한 CPU와 네임노드와 비슷한 용량의 메모리가 필요하므로 별도의 물리 머신에서 실행되는 것이 좋다. 또한 보조 네임노드는 주 네임노드에 장애가 발생할 것을 대비해서 네임스페이스 이미지의 복제본을 보관하는 역할도 맡는다. 하지만 주 네임노드의 네임스페이스 이미지는 약간의 시간차를 두고 보조 네임노드로 복제되기 때문에 주 네임노드에 장애가 발생하면 어느 정도의 데이터 손실은 불가피하다. 이럴 때 일반적인 복구 방식은 NFS에 저장된 주 네임노드의 메타데이터 파일을 보조 네임노드로 복사하여 새로 병합된 네임스페이스 이미지를 만들고 그것을 새로운 주 네임노드에 복사한 다음 실행하는 것이다.


결과적으로 안전한 하둡운영을 위해서는 네임노드의 메타데이터를 원격 NFS도 저장하고 보조 네임노드도 운영하는 것이라고 볼 수 있을 것 같다.

반응형
반응형


오늘은 HDFS에서 블록의 개념과 내용에 대해 포스팅 해보도록 하겠습니다.


기본적으로 HDFS 블록의 사이즈가 64,128,256MB (하둡 배포판에 따라 상이)인건 알고 계실텐데요? 왜 그렇고 어떻게 블록이 처리되는지에 대해 정리해보겠습니다. 해당 내용은 '하둡 완벽 가이드'의 내용을 학습하고 반복 학습겸 정리한 내용입니다.


블록

일반적으로 물리적인 디스크는 블록 크기란 개념이 있습니다. 블록 크기는 한 번에 읽고 쓸 수 있느 데이터의 최대량입니다.

보통 파일시스템의 블록의 크기는 수 킬로바이트고, 디스크 블록의 크기는 기본적으로 512byte입니다.


반면 HDFS도 블록의 개념을 가지고 있지만 HDFS의 블록은 기본적으로 128MB와 같이 굉장히 큰 단위입니다. HDFS의 파일은 단일 디스크를 위한 파일시스템처럼 특정 블록 크기의 청크로 쪼개지고 각 청크(chunk)는 독립적으로 저장됩니다. 단일 디스크를 위한 파일시스템은 디스크 블록 크기보다 작은 데이터라도 한 블록 전체를 점유하지만, HDFS 파일은 블록 크기보다 작은 데이터일 경우 전체 블록 크기에 해당하는 하위 디스크를 모두 점유하지는 않습니다.


예를 들어 HDFS의 블록 크기가 128MB고 1MB 크기의 파일을 저장한다면 128MB의 디스크를 사용하는 것이 아니라 1MB의 디스크만 사용합니다. 


블록은 내고장성(fault tolerance)과 가용성(availability)을 제공하는 데 필요한 복제(replication)를 구현할 때 매우 적합합니다.. 블록의 손상과 디스크 및 머신의 장애에 대처하기 위해 각 블록은 물리적으로 분리된 다수의 머신(보통 3개)에 복제되며 만일 하나의 블록을 이용할 수 없는 상황이 되면 다른 머신에 있는 복사본을 읽도록 클라이언트에 알려주면 됩니다. 블록이 손상되거나 머신의 장애로 특정 블록을 더 이상 이용할 수 없으면 또 다른 복사본을 살아 있는 머신에 복제하여 복제 계수(replication factor)를 정상 수중으로 돌아오게 할 수 있습니다.


일반적인 디스크 파일시스템과 같이 HDFS의 fsck 명령어로 블록을 관리할 수 있습니다.

> hdfs fsck / -files -blocks

파일시스템에 있는 각 파일을 구성하는 블록의 목록이 다음과 같이 출력됩니다.

기본 /(루트) 부터 순차적으로 디렉토리 들을 돌며 블록 상황을 보여줍니다.


HDFS 블록이 큰 이유는?

HDFS 블록은 디스크 블록에 비해 상당히 크다. 그 이유는 탐색 비용을 최소화하기 위해서다. 블록이 매우 크면 블록의 시작점을 탐색하는 데 걸리는 시간을 줄일 수 있고 데이터를 전송하는 데 많은 시간을 할애할 수 있다.(블록이 작고 너무 많으면 시작점을 탐색하는 비용 증가) 따라서 여러 개의 블록으로 구성된 대용량 파일을 전송하는 시간은 디스크 전송 속도에 크게 영향을 받는다. 

탐색 시간이 10ms고 전송률이 100MB/s 라고 하면, 탐색 시간을 전송 시간의 1%로 만들기 위해서는 블록 크기를 100MB로 정하면 된다. 하둡 배포판에 따라 다르지만 블록 크기의 기본값은 128MB다. 기본 블록 크기는 디스크 드라이브의 전송 속도가 향상될 때마다 계속 증가할 것이다.


이상으로 포스팅을 마치도록 하겠습니다:)



반응형
반응형


HDFS 설계 특성에 대해 정리해보도록 하겠습니다.


해당 포스팅은 '하둡 완벽 가이드' 내용을 정리한 것입니다. 공부하고 밑줄 쳐놓고 아까워 한 번 더 복습겸 포스팅해 봅니다.



HDFS 설계 특성

1. 매우 큰 파일  

'매우 큰'의 의미는 수백 메가바이트, 기가바이트 또는 테라바이트 크기의 파일을 의미한다. 최근에는 페타바이트 크기의 데이터를 저장하는 하둡 클러스터도 있다.'

기본적으로 하둡은 대용량 데이터를 처리하기 위해 설계되었다.


2. 스트리밍 방식의 데이터 접근

HDFS는 '가장 효율적인 데이터 처리 패턴은 한 번 쓰고 여러 번 읽는 것' 이라는 아이디어에서 출발했다. 데이터셋은 생성되거나 원본으로부터 복사된다. 그리고 시간이 흐르면서 다양한 분석을 수행할 수 있다. 분석이 전부는 아니지만 첫 번째 레코드를 읽는 데 걸리는 지연 시간보다 전체 데이터셋을 모두 읽을 때 걸리는 시간이 더 중요하다.


3. 범용 하드웨어

하둡은 고가의 신뢰도 높은 하드웨어만을 고집하지는 않는다. 하둡은 노드 장애가 발생할 확률이 높은 범용 하드웨어(여러 업체에서 제공하는 쉽게 구할 수 있는 하드웨어)로 구성된 대형 클러스터에서 문제없이 실행되도록 설계되었다. HDFS는 이러한 장애가 발생하더라도 사용자가 장애가 발생했다는 사실조차 모르게 작업을 수행하도록 설계되었다.


HDFS가 잘 맞지 않는 응용 분야

1. 빠른 데이터 응답 시간

데이터 접근에 수십 밀리초 수준의 빠른 응답 시간을 요구하는 애플리케이션은 HDFS와 맞지 않다. HDFS는 높은 데이터 처리량을 제공하기 위해 최적화되어 있고 이를 위해 응답 시간을 희생했다. 빠른 응답 시간을 원한다면 현재로서는 HBase가 하나의 대안이 될 수 있다.


2. 수많은 작은 파일

네임노드는 파일시스템의 메타데이터를 메모리에서 관리하기 때문에 저장할 수 있는 파일 수는 네임노드의 메모리 용량에 좌우된다. 경험상으로 파일, 디렉터리, 블록은 각각 150바이트 정도의 메모리가 필요하다. 따라서 파일 수가 백만 개고 각 파일의 블록이 하나면 적어도 300MB의 메모리가 필요하다. 물론 수백만 개의 파일은 괜찮겠지만 수십억 개의 파일은 하드웨어 용량을 넘어서게 된다.


3. 다중 라이터와 파일의 임의 수정

HDFS는 단일 라이터로 파일을 쓴다. 한 번 쓰고 끝나거나 파일의 끝에 덧붙이는 것은 가능하지만 파일에서 임의 위치에 있는 내용을 수정하는 것은 허용하지 않으며 다중 라이터도 지원하지 않는다. (하둡 3.0부터는 다중 라이터를 지원한다.


이상으로 포스팅을 마치도록 하겠습니다 :)

반응형
반응형


현상황  : Cloudera(클라우데라) 버전(CDH 5.5.1, Parcel), Spark버전(1.5) - jdk version 1.7

필요상황 : 기존 작업을 Spark1.5(jdk1.7) - jdk 1.8로 돌리기

준비상황 :  클러스터의 각 노드들에 jdk1.8이 설치되어 있어야 함.


spark-submit스크립트에 jdk1.8 path를 명시

--conf "spark.yarn.appMasterEnv.JAVA_HOME=/home1/irteam/jdk/jdk1.8.0_141" \
--conf "spark.driverEnv.JAVA_HOME=/home1/irteam/jdk/jdk1.8.0_141" \
--conf "spark.executorEnv.JAVA_HOME=/home1/irteam/jdk/jdk1.8.0_141" \

이렇게 driver와 executor의 JAVA_HOME은 명시가 되었고

해당 스크립트가 돌아가는 client의 JAVA_HOME은 export로 변경해준다.


기존 단순 spark-submit명령어에서 앞에 다음과 같이 추가

export JAVA_HOME=/home1/irteam/jdk/jdk1.8.0_141 && spark-submit \


이렇게 설정을 해주게 되면 jdk1.8로 빌드된 코드도 기존 spark로 돌릴 수 있게 된다.


이런식의 설정으로 클라우데라 스파크 버전 또한 2점대로 높여 사용할 수 있겠다.


반응형
반응형


Spark dataframe(스파크 데이터프레임)으로 작업 중 dataframe의 null값을 특정값으로 바꾸고 싶은 경우가 있다.


이 때 주의해야할 점은 dataframe의 컬럼의 자료형 타입에 맞게끔 변환해줘야 정상적으로 replace된다.



다음과 같은 데이터프레임(dataframe)이 있을 때 "bid_i"의 값을 0으로 변경하려고 다음을 실행


val result_df_q_new = result_df_q.na.fill(0, Seq("bid_i"))


위와 같은 명령을 수행하고 확인을 해도 정상적으로 null값이 0으로 변경되지 않은 걸 확인할 수 있었다.


원인은 bid_i의 자료형 타입에 맞지않게 변경하려했기 때문이다.



위에서 보듯이 "bid_i"의 자료형 타입은 string인데 0으로 변경(na.fill메서드를 하려고 하니 정상적으로 변환되지 않았던 것이다. 

(처리 도중 딱히 에러메세지가 없었다...)


val result_df_q_new = result_df_q.na.fill("0", Seq("bid_i"))


0을 string형(큰따옴표)를 씌워서 명령어를 주니 정상적으로 변경되는 것을 확인할 수 있었다.


데이터프레임(dataframe) 값을 na.fill을 통해 변경할 때는 자료형타입을 잘 확인하도록 하자!


반응형
반응형


하둡 디렉토리hadoop directory) 존재 여부나 파일이 있는지 확인을 해야 하는 경우가 있다.


이 때 사용할 수 있는 명령어가 -test 라는 명령어이다.


help명령어를 통해 사용할 수 있는 옵션을 살펴보면


> hadoop fs -help test 



다음과 같은 옵션을 확인할 수 있다.


보통 해당 하둡 디렉토리 확인 여부(-d), 하둡 path 존재여부(-e), path에 파일 존재하는 여부 확인(-f) 옵션을 자주 사용한다.


보통 다음과 같이 쉘스크립트(shell script)에서 사용할 수 있다.


> -e옵션과 -z옵션을 통한 하둡파일체크



해당 path가 하둡에 있는지 확인(-e)하고 -z 옵션을 이용해 해당 path의 파일의 사이즈가 0byte가 아닌지 확인한다.


위와 같이 하둡디렉토리에 정상적인 파일이 있는 경우 작업시행시 조건으로 사용할 수 있다.


-test(하둡 명령어)를 유용하게 활용해보시길~





반응형
반응형

[ 하둡 MR보다 스파크(SPARK)를 사용할 때 장점 ]

하둡MR보다 스파크(SPARK)를 사용했을 때의 대부분이 말하는 이점은 디스크 처리 기반에서 메모리 처리 기반으로 넘어오면서 연산처리 속도가 빨라졌다는 것이다.

뭐 틀린말은 아니지만 데이터 엔지니어 입장에서 뭔가 더 구체적으로 설명할 수 있어야 하지 않을까 하는 생각에 간단히 정리해 포스팅해본다.

1. 스파크(SPARK)의 연산 방식은 lazy evaluation으로 수행된다. 

Lazy evaluation(굳이 번역해 보자면 느긋한 연산 정도 되겠다)을 사용함으로써 action이 시작되는 시점에 트랜스포메이션(transformation)끼리의 연계를 파악해 실행 계획의 최적가 가능해진다. 사용자가 입력한 변환 연산들을 즉시 수행하지 않고 모아뒀다가 가장 최적의 수행 방법을 찾아 처리하는 장점을 가진다.
여기서 말하는 최적화란 대부분 지역성(locality)에 관한 것이다. 예를 들어 물건을 사오는 심부름을 시킬 때 A상점에서 파는 물건과 B상점에서 파는 물건을 따로따로 여러 번사오게 하는 것보다 필요한 물건을 한꺼번에 주문해서 한 번 방문했을 때 필요한 물건을 한 번에 사는 것이 효율적이기 떄문이다.

사실 fist() 액션에서도 스파크는 처음 일치하는 라인이 나올 때까지만 파일을 읽을 뿐 전체 파일을 읽거나 하지 않는다.

실제로 하둡 맵리듀스 같은 시스템에서는 맵리듀스의 데이터 전달 회수를 줄이기 위해 어떤 식으로 연산을 그룹화 할지 고민하느라 개발자들이 시간을 많이 빼앗기게 된다. 맵리듀스에서 연산 개수가 많다는 것은 곧 네트워크로 데이터를 전송하는 단계가 많아짐을 의미하고 그만큼 클러스터에 부하를 가져다 줄 수 있다. 스파크(SPARK)에서는 단순한 연산 들을 많이 연결해서 사용하는 것이나 하나의 복잡한 매핑 코드를 쓰는 것이나 큰 차이가 없는데 기본적으로 스파크에서 효율적인 계획을 세워서 수행하기 때문이다. 그렇다고 해서 rdd재사용 등을 고려하지 않고 아무렇게나 프로그래밍을 해도 된다는 의미는 아니다. 따라서 스파크 사용자들은 프로그램을 더 작게 만들고, 효율적인 연산의 코드를 만들어 내야 한다는 부담에서 좀 더 자유로울 수 있다.


2. RDD 재사용을 위한 캐싱 기능
기본적으로 메모리위에 캐싱을 하여 처리를 하게 되면 디스크 처리 기반의 MR작업보다 최소 10~20배 이상 빠를 수 밖에 없다. 여러 액션에서RDD 하나를 재사용하고 싶으면 RDD.persist()를 사용하여 계속 결과를 유지하도록 할 수 있다. 첫 연산이 이루어진 후 스파크는 RDD의 내용을 메모리에 저장하게 되며(클러스터의 여러 머신들에 나뉘어서) 이후의 액션들에서 재사용할 수 있게 된다.


3. RDD는 유연한 연산 방식을 제공한다.
분산 데이터로서의 RDD(Resilient Distributed Datasets)는 문자 그대로 해석하면 "회복력을 가진 분산 데이터 집합"으로  데이터를 처리하는 과정에서 집합을 이루고 있던 데이터의 일부에 문제가 생겨도 스스로 알아서 복구할 수 있다는 의미이다.  실제로 이것은 스파크(SPARK)가 RDD를 만들어 내는 방법을 기억하고 있기 때문에 가능한 것으로 스파크는 데이터의 일부가 유실되면 어딘가에 백업해둔 데이터를 다시 불러오는 것이 아니고 데이터를 다시 만들어내는 방식으로 복구를 수행하게 됩니다.


4. 코드 간결성 및 Interactive shell
하둡 MR을 해보신 분은 알겠지만 단어들을 aggregate하는 하둡 MR소스코드는 맵과 리듀스를 만들어주어야 하기 때문에 길고 복잡할 수 밖에 없는 반면에 스파크는 람다기반의 함수형 프로그래밍 기법으로코드가 매우 간단하며, interactive shell을 사용하여 실제 쉘에서 실시간으로 데이터 변화를 확인할 수 있다는 장점을 가지고 있습니다.


실제로 하둡 MR 대안으로 SQL을 MapReduce로 변환해주는 Hive 프로젝트가 있어 많은 사람이 잘 사용하고 있지만, 쿼리를 최적화하기가 어렵고 속도가 더 느려지는 경우가 많다는 어려움이 있다. 스파크는 이러한 단점들을 보안하며 위와 같은 장점들로 인해 분산 처리 툴로서 많은 관심과 사랑?을 받고 있다고 볼 수 있습니다.


반응형
반응형


hadoop(하둡)을 운영하다 보면 특정한 경우 hdfs에 나누어 저장되어 있는 파일들을 합쳐서 로컬로 받고 싶은 경우가 있다.

이 때 -getmerge명령어를 쓰면되는데 -text명령어로도 동일한 기능을 수행할 수 있다.

다만 주의해야할 차이점은 -text명령의 경우는 hdfs에 파일이 gz으로 묶여 쌓여있는 경우 압축을 풀어 라인을 읽어 로컬에 쓸 수 있는 반면에

-getmerge의 경우는 그렇지 않다. 따라서 합치고자 하는 파일이 .gz형태라면 -text를 사용해서 합쳐 로컬로 받는 방법이 훨씬 더 간편하다.


[ hdfs 예시 파일 ] 

!주의 .gz의 경우에는 -getmerge가 정상적으로 먹히지 않는다. (.gz일 때는 -text사용)

-rw-r--r--   3 irteam irteam      36997 2017-09-22 16:50 /log/temp/manual/part-00000

-rw-r--r--   3 irteam irteam    8828447 2017-09-22 16:59 /log/temp/manual/part-00001

-rw-r--r--   3 irteam irteam      38420 2017-09-22 16:49 /log/temp/manual/part-00002


[ -getmerge 사용법 ] 

hadoop fs -getmerge [hdfs경로] [로컬디렉토리]

 hadoop fs -getmerge  /log/temp/manual  /local/directory


[ -text 사용법 ] 

hadoop fs -text [hdfs경로] > [로컬디렉토리] 

hadoop fs -text /log/temp/manual/part-* > /local/direcotory


명령어 실행 후 로컬디렉토리에 저장된 파일의 개수를 세어보면 두 명령어로 실행한 데이터 개수가 동일한 것을 확인할 수 있다.

텍스트파일로 hdfs에 저장된 총 1241517라인(50M)로 테스트 해봤을 떄 로컬로 쓰는데 까지 두 명령어 모두 약 5초정도 걸렸다.

따라서 편한방법으로 사용하시길:)


반응형
반응형

하둡1.0과 하둡2.0의 차이는 YARN으로 인해 많은 부분이 변화되었다.

그 차이에 대해서 알아보도록 하자.

[ 아키텍처의 변화 ]


[ 하둡 1.0과 2.0에서 리소스 관리 차이 ]

하둡 1.0에서 맵리듀스를 실행할 때는 슬롯 단위로 맵/리듀스 태스크 갯수를 관리했다.따라서 맵퍼는 모두 동작하는데 리듀서는 놀고 있거나 반대의 경우로 인해 클러스터 전체 사용률이 낮았다.

하지만 하둡 2.0에서 YARN(얀)이 도입되면서 슬롯이 아닌 컨테이너 단위로 리소스를 할당하게 되었다. 얀의 리소스 매니저는 전체 클러스터의 리소스 정보를 토대로 할당 가능한 컨테이너 개수를 계산하며, 맵리듀스는 필요한 컨테이너들을 할당 받아서 맵리듀스 태스크를 실행하게 된다. 

이 때 컨테이너 개수와 맵과 리듀스 태스크의 관계는 1:1의 관계가 아니며, 맵과 리듀스 태스크는 상황에 따라서 하나 이상의 컨테이너를 실행할 수도 있다. 그래서 관리자는 전체 클러스터의 리소스 상황과 얀에서 실행하는 잡들의 워크로드를 고려하여 리소스 설정을 진행해야 한다.


[ YARN의 도입으로 JobTracker의 역할이 Resource Manager와 Application Master로 분리 ] 

하둡 1.0에서는 JobTracker(잡트래커)가 클러스터 리소스 관리 및 어플리케이션 스케쥴링 등을 모두 담당했었다.

하지만 하둡 2.0에서는 클러스터마다 Application Master(어플리케이션 마스터)가 존재하고 각 서버마다 Node Manager(노드 매니저)가 할당되어 있고 리소스관리는 Resource Manager(리소스 매니저)가 어플리케이션 수행 및 스케쥴링 관리는 Application Master(어플리케이션 마스터)로 역할이 분리되어 운영된다.


[ Spark 등 분산처리 환경 지원 ]

하둡의 맵/리듀스 작업보다 성능이 훨씬 개선된 SPARK 및 분산처리 프레임워크를 사용할 수 있게 되었다. 스파크는 배치 처리 작업에 있어서 맵리듀스보다 10배정도 빠르며 인메모리 분석에서 100배나 빠르다고 알려져 있다.




반응형

+ Recent posts