CLASSPATH, HADOOP_CLASSPATH

HBase를 다루는 MapReduce 프로그램을 작성하다 보니 job이 할당되고, task가 뜨다가  org.apache.hadoop.hbase.mapreduce.TableMapper 가 NoClassDefFoundError 라는 메시지를 출력하고 task가 종료되어 버린다. 한동안 손을 놓고 있다가 오랫만에 다시 보니 이거 참 새롭다. 분명히 전에도 저런 문제가 있어서 한참 끙끙댔던 기억이 난단 말이다.

classpath 문제이다. hbase.jar 를 못찾는 것인데, HADOOP_CLASSPATH  에 정의를 해 주면 된다. 일반 java 프로그램의 library 경로 지정은 CLASSPATH  환경 변수에 한다. MapReduce의 task 프로그램이 사용하는 classpath는 HADOOP_CLASSPATH이다.

문제는 이걸 알고 있지만서도 자꾸 나중에 끙끙대게 되는 것이다. 먼저 관련 문서를 참고 하자. http://hadoop.apache.org/hbase/docs/current/api/org/apache/hadoop/hbase/mapred/package-summary.html#package_description

이걸 보면 HBase 를 다루는 MapReduce 프로그램은 hadoop/conf 디렉토리에 hbase-site.xml 파일을 넣고 hbase.jar 를 hadoop/lib 디렉토리에 복사한다. 보다 확실한 방법은 hadoop/conf/hadoop-env.sh에  HADOOP_CLASSPATH 에 hbase.jar 와 hbase/conf 디렉토리를 추가하는 것이라 나와있다. task 프로그램이 사용하는 그 외 기타 라이브러리의 경로도 여기에 추가해 주면 된다. 그런데 hadoop-env.sh 의 HADOOP_CLASSPATH 값은 실제 값이어야 한다. .bashrc 같은 파일에 환경변수 값을 설정하고 hadoop-env.sh 에서 이 값을 가져다 쓰는 식으로 하면 처음엔 Job이 잘 실행되는 것처럼 보이다가 정작 task 노드에서 task가 실행될때 task프로그램이 위처럼 class 파일을 못 찾고 종료되어 버린다.

실제 파일 값을 예로 보자.
~/.bashrc

:
for jar in /opt/hbase/lib/*.jar; do
  lib_path=${lib_path}:${jar}
done
export CLASSPATH=”/opt/hbase/hbase-0.20.0.jar:/opt/hbase/conf:${lib_path}”
:

/opt/hadoop/conf/hadoop-env.sh

:
export HADOOP_CLASSPATH=$CLASSPATH
:

이렇게 설정하면 안된다.

아래와 같이 실제 값을 hadoop-env.sh에 넣도록 한다. 아마 task 프로그램이 실행되면서 hadoop-env.sh 을 실행시켜서 값을 설정하는데 이용하는 것 같은데, hadoop-env.sh 안에 #!/bin/sh 없으니까 환경 변수 설정값을 못 받는게 아닌가 하는 추측이 된다.
여튼, 아래와 같이 직접 hadoop-env.sh 안에 값을 설정하도록 하자
/opt/hadoop/conf/hadoop-env.sh

:
for jar in /opt/hbase/lib/*.jar; do
  lib_path=${lib_path}:${jar}
done
export HADOOP_CLASSPATH=/opt/hbase/hbase.jar:/opt/hbase/conf:${lib_path}
:

확인해 보진 않았지만, hbase/conf/hbase-env.sh 안의 HBASE_CLASSPATH  도 같은 맥락으로 이해하면  되지 않을까 싶다.

2010.09.07 추가
hadoop-env.sh 이 HADOOP_CLASSPATH 보다 우선 순위가 높다.
즉, HADOOP_CLASSPATH 와 hadoop-env.sh 에 각각 다른 버전의 hbase-xxxx.jar 가 설정 되어 있을 경우, hadoop-env.sh 의 것이 사용된다.

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중