hive 쿼리를 실행 중에 예약어를 쓰면 에러가 발생할 수 있다. 



FAILED: ParseException line 1:85 Failed to recognize predicate 'to'. Failed rule: 'identifier' in table or column identifier



이럴 때는 두 가지 방법으로 문제를 해결할 수 있다. 


1번째 방법이다. 


SET hive.support.sql11.reserved.keywords=false;

select * from src.google_plus_log where date_id='2037-02-22' and to='365600561231231123121212'


2번째 방법은 back quote를 사용한다.


select * from src.google_plus_log where date_id='2037-02-22' and `to`='365600561231231123121212'


Posted by 김용환 '김용환'



hadoop ls는 명령어가 많지 않다. 


d h R 밖에 없다. 


Usage: hadoop fs [generic options] -ls [-d] [-h] [-R] [<path> ...]



그래서 먼가 후처리를 하고 싶다면, 파이프라인을 활용해야 한다.


예를 들어, 특정 디렉토리에 최근에 만들어진 파일을 얻고 싶다면 다음과 같이 모든 파일을 출력하게 한 후, 시간으로 리버스한 후, 마지막 하나를 읽어오면 된다. 


이 명령어로 검증해보고..


$ hadoop fs -ls -R  /google/app-store-log/  | sort -k 6 | tail -n 1



아래 명령어를 쓰면 최근에 생성된 파일을 찾을 수 있다.


hadoop fs -ls -R /google/app-store-log/  | sort -k 6 | tail -n 1 | awk '{print $8'}



특정 디렉토리의 최신 파일을 복사하려면, 다음과 같이 하면 된다. 



hdfs dfs -get `hadoop fs -ls -R  /google/app-store-log/ | sort -k 6 | tail -n 1 | awk '{print $8'}` /tmp/google-spark-job.jar


Posted by 김용환 '김용환'

hadoop client 설치 URL

hadoop 2016.10.24 19:11



cloudera 5.5.1의 hadoop 2.6.0 버전을 설치하고 싶다면, 아래 싸이트에 접속해서

hadoop-2.6.0+cdh5.5.1+924-1.cdh5.5.1.p0.15.el6.x86_64.rpm를 다운로드한 후 설치한다. 



https://archive.cloudera.com/cdh5/redhat/6/x86_64/cdh/5.5.1/RPMS/x86_64/ 





막상 설치하려면, 아래와 같은 에러가 발생한다. 



경고: hadoop-2.6.0+cdh5.5.1+924-1.cdh5.5.1.p0.15.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID e8f86acd: NOKEY

오류: Failed dependencies:

bigtop-utils >= 0.7 is needed by hadoop-2.6.0+cdh5.5.1+924-1.cdh5.5.1.p0.15.el6.x86_64

zookeeper >= 3.4.0 is needed by hadoop-2.6.0+cdh5.5.1+924-1.cdh5.5.1.p0.15.el6.x86_64

avro-libs is needed by hadoop-2.6.0+cdh5.5.1+924-1.cdh5.5.1.p0.15.el6.x86_64

parquet is needed by hadoop-2.6.0+cdh5.5.1+924-1.cdh5.5.1.p0.15.el6.x86_64



따라서, RPM을 따라하면 엄청 쉽지 않은 작업이 계속 연결되어 있다 .


한번 제대로 설치한 후, 꼭 tar.gz으로 묶어 들고 공유 디렉토리에 잘 저장해 두어야 한다.. 


Posted by 김용환 '김용환'


hive 버전을 알려면, 다음과 같이 실행한다.



$ hive --version


Hive 1.1.0-cdh5.5.1



또는 libary 명으로 확인한다.


$ ls -al /usr/lib/hive/lib/hive*






hadoop 버전을 알려면, 다음과 같이 실행한다.



$ hadoop version


Hadoop 2.6.0-cdh5.5.1







Posted by 김용환 '김용환'


다음 그림은 파티션 범위를 이해하게 하는 그림으로서 전체 윈도우 표현식이다.





* current row : 현재 로우


* X PRECEDING 또는 Y FOLLOWING : 현재 로우(currow row)의 앞/뒤로 N 개의 로우를 의미한다.


* UNBOUNDED PRECEDING : 시작 지점을 알리며, 해당 윈도우는 파티션의 1 번째 로우이다.


* UNBOUNDED FOLLOWING : 마지막 지점을 알린다. 해당 윈도우는 파티션의 마지막 로우이다.


UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING: 테이블의 모든 로우를 의미하며, 1 번째와 마지막 로우를 각각 가르킨다.


* BETWEEN … AND : 윈도우의 시작 지점과 마지막 지점을 명세하기 위해 BETWEEN...AND 절을 사용한다. AND 앞의 표현식은 시작 지점을 정의하고, AND 뒤의 표현식은 마지막 지점을 정의한다. ROWS N PRECEDING 또는 ROWS UNBOUNDED PRECEDING와 같이 BETWEEN...AND 절을 생략한다면, 하이브는 기본적으로 윈도우의 처음 또는 N 번째 앞 부분을 시작 지점으로, 현재 로우를 마지막 지점으로 간주한다.



Posted by 김용환 '김용환'




https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy



하이브에서 사용되는 정렬 키워드를 소개한다.


* ORDER BY (ASC|DESC): RDMBS의 ORDER BY 문과 비슷하다. ORDER BY 문을 실행 시, 하나의 리듀서만 사용해 전역 정렬을 수행하면, 리턴 시간이 더 소요된다. ORDER BY 뒤에 LIMIT 사용하는 것을 강력 추천한다. 그래서, hive.mapred.mode = strict (hive.mapred.mode= nonstrict은 기본값이다.)로 설정하고 LIMIT을 명세하지 않으면, 에러가 발생한다. 



jdbc:hive2://> SELECT name FROM employee ORDER BY NAME DESC;

+----------+

|   name   |

+----------+

| Will     |

| Shelley  |

| Michael  |

| Lucy     |

+----------+



* SORT BY (ASC|DESC): 어떤 레코드의 컬럼으로 정렬할지 가리킨다. 데이터를 리듀서에 보내기 전에 정렬을 완료한다는 것을 의미한다. mapred.reduce.tasks=1을 설정하지 않는다면, SORT BY 문은 전역으로 정렬을 수행하지 않고, 각 리듀서에서 내부적으로 정렬된 데이터인지 확인한다. 이 경우에 ORDER BY 결과와 동일하다. 


--2 개의 리듀서를 사용하면 리듀서마다 정렬(sorting)하기 때문에 정렬 결과가 다르다.

jdbc:hive2://> SET mapred.reduce.tasks = 2;

No rows affected (0.001 seconds)


jdbc:hive2://> SELECT name FROM employee SORT BY NAME DESC;

+----------+

|   name   |

+----------+

| Shelley  |

| Michael  |

| Lucy     |

| Will     |

+----------+

4 rows selected (54.386 seconds)


--리듀서 한 개만 사용하면 order by 와 동일한 효과를 제공한다.

jdbc:hive2://> SET mapred.reduce.tasks = 1;

No rows affected (0.002 seconds)


jdbc:hive2://> SELECT name FROM employee SORT BY NAME DESC;

+----------+

|   name   |

+----------+

| Will     |

| Shelley  |

| Michael  |

| Lucy     |

+----------+

4 rows selected (46.03 seconds)



* DISTRIBUTE BY:  컬럼값이 일치하는 로우는 동일한 리듀서로 파티션 된다. 하나의 리듀서만 사용하면, 리듀스는 정렬된 입력을 보장하지 않는다. 매퍼 결과를 분배하기 위해 어느 리듀서로 결정할지 여부의 관점에서 보면, DISTRIBUTE BY는 RDBMS의 GROUP BY와 비슷하다. SORT BY를 사용할 때, SORT BY 앞에 DISTRIBUTE BY를 명세해야 한다. 그리고, 분배하기 위해 사용된 컬럼은 SELECT 뒤에 컬럼 이름이 나타나야 한다. 



- SQL의 GROUP BY와 같은 형태이기 때문에 select 뒤에 컬럼 이름이 나와야 한다.

jdbc:hive2://> SELECT name 

. . . . . . .> FROM employee_hr DISTRIBUTE BY employee_id; 

Error: Error while compiling statement: FAILED: SemanticException [Error 10004]: Line 1:44 Invalid table alias or column reference 'employee_id': (possible column names are: name) (state=42000,code=10004)


jdbc:hive2://> SELECT name, employee_id 

. . . . . . .> FROM employee_hr DISTRIBUTE BY employee_id; 

+----------+--------------+

|   name   | employee_id  |

+----------+--------------+

| Lucy     | 103          |

| Steven   | 102          |

| Will     | 101          |

| Michael  | 100          |

+----------+--------------+

4 rows selected (38.92 seconds)


--SORT BY로 사용하기 

jdbc:hive2://> SELECT name, employee_id  

. . . . . . .> FROM employee_hr 

. . . . . . .> DISTRIBUTE BY employee_id SORT BY name; 

+----------+--------------+

|   name   | employee_id  |

+----------+--------------+

| Lucy     | 103          |

| Michael  | 100          |

| Steven   | 102          |

| Will     | 101          |

+----------+--------------+

4 rows selected (38.01 seconds)



* CLUSTER BY: 동일한 그룹의 컬럼에 대해 DISTRIBUTE BY와 SORT BY 명령을 동시에 수행하는 명령어다. 그리고 내부적으로 각 리듀서에서 정렬된다. CLUSTER BY 문은 아직 ASC 또는 DESC를 지원하지 않는다. 전역으로 정렬되는 ORDER BY와 비교해, CLUSTER BY 명령은 각 분배된 그룹에서 정렬이 이루어진다. 전역 정렬을 실행할 때 사용할 수 있는 모든 리듀서를 작동시키려면, CLUSTER BY를 먼저 사용하고 뒤에 ORDER BY를 사용한다. 



jdbc:hive2://> SELECT name, employee_id 

. . . . . . .> FROM employee_hr CLUSTER BY name;  

+----------+--------------+

|   name   | employee_id  |

+----------+--------------+

| Lucy     | 103          |

| Michael  | 100          |

| Steven   | 102          |

| Will     | 101          |

+----------+--------------+

4 rows selected (39.791 seconds)



Posted by 김용환 '김용환'

[hive] collect_set

hadoop 2016.04.30 00:49




SELECT문에서 GROUP BY 컬럼이 아닌 다른 컬럼을 사용해야 한다면, 

GROUP BY 절에 해당 컬럼을 사용하지 않고, 

collect_set라는 분석 함수를 사용한다. 


collect_set 함수는 중복 엘리먼트를 제거하는 객체 집합을 리턴한다.



예)


SELECT

    sex, COLLECT_LIST(sex), count(*)

FROM

    member

WHERE

    id > 1

GROUP BY

    sex;




Posted by 김용환 '김용환'



hadoop의 getmerge 명령어의 결과를 hadoop 파일 시스템에 저장하는 줄 알았는데, 알고 보니. local이었다.  ㅠ


getmerge 명령어는 part*로 나눠진 파일을 하나로 모아 로컬 파일 시스템에 저장한다.  




http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/FileSystemShell.html#getmerge


getmerge

Usage: hadoop fs -getmerge [-nl] <src> <localdst>

Takes a source directory and a destination file as input and concatenates files in src into the destination local file. Optionally -nl can be set to enable adding a newline character (LF) at the end of each file.

Examples:

  • hadoop fs -getmerge -nl /src /opt/output.txt
  • hadoop fs -getmerge -nl /src/file1.txt /src/file2.txt /output.txt

Exit Code:

Returns 0 on success and non-zero on error.




예제>


$ hdfs dfs -ls /tmp/test/20160418

Found 6 items


/tmp/test/_SUCCESS

/tmp/test/done

/tmp/test/part-m-00000

/tmp/test/part-m-00001

/tmp/test/part-m-00002

/tmp/test/part-m-00003




$ hdfs dfs -getmerge hdfs://google-hadoop장비이름/tmp/test/20160418  /tmp/1



로컬에 하나의 파일로 저장한 것을 확인한다.

$ ls  /tmp/1

/tmp/1

Posted by 김용환 '김용환'


하이브에서 COUNT와 DISTINCT를 동시에 사용할 때, 

하이브는 mapred.reduce.tasks = 20으로 설정 리듀스 개수를 무시하고 오직 하나의 리듀서만 사용한다. 


데이터가 클 때 병목이 발생한다. 



이 방식의 해결책은 서브쿼리를 사용한다.


예시) 


* COUNT와 DISTINCT를 동시에 쓰면 하나의 리듀스에서만 실행된다.

SELECT count(distinct age)  FROM member;


* 서브 쿼리를 사용하면, 리듀스 작업을 mapred.reduce.tasks로 설정한 값으로 동작한다. DISTINCT를 사용하여 하나 이상의 리듀서를 사용하여 상대적으로 작은 양의 데이터에 COUNT를 실행한다. 따라서 리듀서 병목이 사라진다.

SELECT count(*) FROM (SELECT distinct age FROM member) a;



'hadoop' 카테고리의 다른 글

[hive] collect_set  (0) 2016.04.30
[hadoop] getmerge 명령어  (0) 2016.04.21
[hive] count와 distinct 이슈  (0) 2016.04.20
[hive] group by 이후에 order by 개수 지정하기  (0) 2016.04.19
[hive] ALTER TABLE 예시  (0) 2016.04.19
[hive] alter table 시 주의 사항  (0) 2016.04.19
Posted by 김용환 '김용환'



hive에서 count를 사용하기 위해 group by 컬럼을 적용한 후 order by 컬럼을 사용할 때 사용할 팁이다.



특정 필드를 기반으로 group by 후, count 별 역순으로 확인할 때, 

order by 뒤에 들어갈 필드는 count(*)에 대한 앨리어스를 사용하면 잘된다.


select timezone, count(*) as count from request where date=20160401

 group by timezone order by count desc limit 30




'hadoop' 카테고리의 다른 글

[hadoop] getmerge 명령어  (0) 2016.04.21
[hive] count와 distinct 이슈  (0) 2016.04.20
[hive] group by 이후에 order by 개수 지정하기  (0) 2016.04.19
[hive] ALTER TABLE 예시  (0) 2016.04.19
[hive] alter table 시 주의 사항  (0) 2016.04.19
[hive] hive.cli.print.header  (0) 2016.04.19
Posted by 김용환 '김용환'