프로젝트를 진행하던 중, 빅데이터 플랫폼인 하둡의 대표적인 RDB인 Hive와, NoSQL DB인 HBase에 데이러틀 적재해야 하는 프로그램을 짜야할 일이 생겼다.
Hadoop 기반 개발은 처음이기에 꽤 많이 헤멨었고, 언젠가 또 Hadoop 기반 개발을 해야할 지 모르는 상황이 발생하면 이번처럼 헤매지 않기 위해 간단한 Java를 통한 HIVE/HBASE 연동 방법을 코드로 구현하는 방법을 대략적으로 적어놓고자 한다.
우선 Java Application과 연동되기 위한 Hadoop 인프라를 먼저 설치한다.
Hadoop이 설치될 서버는 다음과 같이 구성했다.
- OS : CentOS 7.9
- ROM : 32GB
- RAM : 8GB
사실 RAM이 중요한데, 로컬 컴퓨터에 램의 용량이 크지 않아 8GB로 설정했다. 가능하다면 크게 줄 수록 테스트 시 스트레스를 받지 않을 수 있고, 여러 테스트 결과 8GB정도는 되어야 RAM 부족으로 에러가 발생하는 일이 없었다.
1. 서버 설정
먼저 하둡이 설치되기 위한 몇 가지 설정을 수행한다.
가장 먼저 수행할 작업은 hostname변경이다.
다음 명령어를 입력해 hostname을 변경한다.
hostnamectl set-hostname hadoopsv
그리고 /etc/hosts 파일에 다음 문구를 추가한다.
192.168.x.x hadoopsv
다음으로 방화벽을 설정한다.
원래대로라면 몇몇 포트만을 열어줘야겠지만, 테스트용으로 할 뿐 상용으로 올리는 게 아니니 방화벽을 꺼버리는 것으로 대체한다.
systemctl stop firewalld
systemctl disable firewalld
이제 몇 가지 필요한 인프라를 설치한다.
가장 먼저 필요한 인프라는 자바이다. 다음 명령어로 설치 가능한 openjdk들을 검색하고, 1.8.0 버전의 devel openjdk를 설치한다.
yum list | grep openjdk
yum install -y java-1.8.0-openjdk-devel.x86_64
설치가 완료되었다면 JAVA_HOME을 설정한다. readlink 명령어로 나온 결과물 중 /bin/javac 전까지를 복사한 후 /etc/profile 파일에 복사한 디렉터리와 PATH를 추가한다.
readlink -f `which javac`
vi /etc/profile
# 다음 내용 추가 후 저장
export JAVA_HOME={복사한 디렉터리}
export PATH=$PATH:$JAVA_HOME/bin
다음은 DB이다. Hadoop의 RDB인 Hive는 메타데이터를 저장하기 위한 RDB를 필요로 하고, 현 포스팅에서는 해당 RDB로 Postgresql을 선택했다.
Postgresql은 쉬운 설치를 위해 Docker 기반으로 설치했다. 다음 명령어를 순차적으로 실행하여 도커를 설치하고 실행한다.
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce
systemctl enable docker
systemctl start docker
도커 실행까지 완료되었다면 다음 명령어로 postgis를 설치한다.
docker run \
-p 5432:5432 \
--restart always \
--name postgres \
-e TZ=Asia/Seoul \
-e POSTGRES_PASSWORD=password \
-d \
postgis/postgis
Image를 pull받아 컨테이너 실행까지 완료되었다면 이제 컨테이너에 진입해 hive 데이터베이스를 생성한다.
docker exec -it postgres bash
su postgres
psql
create database hive;
\q
*create database 이후 정상 생성되었는지 확인하고 싶다면 \l 명령어로 확인이 가능하다.
여기까지 완료되었다면 추가로 몇 가지 인프라를 설치한다.
yum install -y wget net-tools vim
2. Hadoop 계정 생성 및 키 생성
다음으로 Hadoop과 Hive/HBase가 사용할 계정인 hadoop 계정을 생성한다.
아래 명령어를 따라 계정을 생성하고 비밀번호를 설정한다. 참고로 비밀번호도 hadoop으로 설정했다.
adduser hadoop
passwd hadoop
계정 생성이 완료되었다면 hadoop에 sudo 권한을 부여한다. 반드시 해줘야 할 필요는 없지만, 앞으로의 설치를 모두 hadoop 계정으로 수행하기 위해 부여해주었다.
visudo -f /etc/sudoers
#다음 문구 추가
hadoop ALL=(ALL) ALL
이제 hadoop 계정으로 넘어가 자유롭게 서버를 오고갈 수 있도록 key를 생성하고 비밀번호 없이 ssh가 가능하도록 설정해준다.
su hadoop
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa;\
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys;\
chmod 0600 ~/.ssh/authorized_keys
ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop@hadoopsv
3. Hadoop 설치
이제 준비는 끝이났고 본격적으로 Hadoop을 설치한다.
Hadoop 폴더는 일단 hadoop 계정의 홈 디렉터리인 /home/hadoop으로 정했다.
홈 디렉터리에서 wget을 통해 hadoop을 설치하고 압축을 해제한다.
cd ~
wget https://downloads.apache.org/hadoop/common/hadoop-3.2.3/hadoop-3.2.3.tar.gz
tar -xvzf hadoop-3.2.3.tar.gz
설치가 완료됐으면 /home/hadoop/hadoop-{version} 폴더가 생성된다.
초기 설정 파일은 해당 폴더 내 etc/hadoop 안에 존재한다. 이 폴더 안의 다음 파일들을 수정하도록 한다.
- workers
- core-site.xml : hdfs, 맵리듀스 공통 설정 파일
- hdfs-site.xml : hdfs 설정 파일
- mapred-site.xml : 맵리듀스 설정파일
- yarn-site.xml : yarn 설정 파일
- hadoop-env.sh
- httpfs-site.xml : httpfs 설정 파일
그리고 각 파일을 다음과 같이 설정해준다.
workers
# 기존애 있던 localhost는 삭제
hadoopsv
core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoopsv:8020</value>
</property>
<property>
<name>hadoop.proxyuser.hadoop.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hadoop.groups</name>
<value>*</value>
</property>
</configuration>
hdfs-site.xml
<configuration>
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/hadoop/hadoopdata/hdfs/namenode</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/hadoopdata/hdfs/datanode</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/hadoop/hadoopdata/hdfs/journalnode</value>
</property>
<property>
<name>dfs.nameservice</name>
<value>hadoop-cluster</value>
</property>
<property>
<name>dfs.namenode.rpc-address.hadoop-cluster</name>
<value>hadoopsv:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.hadoop-cluster</name>
<value>hadoopsv:50070</value>
</property>
</configuration>
mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.map.memory.mb</name>
<value>4096</value>
</property>
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>4096</value>
</property>
<property>
<name>mapreduce.map.java.opts</name>
<value>-Xmx4096m</value>
</property>
<property>
<name>mapreduce.reduce.java.opts</name>
<value>-Xmx4096m</value>
</property>
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>
</configuration>
yarn-site.xml
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<!-- 생략가능 -->
<property>
<name>yarn.nodemanager.local-dirs</name>
<value>/yarn/nm-local-dir</value>
</property>
<property>
<name>yarn.resourcemanager.fs.state-store.uri</name>
<value>/yarn/system/rmstore</value>
</property>
<!-- 여기까지 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoopsv</value>
</property>
<property>
<name>yarn.web-proxy.address</name>
<value>0.0.0.0:8089</value>
</property>
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster1</value>
</property>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoopsv</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>hadoopsv:8088</value>
</property>
</configuration>
hadoop-env.sh
#아래 내용을 추가한다.
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.352.b08-2.el7_9.x86_64
export HADOOP_PID_DIR=/home/hadoop/pids
추가로 아래 명령어로 방금 설정한 pids 폴더를 만들어준다.
mkdir ~/pids
httpfs-site.xml
<configuration>
<property>
<name>httpfs.hadoop.config.dir</name>
<value>/home/hadoop/hadoop-3.2.3/etc/hadoop</value>
</property>
</configuration>
모든 파일 설정이 완료되었다면 이제 /etc/profile에 다음 환경변수를 추가한다.
export HADOOP_HOME=/home/hadoop/hadoop-3.2.3
export PATH=$PATH:$HADOOP_HOME/bin
export HADOOP_INSTALL=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export HADOOP_YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export HADOOP_OPTS="$HADOOP_OPTS -Djava.library.path=$HADOOP_HOME/lib/native"
마지막으로 namenode를 포맷한다. 이 떄 이상이 발생하지 않으면 설치가 정상 완료된 것으로 봐도 무방하다.
hdfs namenode -format
이상없이 포맷이 완료됐다면 이제 각 서비스를 켜준다.
hdfs --daemon start journalnode
hdfs --daemon start namenode
hdfs --workers --daemon start datanode
cd $HADOOP_HOME/sbin
./start-yarn.sh
cd $HADOOP_HOME/bin
./mapred --daemon start historyserver
hdfs --daemon start httpfs
*최초 실행 이후로는 start-all.sh / stop-all.sh 명령어를 사용해서 껐다키면 된다.
*최초 실행도 start-all.sh로 해도 되는지는 잘 모르겠다.
이후 다음 명령어를 통해 에코시스템들이 잘 켜졌는지 확인해준다.
jps
4. Hive 설치
다음으로 Hadoop의 RDB인 Hive를 설치한다.
다음 명령어를 순차적으로 실행한다.
cd ~
wget https://downloads.apache.org/hive/hive-3.1.2/apache-hive-3.1.2-bin.tar.gz
tar -xvzf apache-hive-3.1.2-bin.tar.gz
설치가 완료됐다면 /etc/profile 파일을 수정한다.
sudo vim /etc/profile
# 추가
export HIVE_HOME=/home/hadoop/apache-hive-3.1.2-bin
export PATH=$PATH:$HIVE_HOME/bin
설정 완료 후 source /etc/profile 명령어로 수정한 환경변수를 적용하고, Hive가 사용할 디렉터리를 만들어준다.
source /etc/profile
hdfs dfs -mkdir /tmp
hdfs dfs -chmod g+w /tmp
hdfs dfs -mkdir -p /user/hive/warehouse
hdfs dfs -chmod g+w /user/hive/warehouse
이제 다음 명령어로 정상적으로 폴더가 생성됐는지 확인한다.
hdfs dfs -ls /
hdfs dfs -ls /user/hive
환경설정을 수행한다. 설정 파일은 conf 폴더에 있는 hive-site.xml인데, 설치 직후에는 파일이 존재하지 않으니 hive-default.xml.template을 복사해서 만들어준다.
cd $HIVE_HOME/conf
cp hive-default.xml.template hive-site.xml
hive-site.xml를 열어 가장 상단에 다음 설정을 추가한다.
<property>
<name>system:java.io.tmpdir</name>
<value>/tmp/hive/java</value>
</property>
<property>
<name>system:user.name</name>
<value>${user.name}</value>
</property>
그리고 DB 연결을 위해 다음 설정들을 수정한다. 참고로 아래 설정들은 한 군데 붙어있지 않고 떨어져 있으니, "jdo.option" 검색을 통해 일일히 수정한다.
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>org.postgresql.Driver</value>
<description>Driver class name for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>postgres</value>
<description>Username to use against metastore database</description>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>password</value>
<description>password to use against metastore database</description>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:postgresql://hadoopsv:5432/hive</value>
<description>
JDBC connect string for a JDBC metastore.
To use SSL to encrypt/authenticate the connection, provide database-specific SSL flag in the connection URL.
For example, jdbc:postgresql://myhost/db?ssl=true for postgres database.
</description>
</property>
Hive의 Transaction을 허용하기 위한 설정들도 수정한다. 마찬가지로 일일히 찾아 아래와 같이 value를 변경한다.
<property>
<name>hive.support.concurrency</name>
<value>true</value>
</property>
<property>
<name>hive.exec.dynamic.partition.mode</name>
<value>nonstrict</value>
</property>
<property>
<name>hive.txn.manager</name>
<value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
</property>
<property>
<name>hive.compactor.initiator.on</name>
<value>true</value>
</property>
<property>
<name>hive.compactor.worker.threads</name>
<value>3</value>
</property>
마지막으로 을 검색해서 에러를 유발하는 특수기호를 삭제한다.
설정이 완료됐다면 hive가 postgresql에 접속할 수 있도록 postgresql jdbc driver을 설치한다.
cd $HIVE_HOME/lib
wget https://jdbc.postgresql.org/download/postgresql-42.5.1.jar --no-check-certificate
이제 메타데이터를 생성한다.
cd $HIVE_HOME/bin
./schematool -dbType postgres -initSchema
이 때 종종 Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V 에러가 발생하곤 하는데, 이 경우 $HADOOP_HOME/share/hadoop/hdfs/lib/guava-{version}.jar을 $HIVE_HOME/lib에 옮기고 기존의 guava-{version}.jar을 삭제하고 재시도하면 된다.
마지막으로 hiveserver2를 실행한다.
nohup ./hive --service hiveserver2 &
잠시 기다린 후 netstat -tnlp | grep 1000 명령어를 통해 10000포트에 hiveserver2가 정상 실행되었는지 확인한다. 조금 시간이 걸리니, 여유를 갖고 기다린다.
*Hive Session ID = ... 만 계속 출력된다면 껐다 켜보자. 끄는 명령어는 kill -15 {pid}이다.
5. Zookeeper 설치
Java Application이 HBase에 접근할 때는 Zookeeper을 통해 접근하게 된다. 그렇기에 HBase 설치 시 Zookeeper를 먼저 설치해주어야 한다.
psql과 달리 도커로 설치하지 않는 이유는 HBase와 Zookeeper가 특정 디렉터리를 공유해야하는데, 이 부분을 쉽게 공유하게 하기 위함이다. 물론 도커로 설치하고 디렉터리를 컨테이너 내 디렉터리와 연동시켜도 무방할 것 같다.
우선 주키퍼를 설치한다.
cd ~
wget https://downloads.apache.org/zookeeper/zookeeper-3.6.4/apache-zookeeper-3.6.4-bin.tar.gz
tar -xvzf apache-zookeeper-3.6.4-bin.tar.gz
zookeeper의 환경설정을 다음과 같이 수행한다. 파일은 conf 폴더 내 zoo_sample.cfg 파일을 zoo.cfg 파일로 변경해 사용한다.
cd ~/apache-zookeeper-3.6.4-bin/conf
cp zoo_sample.cfg zoo.cfg
vim zoo.cfg
#수정
dataDir=/home/hadoop/data
#추가
maxClientCnxns=0
maxSessionTimeout=180000
저 dataDir은 HBase에도 들어갈 예정이므로 잘 기억해둔다.
이제 아래 명령어로 방금 설정한 디렉터리를 생성한다.
mkdir ~/data
폴더가 생성됐다면 zookeeper 서버를 실행한다.
cd ~/apache-zookeeper-3.6.4-bin/bin
./zkServer.sh start
6. HBase 설치
마지막으로 Hadoop의 NoSQL인 HBase를 설치한다.
cd ~
wget http://archive.apache.org/dist/hbase/2.4.15/hbase-2.4.15-bin.tar.gz
tar xvzf hbase-2.4.15-bin.tar.gz
HBase는 기본적으로 실행 시 Zookeeper을 내장해서 실행된다.
하지만 현 포스팅에서는 Zookeeper을 별도로 이미 설치했으므로, 해당 옵션을 꺼줘야 한다.
이 외에도 추가적인 설정을 수행한다. 파일은 conf 폴더 내의 hbase-site.xml, hbase-env.sh, regionservers 파일이다.
hbase-site.xml
<configuration>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.tmp.dir</name>
<value>./tmp</value>
</property>
<property>
<name>hbase.rootdir</name>
<value>hdfs://hadoopsv:8020/hbase</value>
</property>
<property>
<name>hbase.zookeeper.property.clientport</name>
<value>2181</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>hadoopsv</value>
</property>
<property>
<!-- zookeeper 설정과 일치시킨다. -->
<name>hbase.zookeeper.property.dataDir</name>
<value>home/hadoop/data</value>
</property>
<property>
<name>hbase.master</name>
<value>hadoopsv:16000</value>
</property>
<property>
<name>zookeeper.session.timeout</name>
<value>1200000</value>
</property>
</configuration>
hbase-env.sh
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.352.b08-2.el7_9.x86_64
export HBASE_MANAGES_ZK=false
regionservers
# 기존 localhost는 삭제
hadoopsv
설정 완료 후 hbase를 실행한다.
cd /home/hadoop/hbase-2.4.15/bin
./start-hbase.sh
이후 jps로 확인한다. 참고로 설치 과정에서 에러가 있을 경우 잠시 후 jps 재실행 시 HMaster가 꺼질 수 있으므로, jps 명령어 결과에서 HMaster가 잘 켜져있다고 판단하지 말고 시간이 조금 지나 재확인해본다.
'IT 지식 > 빅데이터 & 분석' 카테고리의 다른 글
JAVA-HIVE/HBASE 간 통신_HBase 통신 (0) | 2023.01.22 |
---|---|
JAVA-HIVE/HBASE 간 통신_Hive 통신 (0) | 2023.01.22 |
Apache Bigtop을 이용한 Hadoop 설치 (0) | 2022.10.24 |
멀티노드에 Hadoop 설치해보기 (0) | 2022.10.23 |
[시계열 분석 모델] AR, MA, ARIMA (2) | 2021.10.12 |