반응형

쿼리 수행시 다음과 같은 에러 발생

ERROR: Memory limit exceeded Instance 5240c598fffb12fd:813807e3a953de95 of plan fragment F00 of query 5240c598fffb12fd:813807e3a953de91 could not start because the backend Impala daemon is over its memory limit

 

문제해결

클라우데라 IMPALA -> 구성 -> 단일 풀 메모리 제한(default_pool_mem_limit) 변경

아마 기본 1GB로 되어 있을 것이다.

 

클러스터의 메모리에 맞게 설정해주면 된다.

반응형
반응형

Impala 쿼리를 통해 정확하진 않더라도 대략적인 distinct한 모수를 추정하고 싶을 때 사용할 수 있는 함수가 있어 간단히 확인한겸 옮겨 적어본다. 보통 추정에서 많이 사용되는 하이퍼로그로그와 비슷한 기능을 IMPALA에서도 제공하고 있다. 물론 적은 리소스를 가지고 효율적으로 추정만 하기에 정확한 모수를 알고 싶은경우는 패스하도록 한다. 차이는 대략 1.9%정도 났다. (일반적으로 3%정도 차이가 난다고 생각하면 된다.)

27억건의 데이터를 기준으로 ndv의 성능을 체크해보겠다.

+------------+
| count(uid) |
+------------+
| 2725811026 |
+------------+

ndv 함수를 활용해 distinct한 uid가 몇개나 있는지 확인 select ndv(uid)

+----------+
| ndv(uid) |
+----------+
| 73056968 |
+----------+
Fetched 1 row(s) in 14.59s

 

일반적인 쿼리를 통한 정확한 모수 확인 select count(distinct uid)

+---------------------+
| count(distinct uid) |
+---------------------+
| 74537396            |
+---------------------+
Fetched 1 row(s) in 148.32s

 

시간차이는 대략 10배 정도 빨랐으며 모수의 차이는 1.9%(1,480,428)정도 발생하였다.

대략적인 추정 모수만 빠르게 알고자하는 경우 사용하면 유용할 것 같다.

반응형
반응형

아래와 같은 데이터에서 선생님별 학생리스트가 아닌 1-1 matching된 multi row로 만들 때 보통 lateral view explode()를 사용한다. 하지만 주의할게 explode() udf는 아래와 같이 array형태나 mpa as a parameter형태만 지원한다.

teacher student_id_list
teacher1 [1,2,3]

table : class

$ SELECT teacher, id from  class LATERAL VIEW explode(student_id_list) ids AS id where adid='teacher1';

위처럼 lateral view explode 을 실행하면 아래처럼 muliti row 형태로 변환된다.

teacher student_id_list
teacher1 1
teacher1 2
teacher1 3

하지만 student_id_list가 String 형태로 되어있다면?

teacher student_id_list
teacher1 1,2,3

위에서 언급한 것 처럼 explode()는 array형태나 map as a parameter형태의 데이터에만 지원되기 때문에 다음과 같이 처리해준다.

$ SELECT teacher, id from  class LATERAL VIEW explode(student_id_list, ',') ids AS id where adid='teacher1';

이렇게 해주면 explode를 String format에서도 사용할 수 있다. 

결과는 동일하다.

반응형
반응형

보통 impala(임팔라)에서 임시 테이블을 생성 후 해당 테이블의 데이터를 기존 Imala의 데이터와 Join(조인)해서 사용해야 할 경우 다음과 같이 테이블을 생성 후 해당 경로에 데이터를 밀어넣어 준다.

create table DBNAME.TABLENAME (uid STRING) row format delimited fields terminated by ' ' LOCATION "hdfs:///user/hive/warehouse/특정원하는디렉토리명칭/“;

문제는 해당 명령어로 TABLE을 만들고 Imapa shell상에서 drop table [테이블명] 을 하였을 때 LOCATION으로 지정된 HDFS 파일은 남아 있게 되고 hadoop 명령어로 따로 지우려고 하면 보통 Hadoop 명령어 실행 권한과 해당 경로에 파일을 쓴 권한 [Impala] 가 달라서 Permission denied되며 삭제 되지 않는다.

따라서 해당 테이블을 Impala 테이블에서 Drop시키면서 연결괸 HDFS File도 함께 삭제 하고 싶다면 'PURGE' 옵션을 함께 주자.

drop table [tablename] PURGE

이렇게 하면 한 방에 해결할 수 있다.

반응형
반응형

오늘 날짜가 2019년 4월 12일경우

 

hive 하이브

date_sub(FROM_UNIXTIME(UNIX_TIMESTAMP(),'yyyy-MM-dd') , 1)

>> 2019-04-11

 

impala 임팔라

to_date(date_sub(now(), 1))

>> 2019-04-11

반응형
반응형


Hive external table을 생성하게 되면 테이블을 drop시키더라도 하둡에는 데이터가 남게 되는데요.


이런 이유로 같은 이름으로 테이블을 재생성했을 경우 기존의 데이터가 그대로 들어있는 것을 보실 수 있습니다.


그래서 hdfs명령으로 하둡데이터를 삭제하고 싶은데 권한 문제로 삭제되지 않습니다...


rmr: DEPRECATED: Please use 'rm -r' instead.

rmr: Failed to move to trash: hdfs://server-txa001.svr.maker.net:8020/user/hive/warehouse/oasis.db/specific_pub_and_area: Permission denied by sticky bit setting: user=irteam, inode=specific_pub_and_area

Command failed with exit code = 1


따라서 external 테이블은 drop시키기 전에 alter명령어로  테이블의 external속성을 변경해주고 drop시켜주어야 합니다.


먼저 desc formatted 테이블명 으로 데이터가 하둡어디에 저장되어있는지 확인합니다.


[server-txa001.svr.maker.net: 8020] > desc formatted specific_pub_and_area;

Query: describe formatted specific_pub_and_area



보시면 Location이 하둡에 저장된 데이터 경로입니다.

해당 Table Parameters를 보시면 EXTERNAL옵션이 TRUE로 되어 있는 것을 보실 수 있습니다.


이 상태에서는 아무리 테이블을 drop시켜도 데이터가 남아있게 됩니다.

따라서 alter table specific_pub_and_area set tblproperties('EXTERNAL'='FALSE'); 명령어로 옵션을 변경해주셔야 합니다.


이렇게 변경하고 desc formatted 테이블명 명령어로 보시면 EXTERNAL옵션이 FALSE로 변경된 걸 확인하실 수 있습니다.


이 상태에서 drop table {테이블명} 을 해주시게 되면 하둡에 있는 데이터들도 삭제되는 것을 확인 하실 수 있습니다.

반응형
반응형

최근 SUPERSET(슈퍼셋)작업을 진행 중 impala(임팔라)를 사용하면서 경험했던 내용에 대해 정리해보려고 한다.


impala(임팔라)와 hive(하이브)는 hive metastore(하이브 메타스토어)를 공유하며 impala는 metatdata를 캐시를 해서 관리하기때문에 빠른 성능을 보여주지만 hive에 의해서 메타데이터가 변경되었을 때 해당 캐시를 리프레쉬해주는 invalidate metadat명령이나 refresh명령어를 사용해서 캐시를 갱신해주어야 한다.

 When you create a table, load data, and so on through Hive, you do need to issue REFRESH or INVALIDATE METADATA on an Impala node before executing a query there.
The REFRESH and INVALIDATE METADATA statements are not needed when the CREATE TABLE,INSERT, or other table-changing or data-changing operation is performed through Impala.
These statements are still needed if such operations are done through Hive or by manipulating data files directly in HDFS, but in those cases the statements only need to be issued on one Impala node
rather than on all nodes. See REFRESH Statement and INVALIDATE METADATA Statement for the latest usage information for those statements.

By default, the metadata loading and caching on startup happens asynchronously, so Impala can begin accepting requests promptly. 

참고 : Components of the Impala Server



hive shell(하이브쉘)에서 다음과 같은 테이블이 있다.

hive> show tables;
OK
acedmp_custom
specific_pub_and_area3
test_table

hive shell에서 보면 specific_pub_and_area 테이블이 없다. drop시켰기 때문 (이전에 있었는데 drop시킨후 show tables 명령어)

but impala shell로 접근해서 보면 hive에서 spcific_pub_and_area테이블을 드랍시켰음에도 불구하고 테이블이 나타난다...

[svr.maker.net:21000] > show tables;
Query: show tables
+------------------------+
| name                   |
+------------------------+
| specific_pub_and_area  |
| specific_pub_and_area3 |
| test_table             |
+------------------------+



그래서 drop시켜보려고 하면 이미 hive metastore에는 존재하지 않는다고 나온다...

[svr.maker.net:21000] > drop table specific_pub_and_area;
Query: drop table specific_pub_and_area
ERROR: AnalysisException: Table oasis.specific_pub_and_area no longer exists in the Hive MetaStore. Run 'invalidate metadata oasis.specific_pub_and_area' to update the Impala catalog.
CAUSED BY: TableLoadingException: Table oasis.specific_pub_and_area no longer exists in the Hive MetaStore. Run 'invalidate metadata oasis.specific_pub_and_area' to update the Impala catalog.

여기에 대해서는 impala가 hive metastore를 어떻게 관리하는지 이해할 필요가 있다!(todo)



그래서 invalidate metadata oasis.specific_pub_and_area 명령어를 수행해주어야 impala에도 변경된 내용이 반영된다. 

(refresh oasis.specific_pub_and_area;) 명령어로는 테이블 삭제 생성까지 여부는 반영되지 않는다. 

[svr.maker.net:21000] > invalidate metadata oasis.specific_pub_and_area;
Query: invalidate metadata oasis.specific_pub_and_area

Fetched 0 row(s) in 0.16s
[svrmaker.net:21000] > show tables;
Query: show tables
+------------------------+
| name                   |
+------------------------+
| specific_pub_and_area3 |
| test_table             |
+------------------------+

새로운 테이블이 create됬을 때도 똑같이 해주어야한다.



hive쿼리로 hive테이블에 데이터를 밀어넣어보았다. (밑의 내용은 임의로 수정된 내용임을 말씀드립니다..)

hive> select * from specific_pub_and_area limit 10;
OK
20190320       3339487      Test신문    8888      Test_신문_Below      PAG     333     67
20190320      4449485      Test신문    7777      Test_신문_Below      PAG     14844   103335
.
.
.
(생략)
Time taken: 0.29 seconds, Fetched: 10 row(s)

hive> select count(*) from specific_pub_and_area;
OK
4794



impala shell에서 select를 해보면???

[svr.maker.net:21000] > select count(*) from specific_pub_and_area;
Query: select count(*) from specific_pub_and_area
+----------+
| count(*) |
+----------+
| 0        |
+----------+
Fetched 1 row(s) in 2.03s

[svrmaker.net:21000] > refresh oasis.specific_pub_and_area;
Query: refresh oasis.specific_pub_and_area2

Fetched 0 row(s) in 0.18s
[svrmaker.net:21000] > select count(*) from specific_pub_and_area;
Query: select count(*) from specific_pub_and_area2
+----------+
| count(*) |
+----------+
| 4794     |
+----------+
Fetched 1 row(s) in 1.21s

실제로 hive metastore에 테이블이 추가되거나 데이터가 insert되었을 때 invalidate metadata db.tablename 을해주면 모든 

경우에대해서 impala shell에서도 접근 가능하다.



하지만 invalidate metadata는 refresh에 비해 부하가 크므로 실제 데이터가 insert되었는지에 대한 확인만을 위한거면 refresh명령어로 갱신해주도록하자.

INVALIDATE METADATA and REFRESH are counterparts: INVALIDATE METADATA waits to reload the metadata when needed for a subsequent query, 
but reloads all the metadata for the table, which can be an expensive operation, especially for large tables with many partitions. 
REFRESH reloads the metadata immediately, but only loads the block location data for newly added data files, 
making it a less expensive operation overall. If data was altered in some more extensive way, 
such as being reorganized by the HDFS balancer, use INVALIDATE METADATA to avoid a performance penalty from reduced local reads. 
If you used Impala version 1.0, the INVALIDATE METADATA statement works just like the Impala 1.0 REFRESH statement did, while the Impala 1.1 REFRESH 
is optimized for the common use case of adding new data files to an existing table, thus the table name argument is now required.

The table name is a required parameter [for REFRESH]. To flush the metadata for all tables, use the INVALIDATE METADATA command. 
Because REFRESH tablename only works for tables that the current Impala node is already aware of, when you create a new table in the Hive shell, 
enter INVALIDATE METADATA new_table before you can see the new table in impala-shell. Once the table is known by Impala, 
you can issue REFRESH table_name after you add data files for that table.

참고 : invalidate와 refresh에 대한 자세한 내용



[ 결 론 ] 

hive쿼리를 통해 hive metastore에 데이터베이스나 테이블이 생성되거나 삭제되었을 때는 

impala에서 invalidate metadata db.tablename 명령어를 주어야 다시 캐싱된다.

but 테이블에 새로운 데이터만 hive쿼리에 의해 insert되었을 때는 refresh db.tablename으로 갱신해주도록 하자.

impala에서 생성한 테이블이나 데이터는 hive에서 별다른 명령어 없이 확인 가능하다.


반응형
반응형

최근 hive와 impala query를 만지게 되면서 hive udf를 impala에 등록할 일이 생겼는데


hive에서 udf를 등록할 때의 명령어가 먹지 않아 약간의 삽질을 하였다.


사용한 udf는 string을 입력받아 잘게 쪼개어 다시 string을 반환하는 역할이었다.


[ Hive UDF create command ]

hive> create function ad_get as 'com.data.udf.AdGet' using jar 'hdfs:///user/hive/lib/hive-udf.jar';

ad_get => hive에서 udf로 사용할 명칭
com.data.udf.AdGet => jar에서 udf로 등록할 클래스명칭

hdfs:///user/hive/lib/hive-udf.jar => jar hdfs path



[ Impala UDF create command ] 

Impala는 hive udf create 명령과는 다르게 해당 udf의 return 타입과 input타입을 명시해 주어야 한다.

create function ad_get(string, string, string) returns string location 'hdfs:///user/hive/lib/hive-udf.jar' symbol='com.data.udf.AdGet';


ad_get(string, string, string) => impala에서 udf로 사용할 명칭(string arg 3개를 입력 받는다)

returns string => 리턴타입 지정

symbol='com.data.udf.AdGet' => jar에서 udf로 등록할 클래스명칭

location 'hdfs:///user/hive/lib/hive-udf.jar



impala에 해당 명령어로 udf를 등록한 후 show functions 명령을 내려 보면 잘 등록되었는지 확인이 가능하다.


감사합니다:)


반응형

+ Recent posts