1. RHive 튜토리얼 2 – 기본 함수
RHive 는 Hive 에 R 을 연결하고 다루는데 필요한 기본적인 함수들을 제공한다. 이
함수들을 이용하여 Hive 에 대한 connection 을 만들고 HSQL(Hive SQL)을 Hive 로
전송하고 결과값을 리턴받아 사용할 수 있다. 이 튜토리얼에서는 RHive 를 사용하는데
있어 가장 기초적이며 필수적인 함수들인 RHive basic function 에 대한 사용법을
설명한다.
RHive - basic functions
RHive 로딩하기
모든 R 패키지들을 설치한 후 사용하기 위해서는 library 함수를 이용해서 라이브러리를
로딩한다. RHive 도 동일하게 아래와 같이 실행해서 로딩한다.
library(RHive)
단, RHive 를 로딩하기 전에 HADOOP_HOME 과 HIVE_HOME 환경변수를 설정하는
것을 잊지 말아야 하며, 만약 R 을 실행하기 이전에 이 값들을 설정하지 않았다면 다음의
예제와 같이 library 를 로딩하기 전에 R 에서 임시로 설정할 수 있다.
HADOOP_HOME 은 Hadoop 이 설치된 홈 디렉토리이며 HIVE_HOME 은 Hive 가
설치된 홈 디렉토리이다.
환경변수에 관한 자세한 내용은 RHive 설치 및 설정 튜토리얼을 참조한다.
Sys.setenv(HIVE_HOME="/service/hive-‐0.7.1")
Sys.setenv(HADOOP_HOME="/service/hadoop-‐0.20.203.0")
library(RHive)
rhive.init
rhive.init 펑션은 RHive 를 초기화하는 과정이며 이 과정에서 Hive 와 R 을 연동시키기
위한 몇가지 준비작업을 진행하게된다. 만약 RHive 를 로딩하기전에 환경변수를 정확히
설정하였다면 library(RHive)를 실행하면서 자동으로 실행된다.
하지만 만약 환경변수를 설정하지 않고 library(RHive)로 RHive 를 로딩했다면 다음과
에러메세지를 볼 것이며 환경변수를 설정한 후에 rhive.init 을 명시적으로 실행해 주지
않으면 RHive 는 초기화되지 않는다.
>
rhive.connect()
2. Error
in
.jcall("java/lang/Class",
"Ljava/lang/Class;",
"forName",
cl,
:
No
running
JVM
detected.
Maybe
.jinit()
would
help.
Error
in
.jfindClass(as.character(class))
:
No
running
JVM
detected.
Maybe
.jinit()
would
help.
이런 경우에 아래와 같이 HIVE_HOME 과 HADOOP_HOME 을 지정하거나 R 을
종료한 후 환경변수를 설정하고 다시 R 을 실행하도록 한다.
Sys.setenv(HIVE_HOME="/service/hive-‐0.7.1")
Sys.setenv(HADOOP_HOME="/service/hadoop-‐0.20.203.0")
rhive.init()
또는 아래와 같이 쉘 명령어로 설정한다.
#
close
R
export
HIVE_HOME="/service/hive-‐0.7.1"
export
HADOOP_HOME="/service/hadoop-‐0.20.203.0"
#
open
R
rhive.connect
RHive 의 모든 펑션은 Hive server 에 접속을 한 후에 작동이 가능하다.
만약 RHive 의 다른 함수를 사용하기 전에 rhive.connect 함수를 사용하여
connection 을 만들지 않았다면 모든 RHive 함수들이 정상 작동하지 않을 것이며
실행할 때 다음과 같은 에러메세지를 보게 될 것이다.
Error
in
.jcast(hiveclient[[1]],
new.class
=
"org/apache/hadoop/hive/service/HiveClient",
:
cannot
cast
anything
but
Java
objects
RHive 를 이용하기 위해서 Hive server 와 연결(connection)을 만드려면 아래와
간단하게 할 수 있다.
rhive.connect()
위의 예제에서는 몇가지를 추가로 지정할 수 있다.
rhiveConnection
<-‐
rhive.connect("10.1.1.1")
3. 사용자의 Hive server 가 RHive 와 다른 서버에 설치되어 있어 원격접속을 해야 하는
경우에는 rhive.connect 함수에 인수로 IP address 를 넘겨주어 connection 을 만들 수
있다.
그리고 만약 Hadoop 과 Hive 클러스터를 여러개 구성하고 RHive 가 작동하도록 설정한
뒤 여러개의 Hive 에 번갈아가며 접속을 해 사용한다면 MySQL 과 같은 DBclient 를
사용하는 것 처럼
connection 을 return 값으로 받아 두고 RHive 함수들에 인자(argument)로 넘겨주어
connection 을 명시적으로 선택할 수 있다.
rhive.query
사용자가 Hive 를 사용해 본 경험이 있다면 Hive 가 Map/Reduce 작업과 HDFS 에 있는
데이터를 SQL 구문을 이용해서 다룬다는 것을 알고 있을 것이다.
rhive.query 는 SQL 구문을 Hive 에 넘겨주고 결과를 return 받는 기능을 수행한다.
다음과 SQL 구문을 아는 사용자라면 흔히 볼 수 있는 예제이다.
rhive.query("SELECT
*
FROM
usarrests")
위의 예제를 실행하면 usarrests 라는 이름을 가진 Hive 의 테이블의 내용을 화면에
출력(print)할 것이다.
또는 다음과 같이 return 되는 결과를 화면에 print 하지 않고 data.frame class 타입의
객체(object)에 받아두고 활용할 수 있다.
resultDF
<-‐
rhive.query("SELECT
*
FROM
usarrests")
주의할 점은 rhive.query 에서 return 하는 데이터가 RHive 가 실행되는 서버 또는
랩탑의 메모리보다 크다면 메모리 고갈로 인해 에러메세지를 출력할 것이다.
그렇기 때문에 rhive.query 로 실행하는 SQL 구문의 결과값이 사용하는 시스템의
메모리 보다 클 것으로 예상 된다면 리턴되는 값을 직접 받아서 객체에 담아서는 안된다.
이런 경우에는 먼저 임시 table 을 생성한 뒤에 다음과 같이 임시 table 에 처리한 결과를
그 테이블에 넣은 후 남은 일을 하는 것이 좋다. 이것은 Hive 뿐만 아니라 다른
데이터베이스를 이용하여 데이터를 분석하고 처리할 때 사용하는 흔한 방법이다.
임시 테이블을 만들고 결과를 저정하는 예제는 다음과 같다.
rhive.query("
CREATE
TABLE
new_usarrests
(
rowname
string,
murder
double,
assault
int,
4.
urbanpop
int,
rape
double
)")
rhive.query("INSERT
OVERWRITE
TABLE
new_usarrests
SELECT
*
FROM
usarrest")
Hive SQL 의 자세한 사용법에 대해서는 Hive 문서를 참조하기 바란다.
rhive.close
R 을 실행한 뒤 Hive 를 통해 필요한 작업을 모두 하였고 RHive 함수들을 더 이상
사용하지 않을 것이라면 rhive.close 함수를 이용하여 connection 을 닫을 수 있다.
rhive.close()
또는 다음과 같이 특정한 connection 을 지정하여 close 할 수 있다.
conn
<-‐
rhive.connect()
rhive.close(conn)
Connection 은 닫지 않아도 다른 특별한 작업을 하지 않으므로 R 을 사용하는데 부담으
주지 않는다. Connection 을 자주 맺었다 끊었다를 반복해야 하는 경우가 아니라면
명시적으로 닫지 않아도 거의 모든 경우에는 문제가 되지 않는다.
rhive.list.tables
rhive.list.tables 함수는 Hive 에 존재하는 table 의 결과를 return 한다. 이것은 Hive 나
다른 SQL 에서의 “SHOW TABLES”에 대응되는 RHive 함수이다.
rhive.list.tables()
tab_name
1
aids2
2
new_usarrests
3
usarrests
이것은 실제로 다음의 예제와 동일하다.
5. rhive.query("SHOW
TABLES")
rhive.desc.table
rhive.desc.table 펑션은 지정한 테이블의 description 을 보여 준다.
rhive.desc.table("usarrests")
col_name
data_type
comment
1
rowname
string
2
murder
double
3
assault
int
4
urbanpop
int
5
rape
double
이것은 실제로 다음과 동일하다.
rhive.query("DESC
usarrests")
rhive.load.table
rhive.load.table 함수는 Hive 에 있는 table 의 내용을 R 의 data.frame 객체로
불러온다.
df1
<-‐
rhive.load.table("usarrests")
df1
이것은 실제로 다음과 동일하다.
df1
<-‐
rhive.query("SELECT
*
FROM
usarrests")
df1
rhive.write.table
rhive.write.table 은 rhive.load.table 과 반대의 기능을 하는 함수로 data.frame 객체를
Hive 테이블로 저장해 준다.
보통 Hive 에 있는 데이터를 추가하려면 Hive 에 테이블을 먼저 생성(create)해야 한다.
6. 하지만 rhive.write.table 펑션은 자동으로 R 의 데이터프레임의 이름과
일치하는 테이블을 Hive 에 생성하고 데이터까지 모두 한번에 넣어준다.
다음 예제를 통해 확인할 수 있다.
head(UScrime)
M
So
Ed
Po1
Po2
LF
M.F
Pop
NW
U1
U2
GDP
Ineq
Prob
Time
y
1
151
1
91
58
56
510
950
33
301
108
41
394
261
0.084602
26.2011
791
2
143
0
113
103
95
583
1012
13
102
96
36
557
194
0.029599
25.2999
1635
3
142
1
89
45
44
533
969
18
219
94
33
318
250
0.083401
24.3006
578
4
136
0
121
149
141
577
994
157
80
102
39
673
167
0.015801
29.9012
1969
5
141
0
121
109
101
591
985
18
30
91
20
578
174
0.041399
21.2998
1234
6
121
0
110
118
115
547
964
25
44
84
29
689
126
0.034201
20.9995
682
rhive.write.table(UScrime)
[1]
"UScrime"
rhive.list.tables()
tab_name
1
aids2
2
new_usarrests
3
usarrests
4
uscrime
rhive.query("SELECT
*
FROM
uscrime
LIMIT
10")
rowname
m
so
ed
po1
po2
lf
mf
pop
nw
u1
u2
gdp
ineq
prob
time
1
1
151
1
91
58
56
510
950
33
301
108
41
394
261
0.084602
26.2011
7. 2
2
143
0
113
103
95
583
1012
13
102
96
36
557
194
0.029599
25.2999
3
3
142
1
89
45
44
533
969
18
219
94
33
318
250
0.083401
24.3006
4
4
136
0
121
149
141
577
994
157
80
102
39
673
167
0.015801
29.9012
5
5
141
0
121
109
101
591
985
18
30
91
20
578
174
0.041399
21.2998
6
6
121
0
110
118
115
547
964
25
44
84
29
689
126
0.034201
20.9995
7
7
127
1
111
82
79
519
982
4
139
97
38
620
168
0.042100
20.6993
8
8
131
1
109
115
109
542
969
50
179
79
35
472
206
0.040099
24.5988
9
9
157
1
90
65
62
553
955
39
286
81
28
421
239
0.071697
29.4001
10
10
140
0
118
71
68
632
1029
7
15
100
24
526
174
0.044498
19.5994
y
1
791
2
1635
3
578
4
1969
5
1234
6
682
7
963
8
1555
9
856
10
705
rhive.write.table 함수는 Hive 에 저장할 table 이 이미 존재하는 경우에는 에러
메세지를 출력하고 아무런 작업도 하지 않는다.
때문에 Hive 에 이미 있는 table 이름과 동일한 심볼을 가지는 데이터프레임을 Hive 에
저장하려고 한다면 rhive.write.table 을 사용하기 전에 지워주는 것이 필요하다.
삭제하는 것은 SQL 을 이용해서 다음과 같이 간단하게 처리할 수 있다.
8. if
(rhive.exist.table("uscrime"))
{
rhive.query("DROP
TABLE
uscrime")
}
rhive.write.table(UScrime)
RHive - alias functions
RHive 의 함수들은 S3 generic 펑션을 만들때 사용하는 이름 규정(naming rule)처럼
생겼으나 실제로는 S3 generic 이 아닌 함수들이 많다.
이것은 나중을 위한 것이며 현재로는 S3 generic 펑션과는 관련이 없다. 그리고
함수이름에 "."이 포함하면서도 generic 이 아닌 function 들로 인한 혼란을 좋아하지
않는 user 들을 위해서 이름은 다르지만 기능은 동일한 몇 개의 alias 함수들을 가지고
있다.
다음은 그 alias 함수들이다.
hiveConnect
rhive.connect 와 같다.
hiveQuery
rhive.query 와 같다.
hiveClose
hive.close 와 같다.
hiveListTables
hive.list.tables 와 같다.
hiveDescTable
hive.desc.table 과 같다.
hiveLoadTable
hive.load.table 과 같다.
9. 문의 및 연락
RHive 의 기본 함수들은 계속해서 추가될 예정이며 여러분이 이 튜토리얼을 읽는
시점에는 소개하지 않은 펑션들이 더 추가되었을 수 있다. 추가된 펑션은 R 의 도움말과
업데이트된 RHive 튜토리얼과 레퍼런스등을 통해 얻을 수 있으며 RHive 개발팀에
문의하거나 Github 사이트에서 자세한 정보를 얻을 수 있다.
e-mail: rhive@nexr.com