/ ET-CETERA

Hadoop 설치와 활용

VMware Workstation Pro 15 설치 및 CentOS 7 설치

Hadoop을 사용하기 위해서 Windows 10에 VMWARE Workstation Pro 15를 설치한 후 CentOS 7을 설치합니다. (VMWare Workstation Player는 무료로 사용가능하지만 Workstation Pro 버전은 유료입니다. 30일 trial을 이용할 수 있습니다.)

먼저 VMware Workstation Pro를 설치하고 실행하면 다음과 같은 화면을 볼 수 있습니다.

VMWARE 설치-1

새로운 가상머신을 만듭니다. 가상머신을 만든 후 나중에 iso파일을 이용해서 CentOS 7을 설치합니다.

VMWARE 설치-2

VMWARE 설치-3

가상머신의 이름을 정해주는 부분이 나오는데 우리는 가상머신을 총 4개 이용할것입니다. 각각의 가상머신 이름을 Hadoop01 ~ Hadoop04까지 사용합니다. 처음의 가상머신만 생성하고 나머지 3개의 가상머신은 clone해서 사용합니다.

VMWARE 설치-4

디스크 공간은 50GB로 설정하고 Customize Hardware를 클릭해서 사용 메모리는 2GB로 설정합니다.

VMWARE 설치-5

생성이 완료된 후 Virtual Machine Setting을 이용하여 CD/DVD부분에 CentOS 7 iso image파일을 연결한 후 Virtual Machine을 기동시키면 CentOS 7 설치가 진행됩니다.

CentOS 7 iso image는 여기를 클릭하면 CentOS-7-x86_64-DVD-2003.iso 파일을 받으실 수 있습니다.

아래의 화면은 VMware Player를 이용한 설치화면입니다. WMware Workstation을 사용하는것과 차이가 없습니다.

VMWARE 설치-6

먼저 언어선택에서 한국어를 선택하시고 계속 진행하면 다음과 같은 화면이 나오는데 여기서 먼저 네트워크 및 호스트명으로 들어간 후 네크워크를 연결(켬)합니다.

VMWARE 설치-7

완료를 클릭하신 후 소프트웨어 > 소프트웨어 설치를 클릭한 후 다음과 같이 설정합니다. (GNOME 사용이 필수는 아닙니다. 사용의 편의를 위해서 GNOME을 선택한 것 뿐입니다.)

VMWARE 설치-8

완료를 클릭한 후 시스템 > 설치대상을 선택하여 파티션을 잡아줍니다.

VMWARE 설치-9

파티션을 설정합니다. 부분을 선택하고 완료를 누르면 수동으로 파티션 설정하는 부분으로 넘어갑니다. 다음의 각 파티션을 설정합니다.

  • swap : 2GB
  • /boot : 1GB
  • /home : 10GB
  • / : 용량을 지정하지 않으면 나머지 모든 용량을 자동으로 할당합니다.

VMWARE 설치-10

VMWARE 설치-11

설치시작을 눌러 설치를 시작합니다.

root 유저의 암호를 변경하고 새로운 사용자를 한명 추가합니다. 새로운 사용자를 추가했지만 사용의 편의를 위해 root 계정을 이용하도록 하겠습니다.

VMWARE 설치-12

설치가 끝나면 재부팅하고 root 계정으로 로그인합니다.

Java 설치

Hadoop은 JVM상에서 동작하기 때문에 Java를 설치해야 합니다. Java를 다시 설치하고 환경변수를 설정합니다. Java는 8버전을 이용합니다.

  • 기존의 Java 삭제

rpm -qa | grep java

결과로 출력된 파일 중 javapackages-tools-3.4.1-11.el7.noarch, python-javapackages-3.4.1-11.el7.noarch, tzdata-java-2018e-3.el7.noarch 3개에 대해서 삭제를 진행합니다.

yum remove javapackages-tools-3.4.1-11.el7.noarch

yum remove python-javapackages-3.4.1-11.el7.noarch

yum remove tzdata-java-2018e-3.el7.noarch

rpm -qa | grep java

설치된 내용이 없음을 확인한 후 Oracle에서 Java 8을 다운로드 합니다. 만약 다운로드가 잘 안되면 Windows에서 다운로드 한 후 (Linux X64 tar.gz파일) 공유폴더를 이용해서 CentOS로 복사합니다.

공유폴더 설정은 윈도우에서 공유폴더를 하나 생성한 후 폴더의 속성 > 공유 > 고급공유에서 선택한 폴더공유를 체크하고 권한부분에서 eveyone에 모든 권한을 부여합니다.

VMware 가상머신 설정에서 option 탭에서 아래의 그림과 같이 설정합니다. 설정이 끝나면 VMware Tool을 설치합니다. VM 메뉴의 Install VMware Tools를 선택하면 VMware Tools가 CD형식으로 바탕화면에 나타나고 /run/media/root/VMware Tools/ 디렉토리로 이동하면 VMwareTools-10.3.21-14772444.tar.gz 파일을 확인할 수 있습니다.

해당 파일을 root 계정의 home으로 복사한 후 아래의 명령을 이용하여 해당 파일의 압축을 풀고 설치 shell script를 실행하면 VMware tool을 설치할 수 있습니다.

tar zxvf VMwareTools-10.3.21-14772444.tar.gz

VMware Tool가 설치되어야 /mnt/hgfs폴더가 생성되고 그 안에 윈도우에서 공유한 공유폴더가 보여지게 됩니다..

공유폴더 설정

Java 파일을 얻었으면 압축을 풀고 /usr/local/java 폴더로 Java Home을 설정합니다.

Java 설치

vi를 이용해서 /etc/profile에 다음의 내용을 추가합니다.

export JAVA_HOME=/usr/local/java
export HADOOP_HOME=/usr/local/hadoop
export CLASSPATH=$JAVA_HOME/lib:$CLASSPATH
PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

변경된 profile을 적용시켜야 합니다.

source /etc/profile

Java가 정상적으로 설치됬는지 확인합니다.

java -version

Java Version


VMWARE CentOS 7 복사

Hadoop을 사용하기 위해서 서버 4개를 이용할 것입니다. 설치가 끝나면 생성된 가상머신에서 마우스 오른쪽 클릭을 하면 메뉴가 나오는데 Manage > Clone...을 선택합니다.

VMWARE 설치-13

VMWARE 설치-14

Create a full clone을 선택 후 가상 머신 이름을 입력합니다. Hadoop02 ~ Hadoop04까지 3개를 생성합니다.

VMWARE 설치-15

VMWARE 설치-16

VMWARE 설치-17


Hadoop

Hadoop은 Apache 최상위 오픈소스 프로젝트로 대용량의 데이터를 저장하고 분석하고 처리하기 위한 framework입니다.

Hadoop의 특징은 다음과 같습니다.

  • 선형적인 확장성 제공 : 일반적인 스토리지는 초기에 애플리케이션에서 사용할 용량을 예측하여 미리 스토리지 용량을 확보한 상태에서 시스템이 오픈되나, Hadoop을 이용할 경우에는 서비스 초기에 필요한 수준으로만 스토리지 용량을 확보해 시스템을 오픈한 후 데이터 증가 추이를 보면서 스토리지를 추가하는 방식으로 진행합니다.

  • 데이터 분석 처리에 활용 : 분석용 데이터를 HDFS에 저장하고, Map/Reduce라는 분산/병렬 처리 프레임워크를 데이터 분석하는데 사용합니다.

  • API 기반의 파일 처리 시스템 : 일반적인 파일시스템처럼 운영체제에서 제공하는 파일처리 명령을 이용할 수 없고, Hadoop을 이용하는 애플리케이션은 Hadoop에서 제공하는 명령어나 프로그램 API를 이용해야 합니다.

  • Immutable File System : 파일은 한번 써지면 변경되지 않는다고 가정합니다. 따라서 Hadoop은 파일을 저장하고 저장된 파일에 대해 읽기 요청 위주(스트리밍 방식)인 응용이나 배치 작업 등에 적합합니다. 이런 제약 때문에 파일 처리를 주로 하는 기존 솔루션이나 시스템을 수정없이 Hadoop에 적용 할 수는 없습니다.

  • 네임스페이스 관리를 NameNode 메모리에 저장 : 파일 시스템의 네임스페이스 정보를 NameNode의 메모리상에서 관리하기 때문에 Hadoop에 저장할 수 있는 파일과 디렉토리의 개수는 NameNode의 메모리 크기에 제한을 받게됩니다.

  • NameNode 이중화 : NameNode가 SPOF(Single Point Of Failre)입니다. NameNode에 문제가 발생하면 파일시스템 전체 클러스터에 장애가 발생하게 됩니다. 따라서 일반적으로 Secondary NameNode를 사용해야 합니다.

하둡 분산형 파일시스템(Hadoop Distributed FileSystem, HDFS) 특징

  • HDFS는 데이터를 저장하면 다수의 노드에 복제 데이터도 함께 저장하여 데이터의 유실을 방지합니다.

  • HDFS에 파일을 저장하거나, 저정된 파일을 조회하려면 스트리밍 방식으로 접근해야 합니다.

  • 한번 저장된 파일은 수정할 수 없고(2.0부터는 append가능) 읽기만 가능합니다. 따라서 데이터의 무결성을 유지할 수 있습니다.

  • 데이터의 수정은 불가능하지만 파일이동, 삭제, 복사를 할 수 있는 인터페이스는 제공합니다.

하둡 분산형 파일시스템(Hadoop Distributed FileSystem, HDFS) 아키텍쳐

HDFS Architecture

  • 블록 구조의 파일 시스템으로, 저장하는 파일은 특정 사이즈의 블록으로 나눠져 분산된 서버에 저장됩니다.

  • 기본적으로 HDFS 블록의 사이즈는 Hadoop 배포판에 따라서 64,128,256MB로 상이합니다. 일반적으로 물리적인 디스크는 블록이라는 개념을 이용합니다. 이 블록은 한번에 읽고 쓸 수 있는 데이터의 최대량을 의미합니다. 보통의 파일 시스템의 블록크기는 수 KB이지만 Hadoop의 HDFS는 128MB와 같이 굉장히 큰 단위입니다. 이렇게 큰 단위를 사용하는 이유는 데이터 탐색에 대한 비용을 최소화하기 위해서 입니다. 블록이 크면 블록의 시작점을 탐색하는데 시간이 적게 걸리고 데이터를 전송하는데 더 많은 시간을 할당해 줄 수 있기 때문입니다. 또한 HDFS 파일은 블록 크기보다 작은 데이터일 경우 전체 블록 크기에 해당하는 하위 디스크를 모두 점유하지는 않습니다. 즉, 블록의 크기가 128MB이고 1MB의 데이터를 저장한다면 128MB의 디스크를 사용하는게 아니라 1MB의 디스크만을 사용합니다.

  • 하나의 블록은 기본적으로 3개(변경가능)로 복제되며 각각 다른 HDFS의 노드에 분산저장됩니다.

  • HDFS는 Master 역할을 하는 NameNode 서버 한 대와, Slave 역할을 하는 DataNode 서버 여러 대로 구성됩니다.

  • NameNode는 HDFS의 모든 메타데이터(블록들이 저장되는 디렉토리의 이름, 파일명등)를 관리하고, HDFS 클라이언트가 이를 이용하여 저장된 파일에 접근할 수 있습니다.

  • Hadoop 어플리케이션은 HDFS에 파일을 저장하거나, 저장된 파일을 읽기 위해 HDFS 클라이언트를 사용하며, 클라이언트는 API형태로 사용자에게 제공합니다.

  • DataNode는 주기적으로 NameNode에게 블록 리포트(노드에 저장되어 있는 블록의 정보)를 전송하고 이를 통해 NameNode는 DataNode가 정상 동작하는지 확인합니다.

  • HDFS 클라이언트는 NameNode에 접속해서 원하는 파일이 저장된 블록의 위치를 확인하고, 해당 블록이 저장된 DataNode에서 직접 데이터를 조회합니다.

하둡 분산형 파일시스템(Hadoop Distributed FileSystem, HDFS) 파일 저장 Flow

HDFS File Save Flow

  1. 어플리케이션이 HDFS 클라이언트에게 파일 저장을 요청하면, HDFS 클라이언트는 NameNode에게 파일 블록들이 저장될 경로 생성을 요청합니다. NameNode는 해당 파일 경로가 존재하지 않으면 경로를 생성한 후, 다른 클라이언트가 해당 경로를 수정하지 못하도록 Lock을 설정합니다. 그 후, NameNode는 클라이언트에게 해당 파일 블록들을 저장할 DataNode의 목록을 반환합니다.

  2. 클라이언트는 첫 번째 DataNode에게 데이터를 전송합니다.

  3. 첫 번째 DataNode는 데이터를 로컬에 저장한 후, 데이터를 두 번째 DataNode로 전송합니다.

  4. 두 번째 DataNode는 데이터를 로컬에 저장한 후, 데이터를 세 번째 DataNode로 전송합니다.

  5. 로컬에 데이터를 저장하였으면 자기에게 데이터를 넘겨준 DataNode에게 데이터의 로컬 저장이 완료 되었음을 응답(Ack)합니다.

  6. 로컬에 데이터를 저장하였으면 자기에게 데이터를 넘겨준 DataNode에게 데이터의 로컬 저장이 완료 되었음을 응답(Ack)합니다.

  7. 첫 번째 DataNode는 클라이언트에게 파일 저장이 완료 되었음을 응답합니다.

하둡 분산형 파일시스템(Hadoop Distributed FileSystem, HDFS) 파일 읽기 Flow

HDFS File Load Flow

  1. 어플리케이션이 클라이언트에게 파일 읽기를 요청합니다.

  2. 클라이언트는 NameNode에게 요청된 파일이 어떤 블록에 저장되어 있는지 정보를 요청합니다.

  3. 메타데이터를 통해 파일이 저장된 블록 리스트를 반환합니다.

  4. 클라이언트는 DataNode에 접근하여 블록 조회 요청합니다.

  5. DataNode는 클라이언트에게 요청된 블록을 전송합니다.

  6. 클라이언트를 어플리케이션에 데이터를 전달합니다.

MapReduce(맵리듀스)

대용량의 데이터처리를 위한 분산 프로그래밍 모델이자 software framework입니다. 대량의 데이터를 병렬로 분석할 수 있으며 프로그래머는 Map과 Reduce라는 두 개의 method를 직접 작성해서 구성합니다.

  • Map : 흩어져 있는 데이터를 연관성이 있는 데이터로 key,value형태로 분류하는 작업을 지칭합니다.

  • Reduce : Map에서 출력된 데이터에서 중복된 데이터를 제거하고 원하는 데이터를 추출하른 작업을 수행합니다.

아래의 그림은 문자열 데이터에 포함된 단어의 빈도수를 출력해주는 과정입니다.

MapReduce

  1. Splitting : 문자열 데이터를 라인별로 나눕니다.

  2. Mapping : 라인별로 문자열을 입력받아, <key, value> 형태로 출력합니다.

  3. Intermediate Splitting(Shuffling) : 같은 key를 가지는 데이터끼리 분류합니다.

  4. Reducing : 각 key 별로 빈도수를 합산해서 출력합니다.

  5. Combining : Reduce 메소드의 출력 데이터를 합쳐서 HDFS에 저장합니다.


CentOS 7에 Hadoop 설치

4대의 서버로 진행합니다.

  • Hadoop01 : NameNode (host명 : namenode)
  • Hadoop02 : DataNode (host명 : datanode01)
  • Hadoop03 : DataNode (host명 : datanode02)
  • Hadoop04 : DataNode (host명 : datanode03)

Hadoop의 설치 모드는 총 3개가 있습니다.

  • Standalone : 단일 Node로 사용합니다. 테스트 및 디버깅 용도입니다.
  • Pseudo distributed : 단일 Node에서 Cluster를 구성합니다.
  • Full distributed : 두 대 이상의 Node를 CLuster로 구성합니다.

여기서는 3번째 Full distributed 방식으로 진행하며 Hadoop의 버전은 2.9.2버전을 사용합니다.

참고 : 암호화 방식

  • 대칭키 암호화 방식

암호화를 위해서는 기본적으로 암호화의 대상이 되는 평서문(Plain Text)과 암호화를 위한 일종의 비밀번호인 암호키(Cryptography Key) 그리고 마지막으로 암호화 알고리즘(Algorithm)이 필요한데, 대칭키 암호화 방식은 문자 그대로 암호화와 복호화를 동일한 암호키를 이용하는 방식입니다.

대칭키 암호화 방식

위의 그림을 통해 살펴보면 동일한 암호키를 통해 암호화(Encryption), 복호화(Decryption)하는 것을 볼 수 있는데, 대칭키를 사용하는 암호화 알고리즘은 AESDES가 대표적입니다.

  • RSA를 이용한 암호화

RSA는 공개키를 이용하는 대표적인 암호화 방식이며 전자서명이 가능한 최초의 알고리즘으로 알려져 있습니다. AES, DES와 같은 대칭키 암호화 방식에서 발생하는 문제점을 해결하였습니다. 과거의 암호 방식은 암호화를 위한 키뿐만 아니라 알고리즘 역시 노출되지 않기 위해 노력하였으나 현대의 암호에서는 알고리즘을 공개하도록 하고 있습니다. 키 이외에 암호 시스템의 모든 것이 공개되어도 안전해야 한다고 Kerckhoff라는 사람이 주장 했는데 이것을 Kerckhoff의 법칙이라고 합니다.

RSA는 수학적인 기법을 통해 한 쌍의 공개키비밀키를 생성하는데, 각각의 키는 이론적으로 다음과 같은 용도로 사용됩니다.

Public Key : 누구에게나 공개될 수 있으며 메세지를 보내는 발신자는 공개키를 통해 정보를 암호화한다.

Private Key : 수신자는 비밀키를 암호화된 메세지를 복호화 하는데 사용한다. 외부에 노출되지 않도록 안전하게 보관해야 한다.

이와 같이 RSA를 이용한 공개키 암호화 방식은 비밀키(Private Key)를 외부에 노출할 위험이 없어 기존의 대칭키 암호화 방식의 문제를 해결할 수 있습니다.

SSH 설정

각 서버의 IP address를 알아야 합니다. ifconfig를 이용하여 각 Host의 ip address를 파악합니다.

  • Hadoop01 : 192.168.64.128
  • Hadoop02 : 192.168.64.129
  • Hadoop03 : 192.168.64.130
  • Hadoop04 : 192.168.64.131

각 서버마다 /etc/hosts 파일을 편집해서 아래의 내용을 넣어줍니다.

192.168.64.128 namenode
192.168.64.129 datanode01
192.168.64.130 datanode02
192.168.64.131 datanode03

각 서버마다 /etc/hostname 파일을 편집해서 각 host의 이름을 입력합니다.

  • 192.168.64.128 => namenode
  • 192.168.64.129 => datanode01
  • 192.168.64.130 => datanode02
  • 192.168.64.131 => datanode03

수정이 끝났으면 재부팅을 해줍니다.(서비스를 다시 시작해도 됩니다.)

Hadoop은 클러스터간에 내부 통신에 SSH(Secure Shell) 프로토콜을 이용합니다. 따라서 패스워드 인증과정없이 SSH 통신을 하기 위해 SSH 공개키를 설정하고 모든 서버에 통합 공개키를 복사하여 통신을 합니다.

각 서버에서 인증키를 생성합니다.

ssh-keygen

입력을 요구하는 부분이 있는데 그냥 enter를 입력해도 무방합니다.

대칭키 암호화 방식

모든 서버에서 이 작업을 수행하면 각 서버의 /root/.ssh/ 안에 2개의 파일이 생성됩니다.

  • id_rsa : 생성된 개인키(private key)입니다.
  • id_rsa.pub : 생성된 공개키(public key)입니다.

개인키와 공개키

먼저 namenode에서 다음의 명령을 이용해 authorized_keys 파일을 생성합니다. namenode의 공개키를 authorized_keys 파일에 저장합니다.

cp id_rsa.pub authorized_keys

namenode의 .ssh 폴더안에 authorized_keys 파일이 생성됩니다.

authorized_keys

ssh-copy-id 유틸리티를 이용해서 datanode01 ~ datanode03에서 각자의 공개키를 namenode에 복사합니다.

ssh-copy-id root@namenode (모든 datanode에서 각각 수행해야 합니다.)

key 복사

각 datanode(01~03)에서 namenode로 공개키를 복사하면 namenode의 authorized_keys의 내용은 아래 그림처럼 저장되게 됩니다.

결과 authorized_keys

이제 통합된 key를 각각의 서버에 보내주면 됩니다.

scp -rp authorized_keys root@datanode01:~/.ssh/authorized_keys

scp -rp authorized_keys root@datanode02:~/.ssh/authorized_keys

scp -rp authorized_keys root@datanode03:~/.ssh/authorized_keys

다음의 명령을 이용해서 각 서버에서 다른 서버로 SSH Connection을 설정합니다. 정상적으로 Connection이 설정되면 패스워드 없이 ssh 호출이 정상적으로 이루어집니다.

ssh datanode01 date

방화벽 설정(방화벽 shutdown)

CentOS의 경우 OS를 처음 설치했을 때 기본 포트를 제외한 모든 포트를 방화벽에서 막고 있습니다.

Hadoop은 내부 데몬(NameNode, SecondaryNameNode, DataNode, JobTracker, TaskTracker)간에 통신을 위해 다양한 포트를 사용합니다. 만약 Hadoop이 사용하는 포트가 막혀 있다면, Hadoop은 구동했더라도 HDFS 파일 제어나 MapReduce Job이 정상적으로 실행되지 않게 됩니다.

이러한 현상을 피하기 위해서는 사용되는 Hadoop의 포트를 열어줘야 합니다. (이 부분은 Hadoop의 공식문서를 참조합니다.)

포트를 하나하나 일일이 변경하고 열어주는 일은 상당히 번거로운 작업이고 대부분은 Hadoop이 사내 내부망으로만 설치가 되어 있기 때문에 다음과 같이 방화벽을 내려주시는 게 가장 간단한 방법입니다.

systemctl stop firewalld

systemctl disable firewalld

Hadoop 다운로드 및 설치

Apache site에서 Hadoop 2.9.2 버전을 다운로드 합니다.

다운로드 한 binary 압축 파일을 CentOS로 가져옵니다. 이 부분은 namenode에서만 작업합니다.

tar xvf hadoop-2.9.2.tar.gz

mv hadoop-2.9.2 /usr/local/hadoop

Hadoop에서 사용할 디렉토리를 생성합니다. 디렉토리 생성은 모든 서버에서 수행해야 합니다.

mkdir -p /home/hadoop/hdfs/data

mkdir -p /home/hadoop/hdfs/temp

mkdir -p /home/hadoop/hdfs/name

이제 Hadoop의 환경설정을 진행합니다. 이 환경설정은 namenode에서만 진행하고 설정이 다 끝나면 다른 서버로 배포하게 됩니다.

Hadoop의 환경설정 파일은 /usr/local/hadoop/etc/hadoop/ 안에 위치하고 있습니다.

설정이 끝난 환경설정파일은 여기에서 다운로드 받을 수 있습니다.

hadoop-env.sh 파일을 vi로 열어서 JAVA_HOME에 대한 환경변수를 우리 환경에 맞게 수정합니다.

hadoop-env.sh 설정

hadoop-env.sh 파일의 상단에 다음 내용을 추가하여 아래 그림과 같이 환경변수를 설정합니다.

export HADOOP_HOME_WARN_SUPPRESS=1
export HADOOP_HOME=/usr/local/hadoop
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export YARN_CONF_DIR=$HADOOP_HOME/etc/hadoop

hadoop-env.sh 환경변수 설정

yarn-env.sh 파일의 상단에도 다음 내용을 추가합니다.

export HADOOP_HOME=/usr/local/hadoop
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export YARN_CONF_DIR=$HADOOP_HOME/etc/hadoop

masters 파일이 존재하지 않는데 vi로 만들어서 secondary namenode를 지정해줍니다.

datanode01

slaves 파일을 vi로 열어서 기존 내용을 삭제하고 datanode 들의 서버를 지정해줍니다. 다음의 내용을 입력합니다.

datanode01
datanode02
datanode03

core-site.xml 파일을 열어 property 내용을 적어줍니다.(hive사용을 위한 설정도 들어가 있습니다.)

<configuration>
        <property>
                <name>fs.defaultFS</name>
                <value>hdfs://namenode:9000</value>
        </property>
        <property>
                <name>hadoop.tmp.dir</name>
                <value>/home/hadoop/hdfs/temp</value>
        </property>
        <property>
                <name>hadoop.proxyuser.hive.hosts</name>
                <value>*</value>
        </property>
        <property>
                <name>hadoop.proxyuser.hive.groups</name>
                <value>*</value>
        </property>
        <property>
                <name>hadoop.proxyuser.root.hosts</name>
                <value>*</value>
        </property>
        <property>
                <name>hadoop.proxyuser.root.groups</name>
                <value>*</value>
        </property>
</configuration>

hdfs-site.xml 파일을 열어 다음과 같이 수정합니다.

<configuration>
        <property>
                <name>dfs.replication</name>
                <value>3</value>
        </property>
        <property>
                <name>dfs.namenode.name.dir</name>
                <value>/home/hadoop/hdfs/name</value>
        </property>
        <property>
                <name>dfs.datanode.name.dir</name>
                <value>/home/hadoop/hdfs/data</value>
        </property>
        <property>
                <name>dfs.webhdfs.enabled</name>
                <value>false</value>
        </property>
        <property>
                <name>dfs.namenode.http.address</name>
                <value>namenode:50070</value>
        </property>
        <property>
                <name>dfs.secondary.http.address</name>
                <value>datanode01:50090</value>
        </property>
</configuration>

mapred-site.xml 파일을 수정합니다. 기본적으로는 mapred-site.xml 파일은 없습니다. mapred-site.xml.template을 복사하여 만든 후 수정합니다.

<configuration>
        <property>
                <name>mapreduce.framework.name</name>
                <value>yarn</value>
        </property>
        <property>
                <name>mapred.job.tracker</name>
                <value>namenode:54311</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.resourcemanager.hostname</name>
                <value>namenode</value>
        </property>
        <property>
                <name>yarn.resoucemanager.resource-tracker.address</name>
                <value>namenode:8025</value>
        </property>
        <property>
                <name>yarn.resourcemanager.scheduler.address</name>
                <value>namenode:8030</value>
        </property>
        <property>
                <name>yarn.resourcemanager.address</name>
                <value>namenode:8040</value>
        </property>
</configuration>

파일 수정이 끝났으면 Slave 들에게 설정된 Hadoop을 배포합니다.

cd /usr/local

scp -r hadoop root@datanode01:/usr/local

scp -r hadoop root@datanode02:/usr/local

scp -r hadoop root@datanode03:/usr/local

/etc/profile 파일을 각 Slave 들에게 배포합니다.

scp /etc/profile root@datanode01:/etc/profile

scp /etc/profile root@datanode02:/etc/profile

scp /etc/profile root@datanode03:/etc/profile

복사가 모두 끝나면 각 서버에서 Java와 Hadoop이 정상적으로 동작하는지 확인합니다.

java -version

hadoop version

Hadoop 실행

환경 설정 및 설치가 완료되었으니 이제 hadoop 서버를 실행합니다. 우선 실행전에 포맷을 진행합니다. 이 작업은 namenode에서만 진행합니다.

hadoop namenode -format

포맷이 끝났으면 ~$HADOOP_HOME/sbin/start-all.sh 으로 실행합니다. (중지는 stop-all.sh)

namenode에서만 실행 하면 slaves에 등록되어 있는 모든 datanode의 데몬들도 namenode에서 구동시키므로 구동 후 각 서버에서 jps로 데몬 구동을 확인 하면 됩니다.

hadoop 실헹

정상적으로 실행되었는지 확인하기 위해 각 서버에서 jps(JVM 위에서 돌아가는 프로세스 확인) 명령을 수행합니다.

jps

master에는 ResourceManager가 구동 되어야 하고 slave들에는 NodeManager가 구동 되어야 클러스터가 정상 동작합니다.

다음의 URL을 이용하면 HDFS를 확인할 수 있습니다. Live Nodes : 3 ( 3개의 slave 존재 확인 )

localhost:50070

hadoop 실헹상태 확인

간단한 명령어를 이용해 파일 시스템을 다룰 수 있습니다.

  • 디렉토리 생성

hadoop fs -mkdir /test

  • 파일 업로드

hadoop fs -put (업로드 할 파일) (타겟 디렉토리)

  • 디렉토리 리스트 출력

hadoop fs -ls (타겟 디렉토리)

참고로 Hadoop이 비정상 종료 시 safe 모드로 전환되는데 이 경우 에러가 발생합니다. 이런 경우 다음의 명령을 이용해서 Safe mode를 OFF해야 합니다.

hdfs dfsadmin -safemode leave

현재 모드가 Safe 모드인지 확인 하는 방법은 다음의 명령을 이용하면 됩니다.

hdfs dfsadmin -safemode get

마지막으로 파일시스템을 검사할 수 있는데 다음의 명령을 이용하면 됩니다.

hdfs fsck /


Hadoop Example

Hadoop File 처리

가장 기본적인 예제인 File Read Write를 통해서 Hadoop 사용법을 알아보겠습니다.

기본적으로 Hadoop 프로그래밍은 Maven 빌드를 사용하는데 이번에는 Maven을 사용하지 않고 직접 jar file을 다운로드 받아서 처리하겠습니다. 필요한 jar파일은 hadoop-core jar파일입니다. 다운받기 위해서는 Maven Repository에 가야합니다.

Maven Repository에 가서 검색창에 hadoop core를 입력하고 검색하면 hadoop-core-1.2.1.jar 파일을 다운로드 받을 수 있습니다. 이 파일을 우리 Eclipse project의 적당한 곳에 복사한 후 Build Path 설정에서 라이브러리로 등록합니다.

다음의 코드를 작성합니다.

public class Exam01_SimpleFileReadWrite {

	public static void main(String[] args) {

            if (args.length != 2) {
                System.out.println("Usage : Exam01_SimpleFileReadWrite <filename> <contents>");
                System.out.println();
            }
            Configuration conf = new Configuration();
            // Configuration class는 Hadoop의 설정값을 가져온다. 
            // Hadoop xml 설정값들을 확인.
            try {
                FileSystem hdfs = FileSystem.get(conf);
                // FileSystem은 Hadoop의 FileSystem. 
                // Hadoop의 설정값을 보고 파일시스템을 가져온다.
                Path path = new Path(args[0]);
                if (hdfs.exists(path)) {
                    hdfs.delete(path, true);
                }
                // 파일 시스템을 가져온후 출력 스트림을 열어서 args[0]이름으로 파일을 생성한다. 
                // 그후 args[1]을 파일 내용으로 저장한다.
                // 그 후 다시 입력 스트림을 열어서 HDFS에서 해당 파일을 가져온 후 그 내용을 출력.
                FSDataOutputStream outStream = hdfs.create(path);
                outStream.writeUTF(args[1]);
                outStream.close();
    
                FSDataInputStream inputStream = hdfs.open(path);
                String inputString = inputStream.readUTF();
                inputStream.close();
                System.out.println("읽은 내용 : " + inputString);
            } catch (IOException e) {
                e.printStackTrace();
            }
	}
}

이제 우리 Project를 jar 파일로 export 시킵니다. 해당 jar파일을 yarn을 이용해서 실행하는 과정을 거쳐야 합니다. yarn은 작업을 실행해주는 모듈입니다.

yarn (실행시킬 타입) (실행시킬 파일 이름) (실행시킬 클래스경로) [-옵션]

yarn jar FileReadWriteExam.jar javaHadoop.Exam01_SimpleFileReadWrite test.txt HelloWorld

MapReduce

이번에는 Hadoop의 데이터 처리 기술인 MapReduce에 대해서 알아보겠습니다. 사실 MapReduce개념은 Hadoop의 고유개념은 아니고 데이터 처리 솔루션들은 대부분 가지고 있는 기술입니다.

MapReduce는 MapReduce 두 개의 기능으로 나뉘며 Map은 특정 데이터를 가져와서 Key와 Value의 쌍으로 만드는 일을 합니다. Reduce는 Map에서 묶은 Key와 Value을 이용해서 내가 필요한 정보로 다시 Key와 Value의 쌍으로 데이터를 조작하는 것을 의미합니다.

여기서는 WordCount라는 아주 유명한 입문 예제를 가지고 MapReduce를 이해해 보도록 하겠습니다.

MapReduce작업을 위해서는 반드시 3가지의 클래스가 필요합니다. 이는 각각 MapperReducer 그리고 Driver입니다. Driver는 자바의 entry point인 main method가 포함된 class를 지칭합니다.

먼저 Mapper class를 살펴보겠습니다.

class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    @Override
    protected void map(LongWritable key, Text value, 
    		Mapper<LongWritable, Text, Text, IntWritable>.Context context)
            throws IOException, InterruptedException {
        StringTokenizer itr = new StringTokenizer(value.toString());
        while (itr.hasMoreTokens()) {
            word.set(itr.nextToken());
            context.write(word, one);
        }
    }
}

Mapper class는 4개의 인자를 받습니다.

MapReduce에서의 인자는 일반 long형이나 int형, String형을 쓰지 않습니다. 대신 long이나 int형은 각각 LongWritable, IntWritable이라는 Hadoop 전용 자료형을 사용합니다. 그리고 String은 Text로 사용합니다.

Mapper class의 인자는 순서대로 Input Key, Input Value, Output Key, Output Value를 의미합니다. Input으로 들어오는것 역시 Key와 Value쌍이고 Output 역시 Key와 Value쌍 입니다.

일반적으로 Input의 경우 Key는 LongWritable이고 Value는 Text로 고정되는 경향이 있습니다. 원래 Input에는 Key값이 있을리가 없습니다. 그런데 값이 들어올때 Hadoop은 개행 단위로 끊어서 값을 받아오고 그 순서대로 번호를 매기게 됩니다. 그리고 그 번호의 값이 Key가 됩니다. 따라서 Key값은 숫자가 되고 빅데이터 처리에서 데이터량이 많을 수 있으므로 LongWritable로 사용하는 것입니다. 받는 값을 Text로 하는 이유는 가공의 편의성 때문입니다.

따라서 Input의 경우 Key는 LongWritable이되고 Value는 Text가 됩니다.

반면에 Output의 경우는 Key와 Value는 임의로 지정할 수 있습니다.위의 예제에서는 StringTokenizer로 공백단위로 들어온 텍스트를 끊어내고 그 값을 Output Key로 정하고 그 Value는 1로 고정해서 출력합니다.

Reducer로 Key,Value 쌍을 보내는 작업은 context.write이 담당합니다.

정리하자면, <들어온순서, 라인단위 텍스트>로 Input값이 들어오게 되고 반대로 Output은 <끊은 단어,1>값을 출력하게 됩니다.

이번에는 Reducer class를 살펴보겠습니다.

class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    private IntWritable result = new IntWritable();

    @Override
    protected void reduce(Text key, Iterable<IntWritable> values,
                          Reducer<Text, IntWritable, Text, IntWritable>.Context context) 
                            throws IOException, InterruptedException {
        int sum = 0;
        for (IntWritable val : values) {
            sum += val.get();
        }
        result.set(sum);
        context.write(key, result);
    }
}

Reduce 작업은 사실 Map 로직과 거의 동일합니다. Reducer는 Mapper의 Output을 가지고 작업을 하게 되며 Reducer도 총 4개의 인자를 가지는데 Mapper와 동일합니다. 즉, Input Key, Input Value, Output Key, Output Value 입니다. 당연히 Mapper의 Output 인자와 Reducer의 Input 인자는 같아야합니다.

한가지 특이한점은 Reducer의 Value는 Mapper와는 다르게 복수형으로 일종의 컬렉션을 받게된다는 것입니다. 그 이유는 Key에 중복이 존재할 수 있기 때문입니다.

Reducer 작업이 Mapper와 다른점이 있다면 MApper는 순서대로 값을 받으므로 Input Key는 중복될 수 없습니다. 그러나 Reducer는 Mapper의 Output을 받게되는데 Mapper의 Output Key는 중복이 안된다는 제약은 없습니다. 따라서 Reducer의 Input Key는 중복될 수 있습니다.

Reducer의 실질적은 역활은 중복된 키들을 어떻게 처리하느냐 입니다. Mapper는 의미가 같다고 생각되는 데이터를 같은 Key로 만들어서 출력합니다. 그러면 Reducer에서는 그 동일한 Key를 묶어서 처리를 한다고 보면 됩니다.

위의 예제에서 Value들은 모두 1로 고정되어있습니다. 같은 Key의 경우에 계속해서 더하게 됩니다. 즉, 들어가는 데이터에 hello라는 단어가 10개가 들어왔다고 가정해 보면 <hello,1>이라는 Output이 Mapper에 의해 생성될 것이고 Reducer에서는 저 hello라는 Key가 10개가 있으므로 10번 for문을 돌면서 합을 계산해 10이라는 값을 계산하게 됩니다.

마지막으로 Driver class를 살펴보겠습니다.

public class Exam02_WordCountMapReduce {

	public static void main(String[] args) throws Exception {

        Configuration conf = new Configuration();
        if (args.length != 2) {
            System.out.println("Usage: Exam02_WordCountMapReduce <input> <output>");
            System.exit(2);
            ;
        }
        Job job = new Job(conf, "WordCount");
        job.setJarByClass(Exam02_WordCountMapReduce.class);
        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);

        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        job.waitForCompletion(true);
    }	
}

Driver로 Mapper와 Reducer를 등록하고 실행하면 됩니다.

이제 실행을 하기 위해서 샘플로 사용할 입력 파일을 하나 생성합니다. (wow_wordcount.txt)

생성한 txt 파일을 Hadoop 파일 시스템에 저장합니다.

hdfs dfs -put wow_wordcount.txt

다음의 명령을 이용해서 파일 시스템에 정상적으로 저장되었는지를 확인합니다.

hdfs dfs -ls

작성된 프로그램(Java Project)을 jar파일로 생성한 후 yarn으로 실행시킵니다. output 결과는 텍스트가 아니라 폴더로 나오기에 확장자를 붙혀줄 필요는 없습니다.

yarn jar wordCounterExam.jar javaHadoop.Exam02_WordCountMapReduce wow_wordcount.txt output

hdfs dfs -ls output

output 디렉토리 안에 파일은 part-r-00000로 저장됩니다. 이 파일은 텍스트 파일이므로 cat으로 읽을 수 있습니다. 다음의 명령을 이용하여 결과를 확인합니다.

hdfs dfs -cat output/part-r-00000


Hive 설치 및 활용

현재 서비스 로그 및 사용자 생성 데이터는 점점 크고 빠르게 늘어나고 있습니다. 우리가 설치한 Hadoop은 이런 매우 큰 데이터를 저장하고 처리하기 적합한 가장 인기 있는 오픈 소스입니다.

하지만 데이터 분석을 위해 MapReduce를 직접 구현하기에는 코드가 매우 어려운 형태이며, 따라서 시스템을 구현하기 위해서는 그만한 개발 능력이 되는 개발자가 있어야 하는 등 실제 시스템을 도입해서 사용하는데는 어려움도 있는게 사실입니다.

그런 이유로 MapReduce 처리를 쉽게 해주기 위한 대안으로 Hive를 사용합니다. (다른 framework도 존재합니다.) Hive는 RDB의 SQL문을 작성해 본 개발자라면 상당히 익숙한 형태로 데이터 분석 작업을 진행할 수 있습니다.

정리하자면, Hive는 Hadoop 상의 오픈소스 Data Warehouse 솔루션입니다. DW(Data Warehouse)는 리포팅 및 분석을 위한 Database라고 생각하면 됩니다.

간단하게 Hive의 동작방법에 대해 알아보면 다음과 같습니다.

Hive는 Hadoop상에서 동작합니다. 당연히 데이터 또한 HDFS에 저장되어 있습니다. Hive는 메타스토어(Metastore)라는 저장소를 만들어 Hadoop에서 처리된 메타데이터의 구조를 메타스토어에 저장합니다. 하이브는 Oracle, MySQL 등 JDBC를 지원하는 모든 데이터베이스를 이용해 메타스토어를 구축할 수 있습니다. 디폴트로 Apache Derby를 사용하지만, 일반적으로 MySQL이나 Postgres를 많이 사용합니다.

Hadoop Hive 구조

  1. 사용자가 제출한 SQL문을 Driver가 Compiler에 요청하여 MetaStore의 정보를 이용해 처리에 적합한 형태로 컴파일
  2. 컴파일된 SQL을 실행엔진으로 실행
  3. 리소스 매니저가 클러스터의 자원을 적절히 활용하여 실행
  4. 실행 중 사용하는 원천데이터는 HDFS등의 저장장치를 이용
  5. 실행결과를 사용자에게 반환

MySQL 설치

MySQL은 Hadoop namenode에 설치하겠습니다.

먼저 wget을 이용해서 MySQL을 설치합니다.

wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm

rpm -ivh mysql-community-release-el7-5.noarch.rpm

yum install mysql-server

systemctl start mysqld

systemctl enable mysqld

systemctl status mysqld

mysql_secure_installation 명령으로 기본적인 보안 설정을 합니다. 몇가지 설정을 수행합니다.

root 권한으로 mysql console에 진입합니다.

mysql -u root -p

일단 mysql 버전부터 확인하고 진행하겠습니다.

SHOW VARIABLES LIKE “%version%”;

MySQL Version 확인

이제 사용자 계정을 생성합니다.

CREATE USER hive IDENTIFIED BY “hive”;

CREATE USER hive@localhost IDENTIFIED BY “hive”;

이제 사용할 database를 만들고 hive 계정에 해당 database의 권한을 부여합니다.

CREATE DATABASE hivedb;

GRANT ALL PRIVILEGES ON hivedb.* TO hive;

GRANT ALL PRIVILEGES ON hivedb.* TO hive@localhost;

설정된 권한을 바로 적용하고 mysql console을 종료합니다.

FLUSH PRIVILEGES;

EXIT

참고 : MySQL 삭제

기존 설치되어 있는 MySQL 패키지를 제거하려면 다음과 같은 명령을 사용해야 합니다.

yum remove mysql mysql-server

패키지를 삭제한 후 남아있는 MySQL 디렉토리를 삭제합니다.

rm -rf /var/lib/mysql

HIVE 설치

http://hive.apache.org에서 2.3.7 버젼을 다운로드 받아 압축을 풀어줍니다.

wget http://apache.mirror.cdnetworks.com/hive/hive-2.3.7/apache-hive-2.3.7-bin.tar.gz

tar -zxvf apache-hive-2.3.7-bin.tar.gz

mv apache-hive-2.3.7-bin /usr/local/hive

/etc/profile을 vi로 열어서 아래의 내용을 추가합니다.

export HIVE_HOME=/usr/local/hive
export PATH=$HIVE_HOME/bin:$PATH

위에서 설치한 MySQL과 연동하기 위해서 MySQL JDBC Connector를 설치합니다.

wget http://www.java2s.com/Code/JarDownload/mysql/mysql-connector-java-commercial-5.1.7-bin.jar.zip

unzip mysql-connector-java-commercial-5.1.7-bin.jar.zip

cp mysql-connector-java-commercial-5.1.7-bin.jar $HIVE_HOME/lib/

다음은 사용할 HDFS 디렉토리를 생성해야 합니다. 다음의 명령을 이용하여 HDFS 디렉토리를 생성합니다. 당연히 Hadoop이 실행되고 있는 상황이어야 합니다.

hadoop fs -mkdir /tmp

hadoop fs -mkdir -p /user/hive/warehouse

hadoop fs -chmod g+w /tmp

hadoop fs -chmod g+w /user/hive/warehouse

$HIVE_HOME/conf안의 hive-env.sh.template를 hive-env.sh로 복사한 후에 HADOOP_HOME을 아래와 같이 수정합니다.

mv $HIVE_HOME/conf/hive-env.sh.template $HIVE_HOME/conf/hive-env.sh

HADOOP_HOME=/usr/local/hadoop

$HIVE_HOME/conf안에 hive-site.xml 파일을 생성하여 생성된 내용을 입력합니다. UserNamePassword는 MySQL에서 사용하게될 UserName과 Password입니다.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
        <property>
                <name>hive.metastore.local</name>
                <value>false</value>
        </property>
        <property>
                <name>hive.metastore.warehouse.dir</name>
                <value>hdfs://namenode:9000/user/hive/warehouse</value>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionURL</name>
                <value>jdbc:mysql://localhost:3306/hivedb?createDatabaseIfNotExist=true</value>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionUserName</name>
                <value>hive</value>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionPassword</name>
                <value>hive</value>
        </property>
        <property>
                <name>hive.metastore.schema.verification</name>
                <value>false</value>
        </property>
        <property>
                <name>hive.server2.thrift.port</name>
                <value>10000</value>
                <description>TCP port number to listen on, default 10000</description>
        </property>
        <property>
                <name>hive.server2.enable.doAs</name>
                <value>false</value>
        </property>
        <property>
                <name>hive.server2.authentication</name>
                <value>NONE</value>
        </property>
        <property>
                <name>hive.metastore.sasl.enabled</name>
                <value>false</value>
                <description>If true, the metastore Thrift interface will be secured with SASL.
                        Clients must authenticate with Kerberos.</description>
        </property>
        <property>
                <name>hive.server2.enable.impersonation</name>
                <description>Enable user impersonation for HiveServer2</description>
                <value>true</value>
        </property>

        <property>
                <name>hive.server2.thrift.bind.host</name>
                <value>192.168.64.128</value>
        </property>

        <property>
                <name>hive.support.concurrency</name>
                <value>true</value>
        </property>

        <property>
                <name>hive.enforce.bucketing</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>2</value>
        </property>
</configuration>

HIVE 실행

Hive 2.1부터는 초기화 단계로 아래의 코드를 실행해야 합니다. 실행한 뒤 schemaTool completed가 출력되면 됩니다.

schematool -dbType mysql -initSchema

HIVE 초기화

초기화가 정상적으로 진행되면 hive 명령을 실행합니다.

HIVE 실행

정상적으로 동작하는지 확인하기 위해 Hive QL을 이용하여 Table을 생성하고 조회합니다.

CREATE TABLE mytbl(seq INT, contents STRING);

SELECT * FROM mysql

HIVE CREATE Table

MySQL Server에 접속해서 생성된 Table이 존재하는지 확인합니다.

show databases;

show tables;

SELECT * FROM hivedb.TBLS;

HIVE java 연동

먼저 Host PC의 Eclipse에서 작성된 Java 프로그램이 VMware로 생성한 Hadoop01 가상머신에 내부 IP를 이용하여 접속이 가능하도록 VMware의 Edit > Virtual Network Editor를 선택합니다.

설정을 바꾸기 위해 하단의 change settings를 클릭합니다.

아래의 그림과 같이 VMnet8을 선택한 후 connect a host virtual adapter to this network 체크박스를 체크합니다.

네트워크 설정

Host PC의 네트워크 설정을 살펴보면 다음과 같이 표현됩니다.

네트워크 설정

자바 프로그램에서 Hive에 접근할 수 있게 Hive를 기동합니다.

hiveserver2

Host PC의 Eclipse에서 Maven Project를 생성합니다.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>test.bbb</groupId>
  <artifactId>SampleTest</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>SampleTest</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <version>0.12.0</version>
	</dependency>
	<dependency>
            <groupId>jdk.tools</groupId>
            <artifactId>jdk.tools</artifactId>
            <version>1.8.0_221</version>	
            <scope>system</scope>
            <systemPath>C:/Program Files/Java/jdk1.8.0_221/lib/tools.jar</systemPath>	
	</dependency>
	<dependency>                                                                                                                                       
    	<groupId>org.apache.hadoop</groupId>                                                                                                           
    	<artifactId>hadoop-common</artifactId>                                                                                                         
    	<version>3.2.0</version>                                                                                            
	</dependency>  
  </dependencies>
</project> 

일반적은 JDBC 코드를 작성합니다.

public class App {
	public static void main(String[] args) {
        Connection conn = null;
        ResultSet rs = null;
       
        try {           
            String driver = "org.apache.hive.jdbc.HiveDriver";
            Class.forName(driver);
           
            String url = "jdbc:hive2://192.168.64.128:10000/hivedb";
            String id = "hive";
            String pw = "hive";
           
            conn = DriverManager.getConnection(url, id, pw);
           
            String sql = "SELECT count(*) FROM mytbl";
            Statement stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
           
            while(rs.next()){
                int col = rs.getInt(1);                       
                System.out.println( "결과 : " + col);
            }
           
            rs.close();
            conn.close();
           
        } catch(Exception ex){
            ex.printStackTrace();
        } finally {
            try{
                if( rs != null ){
                    rs.close();               
                }
                if( conn != null ){
                    conn.close();               
                }                
            } catch(Exception ex){
                rs = null;
                conn = null;
            }
        }
    }
}

End.