Hadoop 클러스터 구성 &


아직 작성 중인 문서임을 밝힙니다. 언제든지 수정될 수 있으며 삽질중입니다 잘못된 곳이 있다면 알려주세요 ㅠㅠ.

현재 벤치마킹 부분을 진행중인. 아래와 같은 에러가 발생중입니다 ㅠㅠ..



저번 포스팅에서는 클라우데라의 CDH3 를 이용하여 설치를 진행했었다.
이번엔 직접 아파치 사이트에서 Hadoop 을 내려받아서 설치해보도록 한다. 

이 문서에서는 hadoop Core (HDFS, MapReduce) Cluster 설치만 진행하고, 추후 이 환경을 바탕으로 hadoop 서브 프로젝트들을 구축하는 것을 목표로 하고 있습니다.
 



준비 사항



java 1.6.14 이상 
- download : http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u32-downloads-1594644.html
- manual : http://www.oracle.com/technetwork/java/javase/install-linux-64-self-extracting-142068.html
hadoop 1.0.3 
- download : http://hadoop.apache.org/common/releases.html#Download 
 
총  3대의 가상 머신
- CentOS 6.2 


  hostName     IP               역할
- master : 192.168.116.131 (JobTracker, NameNode)
- slave1 : 192.168.116.132 (TaskTracker, DataNode)
- slave2 : 192.168.116.133 (TaskTracker, DataNode)  


OS 환경 설정 



환경 변수 설정

# su - hadoop
vi .bash_profile
 // JAVA_HOME 과 HADOOP_HOME 을 설정한다.
export JAVA_HOME=/usr/lib/jdk1.6.0_32
export HADOOP_HOME=/var/hadoop-1.0.3



// PATH 에 각 bin 디렉토리를 추가한다.
PATH=$PATH:$HOME/bin:$JAVA_HOME/bin:$ HADOOP_HOME/bin

<모든 노드 동일>


hosts 파일설정.

// 모든 노드 동일 (127.0.0.1 은 Hadoop 에서 socket binding 될 때 장애 발생하는 경우가 있음.)
cat /etc/hosts
192.168.116.131         master
192.168.116.132         slave1
192.168.116.133         slave2




ssh 설정(모든 노드 진행)

rsa 알고리즘으로 공개키 기반 SSH 인증을 한다.

공개키 생성 (모든 Node)

ssh-keygen -t rsa -f ~/.ssh/id_rsa


Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): pw
Enter same passphrase again: pw
Your identification has been saved in /home/hadoop/.ssh/id_rsa.
Your public key has been saved in /home/hadoop/.ssh/id_rsa.pub.
The key fingerprint is:
a6:6b:bf:8f:33:fe:0c:fe:03:5c:72:ca:6b:32:0f:a0 hadoop@localhost.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|                 |
|                 |
|        . o      |
|    .  oS=       |
|   . . o=        |
|  E   o .o       |
|      ++=+.      |
|     ..BBB=.     |
+-----------------+

$ ls /home/hadoop/.ssh
id_rsa   // 개인키
id_rsa.pub // 공개키 
 
< 모든 node에서 실행 >

공개키 분배 ( Master Node에서 실행 )


 
// master 공개키를 authorized_keys 파일에 추가
 
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
 
// slave1 공개키를 master의 authorized_keys 파일에 추가 
 $ ssh hadoop@slave1 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys 
// slave2 공개키를 master의 authorized_keys 파일에 추가  
$ ssh hadoop@slave2 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
 

// 공개키 확인. master, slave1, slave2 공개키가 모두 있다.

cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAk1Jd/gVVBCDk+s0Ewp7Ly1xAYGm2ot9lkrfvlTbR0bRhtO69k0SSbOMREtC0+KZcaGOskFBxcoehTmAbhjaohpoS8WyTJ1zeyleCv+72usL4zzZLDrd4jO4p4rXLHbzmGSZAfi+eJirNdI4M1Gv+lulwythu4Liotx0zGUXJ6I4oPqtDPScXLHujvoq/fBWQaJr6fCliIfieEc0Xgx4faQEbqe0pDmsreQpRjY4cCDwf8gHVji3QdiJrvWqh/USEmvnWW+leyaP3fP+lKXZQF1QLbYXU/HZEb73K3BTA2/e06HUGTrWJ/ouhDNpubUHWPwjF7qVY+KUPH4Ypy+J1mw== hadoop@localhost.localdomain
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAndeaaNCwkKG4p6v9vwEFRUgSsHD+rQ84Shr/2xpqkVXQb4GT1kZPoZiPmGqh/sFjzLrAU6NnW7yCv4c5+7x2Dw0W0GdiJRQBffx6ItkdOUho452/cFkj1VY2GrDJAM2/lq9tcUua8IIPyJJ6lktlbYmzh74CZqJu487BsAGkMA7PiYUOgumABWjSB1JkhXBXRP2exwWGjmOfXgxrBd3lXE9j+QJ/Hn92QbI89toXNVpwSvuWCZNGwmq5+60VD9V5qTXx0iHj+fjrwepNIOZb5S0beBegCHpFZfy2TeZ/XwyTn+AuRuvNmsTXgcjKiFLfdR0AvCvP4zh+uEqZLELacw== hadoop@localhost.localdomain
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAum8qrfdRX+sZ4VRqpmFb6Xo/H7v9Ws8RMMo++bAh506LmoFyWkfcN/CejXN2J728Z8X/bq2ZIOKpTo9WDIR51lsgRz00Lv67gMxUNjLM6es+fTR+SxgvitNkipRBnuWBlbdYN8CKIMo45Fao1lecPEO2ZTlO5JllJWWwBksMb3XwCoqU7qmFXBT93T78ykAD9fnBWLm3OMvt9vuEjXnZmnBIfZMJjglY8yjKjcY8jGCuy13CTtfHkw6a28/ENSGsD9Vqqnh4Px1krVHngzYCpjSrdwhtDG163xD62yClNWf0sLlGBOxBDvznXYHbyNhPk7HivKoQ0llgD3kovcRyxw== hadoop@localhost.localdomain


// 모든 node에 공개키 재분배. 모든 노드에서 서로의 공개키를 공유한다.
scp authorized_keys hadoop@slave1:~/.ssh/authorized_keys
scp authorized_keys hadoop@slave2:~/.ssh/authorized_keys 

< master node에서만 >


테스트 진행 (모든 Node)
위에서 모든 노드에 공개키를 복사했다면 아래와 같은 방법으로 테스트를 진행한다.
만일 정확하게 진행했는데도 패스워드를 물어본다면   이곳을 참조한다. 


// 테스트 master
 ssh hadoop@slave1 date
Fri May 25 00:56:03 KST 2012 // 이렇게 뜨면 정상. 패스워드를 묻는 경우 
ssh hadoop@slave2 date
Fri May 25 00:59:06 KST 2012 
 // 테스트 slave1 
ssh hadoop@master date
Fri May 25 01:01:39 KST 2012
ssh hadoop@slave2 date
Fri May 25 01:01:21 KST 2012
// 테스트 slave2 
 $ ssh hadoop@master date
Fri May 25 01:01:49 KST 2012
ssh hadoop@slave1 date
Fri May 25 01:01:53 KST 2012


 

Hadoop 설치 단계



복사 & 압축 해제
 메뉴얼에는 /usr/local 또는 /opt 에 위치하는 것을 권장하고 사용자의 Home 디렉토리에는 권장하지 않는다.
(전 공간 할당 잘못으로 부득이 하게 '/var/hadoop-1.0.3' 에 설치를 진행합니다.ㅠㅠ)


복사는 winscp 등을 이용하면 된다.

$ sudo tar xzf  hadoop-1.0.3.tar.gz
$ sudo chown -R hadoop:hadoop  hadoop-1.0.3




Hadoop 환경 설정

Hadoop 은 설정정보를 클러스터 내의 각 하둡 노드는 고유의 설정 파일들이 있으며 이 파일들을 시스템 전역에 걸쳐 동기화 시킬수 있다.(dsh, pdsh) 
 또한 기본적인 기능은 아니지만 모든 노드가 같은 설정을 가질수 없는 경우 Class 를 만들어 클래스별로 다른 설정을 동기화 할 수 있다. (pupptet, cfengine, bcfg2)
 

설정 파일 목록

$ ll 


total 76

-rw-rw-r--. 1 hadoop hadoop 7457 May  9 05:34 capacity-scheduler.xml

-rw-rw-r--. 1 hadoop hadoop  535 May  9 05:34 configuration.xsl

-rw-rw-r--. 1 hadoop hadoop  178 May  9 05:34 core-site.xml

-rw-rw-r--. 1 hadoop hadoop  327 May  9 05:34 fair-scheduler.xml

-rw-rw-r--. 1 hadoop hadoop 2275 May 25 02:23 hadoop-env.sh

-rw-rw-r--. 1 hadoop hadoop 1488 May  9 05:34 hadoop-metrics2.properties

-rw-rw-r--. 1 hadoop hadoop 4644 May  9 05:34 hadoop-policy.xml

-rw-rw-r--. 1 hadoop hadoop  178 May  9 05:34 hdfs-site.xml

-rw-rw-r--. 1 hadoop hadoop 4441 May  9 05:34 log4j.properties

-rw-rw-r--. 1 hadoop hadoop 2033 May  9 05:34 mapred-queue-acls.xml

-rw-rw-r--. 1 hadoop hadoop  178 May  9 05:34 mapred-site.xml

-rw-rw-r--. 1 hadoop hadoop   10 May  9 05:34 masters

-rw-rw-r--. 1 hadoop hadoop   14 May 25 02:14 slaves

-rw-rw-r--. 1 hadoop hadoop 1243 May  9 05:34 ssl-client.xml.example

-rw-rw-r--. 1 hadoop hadoop 1195 May  9 05:34 ssl-server.xml.example

-rw-rw-r--. 1 hadoop hadoop  382 May  9 05:34 taskcontroller.cfg



hadoop-env.sh : hadoop을 운용하기 위한 환경변수
hadoop-site.xml : master node의 호스트정보와 분산디렉토리 파일시스템 정보
slaves : data node 호스트이름 
master : 보조 네임노드 목록
mapred-site.xml : 잡트래커와 태스크트래커와 맵리듀스 데몬을 위한 환경설정

각 설정 파일에 자세한 설명과 기본값은 여기서 참조 가능하다.

conf/hadoop-env.sh 

하둡에서 실행하는 프로세스들에 적용되는 파라미터(환경변수)를 설정한다. 

메뉴얼에는 .bash_profile 에 설정을 하면  hadoop-env.sh 에서는 설정을 안해도 된다고 하지만 start-dfs.sh 를 할 때 해당 노드에 JAVA_HOME 환경변수가 없다고 나온다. 설정해 주자.

vi hadooop-env.sh


// 없으면 구동시 set 이 안되어 있다고 나온다.

export JAVA_HOME=/usr/lib/jdk1.6.0_32

// 각 데몬에 할당할 메모리 크기, Jobtraker, Namenode, DataNode, TaskTraker 에 각각 할당된다. )
# export HADOOP_HEAPSIZE=2000
export HADOOP_HEAPSIZE=500



conf/slaves
WorkNode 로 사용될 호스트 명, ip 주소를 넣어도 된다.(테스트는 해보지 않았음) 

$ vi /var/hadoop-1.0.3/conf/slaves

slave1

slave2



conf/masters
보조 네임노드를 설정한다. * 주 네임노드를 설정하는 것이 아니다.
이번 구성에서는 제외하였다.

vi /var/hadoop-1.0.3/conf/masters

hostName




conf/core-site.xml
로그 파일, 네트워크 튜닝, I/O 튜닝 , 파일 시스템 튜닝, 압축 등의 하부 시스템을 설정한다.

<configuration>
 <property>
        <name>fs.default.name</name>
        <value>hdfs://master:9000</value>
 </property>
</configuration>


- fs.default.name : 하둡의 기본 파일 시스템에 대한 설정 기본값은 로컬 파일 시스템이다. 위와 같이 설정하면 HDFS 를 사용하게 되고 데이터 노드도 이 설정 값을 통해 네임 노드에 접근한다. 


conf/hdfs-site.xml
HDFS 의 설정 파일

/home/hadoop/work/name 디렉토리 생성 (master)   
/home/hadoop/work/data 디렉토리 생성 (slave1, slave2)  

<configuration>

    <property>

        <name>dfs.replication</name>

        <value>3</value>

    </property>

    <property>

        <name>dfs.name.dir</name>

        <value>/home/hadoop/work/name</value>

    </property>

    <property>

        <name>dfs.data.dir</name>

        <value>/home/hadoop/work/data</value>

    </property>

    <property>

        <name>dfs.support.append</name>

        <value>true</value>

    </property>  

</configuration>

 
- dfs.name.dir : 네임노드에서 사용한다. 파일의 디렉토리 정보와 파일 정보등을 저장한다.
- dfs.data.dir : 데이터노드에서 데이터 파일이 저장. ',' 을 이용해 여러개 지정가능하다.
- 가끔 dfs.datanode.max.xcievers 이 파라미터를 설정한 문서를 가끔 찾아 볼 수 있다. 실제로는 데이터 노드의 동시 접속 수를 조절하는 파라미터로 기본값은 256 이다. 하지만 0.23 문서에서 'dfs.datanode.max.transfer.threads' 으로 바뀌었고 기본값이 '4096' 으로 수정되었지만 현재 1.0.3 버전 문서에서는 관련된 파라미터 정보를 찾을 수가 없어서 생략했다.


mapred-site.xml
map reduce 관련 설정

<configuration>
    <property>
        <name>mapred.map.child.java.opts</name>
        <value>-Xmx200m </value>
    </property>
    <property>
        <name>mapred.reduce.child.java.opts</name>
        <value>-Xmx200m </value>
    </property>
    <property>
        <name>mapred.job.tracker</name>
        <value>master:9001</value>
    </property>
    <property>
        <name>mapred.system.dir</name>
        <value>/home/hadoop/work/mapred/system</value>
    </property>
</configuration>



conf/mapred-site.xml
맵 리듀스 작업시 각 worknode 로 분배 역할을 하는 서버 위치 설정,

/home/hadoop/work/mapred/system 디렉토리 생성

<configuration>

    <property>

        <name>mapred.job.tracker</name>

        <value>master:9001</value>

    </property>

    <property>

        <name>mapred.system.dir</name>

        <value>/home/hadoop/work/mapred/system</value>

    </property>

</configuration>


- mapred.local.dir : 맵리듀스 잡 과정에서 발생하는 중간 데이터를 저장하는 디렉터리의 임시 저장소를 지정한다. 잡이 끝나면 삭제된다.  기본위치는 ${hadoop.tmp.dir) 이다.

설정파일 모든 노드 동기화

$ cd /var/hadoop-1.0.3/conf/ 
$ sudo rsync -av . hadoop@slave1:/var/hadoop-1.0.3/conf/
$ sudo rsync -av . hadoop@slave2:/var/hadoop-1.0.3/conf/


클러스터 시작


name node format

만약 name node를 format 하지 않고 시동하면 아래와 같은 에러 발생한다.

java.io.IOException: NameNode is not formatted.



참조 :  http://blog.naver.com/PostView.nhn?blogId=serverbin&logNo=30108860842 



hadoop namenode -format


12/05/25 07:04:03 INFO namenode.NameNode: STARTUP_MSG:

/************************************************************

STARTUP_MSG: Starting NameNode

STARTUP_MSG:   host = localhost.localdomain/127.0.0.1

STARTUP_MSG:   args = [-format]

STARTUP_MSG:   version = 1.0.3

STARTUP_MSG:   build = https://svn.apache.org/repos/asf/hadoop/common/branches/branch-1.0 -r 1335192; compiled by 'hortonfo' on Tue May  8 20:31:25 UTC 2012

************************************************************/

Re-format filesystem in /home/hadoop/work/name ? (Y or N) Y

12/05/25 07:04:18 INFO util.GSet: VM type       = 64-bit

12/05/25 07:04:18 INFO util.GSet: 2% max memory = 9.6675 MB

12/05/25 07:04:18 INFO util.GSet: capacity      = 2^20 = 1048576 entries

12/05/25 07:04:18 INFO util.GSet: recommended=1048576, actual=1048576

12/05/25 07:04:19 INFO namenode.FSNamesystem: fsOwner=hadoop

12/05/25 07:04:19 INFO namenode.FSNamesystem: supergroup=supergroup

12/05/25 07:04:19 INFO namenode.FSNamesystem: isPermissionEnabled=true

12/05/25 07:04:19 INFO namenode.FSNamesystem: dfs.block.invalidate.limit=100

12/05/25 07:04:19 INFO namenode.FSNamesystem: isAccessTokenEnabled=false accessKeyUpdateInterval=0 min(s), accessTokenLifetime=0 min(s)

12/05/25 07:04:19 INFO namenode.NameNode: Caching file names occuring more than 10 times

12/05/25 07:04:22 INFO common.Storage: Image file of size 112 saved in 0 seconds.

12/05/25 07:04:22 INFO common.Storage: Storage directory /home/hadoop/work/name has been successfully formatted.

12/05/25 07:04:22 INFO namenode.NameNode: SHUTDOWN_MSG:

/************************************************************

SHUTDOWN_MSG: Shutting down NameNode at localhost.localdomain/127.0.0.1

************************************************************/


format 이 끝나면 slave1, 2 노드의  dfs.data.dir 에 몇개의 파일이 생성된 것을 확인 할 수 있다.


start-dfs.sh

master Node 에서 start-dfs.sh 를 실행하면 'slaves' 파일에 설정한 node 가 실행되는 것을 볼 수 있다.

$ start-dfs.sh 

starting namenode, logging to /var/hadoop-1.0.3/libexec/../logs/hadoop-hadoop-namenode-localhost.localdomain.out
// slave2 DataNode 시작

slave2: starting datanode, logging to /var/hadoop-1.0.3/libexec/../logs/hadoop-hadoop-datanode-localhost.localdomain.out

 // slave1 DataNode 시작
slave1: starting datanode, logging to /var/hadoop-1.0.3/libexec/../logs/hadoop-hadoop-datanode-localhost.localdomain.out

localhost: starting secondarynamenode, logging to /var/hadoop-1.0.3/libexec/../logs/hadoop-hadoop-secondarynamenode-localhost.localdomain.out


hadoop-env.sh 에  JAVA_HOME 설정이 안되어 있으면 아래와 같은 에러가 뜬다.
slave2: Error: JAVA_HOME is not set.
slave1: Error: JAVA_HOME is not set

start-dfs.sh 를 실행하면 slaves > masters 순으로 실행된다.




mstart-mapred.sh

$ start-mapred.sh


starting jobtracker, logging to /var/hadoop-1.0.3/libexec/../logs/hadoop-hadoop-jobtracker-localhost.localdomain.out

slave2: starting tasktracker, logging to /var/hadoop-1.0.3/libexec/../logs/hadoop-hadoop-tasktracker-localhost.localdomain.out

slave1: starting tasktracker, logging to /var/hadoop-1.0.3/libexec/../logs/hadoop-hadoop-tasktracker-localhost.localdomain.out



mstart-mapred.sh 를 실행하면 로컬의 잡트래커 실행 > slaves 의 태스크크래스 실행 순으로 실행된다.



기타 설정


hadoop-env.sh  메모리설정

자세한 설명은  http://tawool.tistory.com/283 이곳을 보자.

테스트 환경에서는 메모리의 크기에 한계가 있다. 아래와 같은 구성이 필요하다.

Worker Node
 

태스크 트래커 노드
태스크 크래커 : 500 MB
맵태스크 : 200 MB * 2
리듀스 태스크 : 200 MB * 2

데이터 노드 태스크
데이터 노드 : 500 MB


총 1.8 GB



설정법


// 맵 태스크 리듀스 태스크 JVM 할당 

$ vi  mapred-site.xml
 
<configuration>
    <property>
        <name> mapred.child.java.opts </name>
        <value> -Xmx200m </value>
    </property>
    <property>
        <name>mapred.job.tracker</name>
        <value>master:9001</value>
    </property>
    <property>
        <name>mapred.system.dir</name>
        <value>/home/hadoop/work/mapred/system</value>
    </property>
</configuration>
 



확인하기


 
HDFS 상태 확인

http://192.168.116.131:50070/dfshealth.jsp



Map / Reduce Adminstration


http://192.168.116.131:50030/jobtracker.jsp




Log 확인

Start-all.sh 실행시에 Data Node에 taskTracker, DataNode의 Log가 slave1, slave2 에서 정상적으로 출력되고 있습니다.





jps 

아래와 같이 떠야 한다....
master jps
30627 NameNode
30814 JobTracker  
30762 SecondaryNameNode   << 구성하지 않았음.
30910 Jps

slave jps
30695 DataNode
30881 TaskTracker



Hadoop 벤치마킹 Tool




읽기 쓰기


- 30mb 짜리 파일 2개 기록

$ hadoop jar /var/hadoop-1.0.3/hadoop-test-1.0.3.jar TestDFSIO -write -nrFiles 2 -fileSize 30

- 30mb 짜리 파일 2개 읽기 
$ hadoop jar /var/hadoop-1.0.3/hadoop-test-1.0.3.jar TestDFSIO -read -nrfiles 2 -fileSize 30

- 테스트용 파일 모두 삭제 
$ hadoop jar /var/hadoop-1.0.3/hadoop-test-1.0.3.jar TestDFSIO -clean

정렬

test.randomwriter.maps_per_host

10

Number of maps/host

test.randomwrite.bytes_per_map

1073741824

Number of bytes written/map

test.randomwrite.min_key

10

minimum size of the key in bytes

test.randomwrite.max_key

1000

maximum size of the key in bytes

test.randomwrite.min_value

0

minimum size of the value

test.randomwrite.max_value

20000

maximum size of the value

<http://wiki.apache.org/hadoop/RandomWriter >

http://anujjaiswal.wordpress.com/2011/04/07/hadoop-cluster-performance-evaluation/ 

$hadoop jar $HADOOP_INSTALL/hadoop-examples.jar randomwriter random-data -Dtest.randomwrite.bytes_per_map=5000000 -Dtest.randomwrite.total_bytes=50000000




참고

Module 7: Managing a Hadoop Cluster : http://developer.yahoo.com/hadoop/tutorial/module7.html  
O'reilly 톰 화이트 : Hadoop 완벽 가이드  





&


 

'빅데이터' 카테고리의 다른 글

Hadoop Deprecated Properties  (0) 2012.05.29
관리 도구  (0) 2012.05.29
hadoop-en.sh 설정  (0) 2012.05.28
Hadoop Master Node  (0) 2012.05.28
CDH3 Installation  (0) 2012.05.20