Hive 데이터 입력시 노드당 처리 파티션 개수 초과 오류

 

·       Version : Hive

 

파티셔닝된Hive 테이블에 데이터 입력시 아래와 같은 오류가 발생하였다. 오류 메시지를 살펴보면 노드당 최대 동적 파티션 개수보다 많은 수의 동적 파티션이 생성되어 발생한 오류이다.

Error: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row {“col_1”:25513237,“col_2”:8104666,“col_3”:3808,“col_4”:6705,“col_4”:“2016-01-21 08:31:33",“col_6”:42,“col_7”:“471.00”,“col_8”:null} at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.map(ExecMapper.java:157) at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:54) at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:465) at org.apache.hadoop.mapred.MapTask.run(MapTask.java:349) at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:174) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1875) at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:168) Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row {“col_1”:25513237,“col_2”:8104666,“col_3”:3808,“col_4”:6705,“col_5”:“2016-01-21 08:31:33",“col_6”:42,“col_7”:“471.00”,“col_8”:null} at org.apache.hadoop.hive.ql.exec.MapOperator.process(MapOperator.java:494) at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.map(ExecMapper.java:148) ... 8 more Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: [Error 20004]: Fatal error occurred when node tried to create too many dynamic partitions. The maximum number of dynamic partitions is controlled by hive.exec.max.dynamic.partitions and hive.exec.max.dynamic.partitions.pernode. Maximum was set to 100 partitions per node, number of dynamic partitions on this node: 101 at org.apache.hadoop.hive.ql.exec.FileSinkOperator.getDynOutPaths(FileSinkOperator.java:951) at org.apache.hadoop.hive.ql.exec.FileSinkOperator.process(FileSinkOperator.java:722) at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:882) at org.apache.hadoop.hive.ql.exec.SelectOperator.process(SelectOperator.java:95) at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:882) at org.apache.hadoop.hive.ql.exec.TableScanOperator.process(TableScanOperator.java:130) at org.apache.hadoop.hive.ql.exec.MapOperator$MapOpCtx.forward(MapOperator.java:146) at org.apache.hadoop.hive.ql.exec.MapOperator.process(MapOperator.java:484) ... 9 more

 

Hive 노드당 최대 동적 파티션 기본값은 100으로 설정되어 있다. 문제를 해결하기 위해서는 아래와 같은 명령을 사용하여 노드당 최대 동적 파티션 갯수 설정을 변경할 있다.

set hive.exec.max.dynamic.partitions=100000;
set hive.exec.max.dynamic.partitions.pernode=100000;

 

노드당 파일 갯수 초과할 경우에도 비슷한 오류가 발생한다. 아래 같은 오류 구문이 발생 때에는 파일 갯수의 설정을 오류가 발생한 최대 값보다 크게 설정할 있도록 한다.

[Fatal Error] total number of created files now is 100028, which exceeds 100000. Killing the job.

 

set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.max.dynamic.partitions.pernode=100000;
set hive.exec.max.dynamic.partitions=100000;
set hive.exec.max.created.files=900000;

 

 

위와 같이 설정값을 변경하기에 앞서 Hive에서 이렇게 많은 파티션 또는 파일을 생성하는지 생각해보아야 한다. 대부분의 경우 사용자 설정값 범위 내에서 파티션이 이루어진다는 가정하에 사용하는데,  이렇게 한계를 벗어난 다는 것은 파티션 키를 잘못 배치했거나 파티션 처리에 적절하지 않는 데이터셋을 사용했을 가능성이 크다. 그럼에도 불구하고 파티션을 늘려야한다고 생각되면 옵션을 사용하여 적절할 임계치를 조절할 있도록 한다.

 

2021-09-13 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, 파티션 테이블, 동적 파티션 개수 초과,

Hive UDF (사용자 정의 함수)

 

·       Version : Hive

 

Hive UDF(User Define Function, 사용자 정의 함수) 사용자에게 HiveQL 확장할 있게 해주는 하이브의 강력한 기능이다. 자바를 이용해 구현하며 세션에 추가되면 마치 내장 함수처럼 동작하고 심지어 온라인 도움말도 제공할 있다. UDF 사용하면 하이브 쿼리가 동작하는 동일한 프로세스 안에서 마치 태스크처럼 돌아간다. 그러므로 효과적으로 동작하고 다른 시스템과의 통합 과정에서 발생하는 복잡함을 제거할 있다.

 

현재 하이브 세션에 로드된 내장함수는 SHOW FUNCTIONS 명령어를 사용하여 목록을 확인할 있다.

hive>show functions;

 

함수는 보통 자신을 설명하는 문서를 가지고 있으며 DESCRIBE FUNCTION 명령어를 사용하여 간략한 설명을 볼수 있다. EXTENDED 예약어로 확장 문서를 확인할 수도 있다.

hive>describe function concat;

 

hive>describe function extended concat;

 

함수를 사용할면 쿼리 안에서 필요한 인자를 넣고 간단히 이름으로 호출하면 된다. 어떤 함수는 지정된 개수의 인자를 받기도 하며, 어떤 함수는 인자와 데이터 형식을 받기도 하는등, 함수에 따라 필요 인수가 다를수 있다.

일반적으로 표준함수라 불리는, 하나의 로우 또는 하나 이상의 컬럼을 받아서 하나의 값을 반환하는 함수는 데이터형을 변환 (DOUBLE-> BIGINT)하거나 round(), floor(),  절대값을 계산하는 abs() 함수 같은 수학함수가 있으며, 대소문자 전환, 문자열 뒤집기, 문자열 연결등과 같은 문자열 조작 함수 등이 있다.

 

집계함수(aggregate function) 사용자 정의와 내장된 모든 집계 함수를 포함하여 0 이상의 로우 또는 하나 이상의 컬럼을 받아서 하나의 결과값을 반환한다. 대표적인 함수로 sum(), avg(), min(), max() 등이 있다.

 

테이블 생성함수(table generating function 0 또는 이상의 입력을 받아서 여러 컬럼 또는 로우를 결과값으로 생성한다. 대표적으로 array 함수가 있으며, explode() 함수는 배열을 입력받아서 배열의 요소를 ROW 반환한다.

 

2020-11-12 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, 하이브 사용자 함수, 하이브 UDF, Hive UDF, User Define Function, Hive Function

Hive Thrift Service (쓰리프트 서비스)

 

·       Version : Hive

 

Hive 하이브 서버(Hive Server) 또는 하이브 쓰리프트(Hive Thrift) 불리는 구성요소를 가지고 있다. 쓰리프트는 확장성과 서로 다른 언어간에 통신이 가능한 소프트웨어 프레임워크이다. 구성요소를 통해 클라이언트는 하나의 포트(Port) 하이브에 접근할 있다.

CLI 하이브를 접근하는 가능 일방적인 방식이다. CLI 모든 하이브 구성요소 설정이 로컬에 복사본으로 존재해야만 동작한다. 마찬가지로 하둡 클리아언트와 하둡 설정도 있어야 한다. 하이브 CLI HDFS 클라이언트, 맵리듀스 클라이언트, JDBC 클라이언트(메타스토어 접속용) 동작한다.

 

하이브 서비스는 쓰리프트를 이용한다. 쓰리프트는 인터페이스 언어를 제공한다. 쓰리프트 컴파일러는 인터페이스를 해석하여 다양한 언어로 네트워크 RPC 클라이언트 코드를 생성한다. 하이브는 자바로 작성되었고, 자바 바이트 코드(bytecode) 범용 플랫폼이므로 쓰리프트 서버를 위한 자바 클라이언트를 하이브 배포에 포함하고 있다. 클라이언트를 사용하는 방법중 하나는 자바 통합 개발 환경으로 프로젝트를 시작해 관련 라이브러리를 직접 포함시키거나 메이븐을 통해 가져오는 방법이 있다.

 

하이브 서비스는 쓰리프트를 통해 하이브 메타스토어에 접속한다. 일반적으로 사용자는 메타스토어를 직접 수정하는 메타스토어 메소드를 사용하지 말고 하이브를 통해 HiveQL 언어를 이용해야한다. 사용자는 테이블에 관한 메타 정보만 제공하는 읽기 전용 메소드를 사용하는것이 좋다.

 

하이브 CLI /tmp hadoop.tmp.dir 디렉터리에 .hivehistory 같은 산출물을 만들어 낸다. 하이브 서비스는 하둡 잡이 실행되는 시작점이기 때문에 하이브 서비스를 배치할 몇가지 고려할 점이 있다. 특히 클라이언트 장비에서하던 태스크 계획, 관리 작업이 서버에서 실행되기 때문에 여러 클라이언트의 동시 실행시 서비스 오버헤드를 줄이기 위하 부하 분산으로 TCP load balance 이용하거나 백엔스 서버의 pool 접속하는 프록시를 만들어 사용하는것이 좋다. 또한 하이브는 hive.start.cleanup.scratchdir 이라는 속성을 통해 재시작시 scratch 디렉터리를 비운다. 기본값은 false이며, true 변경하여 재시작시 디렉터리를 클린업 있다.

 

일반적으로 하이브 세션은 메타스토어로 이용하는 JDBC 데이터베이스에 직접 연결된다. 하이브는 쓰리프트 메타스토어(ThriftMetastore)라는 선택적 구성요소를 제공하는데, 이를 설치하면 하이브 클라이언트는 쓰리프트 메타스토어로 연결되고 쓰리프트 메타스토어가 JDBC 데이터베이스에 연결된다.

 

 

 

 

 

2020-11-08 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, Hive tunning, 하이브 쓰리프트, Hive Thrift, 하이브 관리, Hive Management

Hive 보안 인증, 권한 부여

 

·       Version : Hive

 

하둡은 보안강화를 위해 커버로스(Kerberos)인증을 지원한다. 커버로스 인증은 서버와 클라이언트 간의 상호 인증을 지원한다. 더이상 hadoop. job.ugi 속성을 설정하여 다른 사용자인척 없다. 하지만 이렇게 동작하려면 모든 하둡 구성요소는 커버로스 보안을 양쪽 끝에서 지원해야한다.  모든 하둡 에코 시스템이 커버로스 인증을 지원 못하듯이, 하이브 인증도 완전하지 않다. 하이브는 메타스토어에 접속하기 위해서 JDBC 데이터베이스 연결을 사용하거나 사용자를 대신해서 동작을 수행하는 쓰리프트를 사용한다. 쓰리프트 기반의 하이브 서비스 역시 다른 사용자인척 해야한다. 소유자와 그룹이 파일에 대한 소유권을 갖는 하둡의 파일 소유 모델은 테이블에서 로우나 컬럼 기반 방식으로 접근을 허용하고 금지하도록 구현된 많은 데이터베이스의 방식과 다르다.

앞에 설명한 파일 소유 모델 때문에 파일과 디렉터리의 소유가 서로 다른 사용자라면 파일에 퍼미션(permission) 부여하는 일이 중요하다.  HDFS 퍼미션 시스템은  user, group, others 요소가 있으며 read, write, execute라는 퍼미션이 있다. 하이브는 hive.files.umask.value 속성을 가지고 있는데 설정으로 새롭게 생성하는 파일의 기본 퍼미션을 비트 마스크를 통해서 설정한다. Hadoop Hive 사용자의 구성에 따라 664 권한인 0002 파일 권한 비트 마스크를 만들 있다.

<property> 

  <name>hive.files.umask.value</name> 

  <value>0002</value> 

  <description>The dfs.umask value for the hive created folders</description> 

</property>

 

hive.metastore.authorization.storage.checks 속성을 true 설정하면 테이블 내부에 사용자가 지울 있는 퍼미션을 갖지 못한 파일이 있을때 하이브는 해당 테이블을 드롭하는 것을 방지한다. 속성의 기본값은 false 이며 true 설정해야 한다.

<property> 

  <name>hive.metastore.authorization.storage.checks</name> 

  <value>true</value> 

  <description>Should the metastore do authorization checks against 

  the underlying storage for operations like drop-partition (disallow 

  the drop-partition if the user in question doesn't have permissions 

  to delete the corresponding directory on the storage).</description> 

</property>

 

동시에 Hive hive.metastore.execute.setugi 가능한 true 설정한다. 안전하지 않은 모드에서 속성을 true 설정하면 메타 스토어가 사용자 그룹의 권한을 정의하는 DFS 작업을 수행한다.

 

Hive 인증을 활성화 하는 방법은 hive.security.authorization.enabled true 설정한다. 기본값은 false이다.

<property> 

  <name>hive.security.authorization.enabled</name>  

  <value>true</value> 

  <description>Enable or disable the hive client authorization</description> 

</property>

 

hive.security.authorization.createtable.owner.grants 속성에서는 테이블 생성자가 접근할 있는 권한을 구성한다. 기본값은 null이며, ALL 설정하여 사용자가 자신이 만든 테이블에 액세스 있도록 한다.

<property> 

  <name>hive.security.authorization.createtable.owner.grants</name> 

  <value>ALL</value> 

  <description>The privileges automatically granted to the owner whenever 

  a table gets created.An example like "select,drop" will grant select 

  and drop privilege to the owner of the table</description> 

</property> 

 

아래 스크립트는 Hive명령으로 사용자 인증을 활성화 한다. 권한이 없을 경우 아래 예제 스크립트와 같이 테이블 생성시 오류가 발생한다.

hive> set hive.security.authorization.enabled=true;   

 

hive> CREATE TABLE auth_test (key int, value string);   

 

Authorization failed:No privilege 'Create' found for outputs { database:default}.   

Use show grant to get more details

 

권한을 부여하기 위해서는 아래 스크립트를 사용할수 있다. 사용자(USER), 그룹(GROUP), 역할(ROLES) 같은 다양한 주제에 권한을 부여할 있다.

hive> set system:user.name; 

 

system:user.name=hadoop 

 

hive> GRANT CREATE ON DATABASE default TO USER hadoop; 

 

hive> CREATE TABLE auth_test (key INT, value STRING); 

 

Confirm the permissions we have with the SHOW GRANT command:

hive> SHOW GRANT USER hadoop ON DATABASE default;   

database default   

principalName hadoop   

principalType USER   

privilege Create   

grantTime Sun May 06 17:18:10 EDT 2018   

grantor hadoop

 

사용자별로 퍼미션을 부여하는 작업은 사용자와 테이블이 많을수록 관리 부담이 증가한다. 이런경우 그룹 단위로 퍼미션을 부여할 있다. 하이브에서 그룹은 사용자의 번째 POSIX 그룹과 동일하다.

hive> CREATE TABLE auth_test_group(a int,b int); 

 

hive> SELECT * FROM auth_test_group;

 

Authorization failed:No privilege 'Select' found for inputs 

{ database:default, table:auth_test_group, columnName:a}. 

Use show grant to get more details. 

hive> GRANT SELECT on table auth_test_group to group hadoop; 

hive> SELECT * FROM auth_test_group; 

OK 

Time taken: 0.119 seconds

 

사용자와 그룹 퍼미션이 충분히 유연하지 않은경우 역할(role) 사용할 있다. 사용자에게 역할을 부여하고 특권이 역할에 부여될수 있다. 시스템 외부에서 제어하는 그룹과는 달리 역할은 하이브 내부에서 제어되므로 좀더 유연성을 제공한다.

hive> set system:user.name; 

 

system:user.name=hadoop 

 

hive> GRANT CREATE ON DATABASE default TO USER hadoop; 

 

hive> CREATE TABLE auth_test (key INT, value STRING); 

 

Confirm the permissions we have with the SHOW GRANT command:

hive> SHOW GRANT USER hadoop ON DATABASE default;   

database default    

principalName hadoop   

principalType USER   

privilege Create   

grantTime Sun May 06 17:18:10 EDT 2018   

grantor hadoop

 

기본적으로 파티션 테이블의 권한은 테이블의 권한을 따르거나  파티션에 대한 권한 메커니즘을 설정할 있다. 테이블 속성의 PARTITION_LEVEL_PRIVILEGE true 설정하여 사용할 있다.

hive> ALTER TABLE auth_part 

> SET TBLPROPERTIES ("PARTITION_LEVEL_PRIVILEGE"="TRUE"); 

Authorization failed:No privilege 'Alter' found for inputs 

{database:default, table:auth_part}. 

Use show grant to get more details.

 

일반 사용자는 쿼리를 수행하기 위해서 스스로 특권을 부여하는 번거로움 없이 테이블을 생성하고 싶을 것이다. 또는 기본 동작으로 모든 특권을 부여하여 사용하고 싶을 것이다. 아래 스크립트는 SELECT DROP 특권을 자신 소유의 테이블에 자동으로 권한을 부여한다.

<property> 

  <name>hive.security.authorization.createtable.owner.grants</name> 

  <value>select,drop</value> 

</property>

 

비슷하게 특정 사용자는 생성한 테이블에 대한 특권을 자동으로 부여받을수 있다. 아래 스크립트는 sungwook, sqlmvp 사용자가 모든 테이블을 읽을수 있는 권한을 부여한다. 그리고 tom 테이블 생성만 가능하다.

<property> 

  <name>hive.security.authorization.createtable.user.grants</name> 

  <value>sungwook,sqlmvp:select;tom:create</value> 

</property>

 

동일한 구성을 그룹 권한 역할 권한에도 적용할 있다.

hive.security.authorization.createtable.group.grants 

hive.security.authorization.createtable.role.grants

 

권한을 회수하는 방법은 아래 스크립트를 사용한다.

revoke create on database default from user sungwook;

revoke select on database default from group sungwook; 

 

 

 

[참고자료]

·       Hive - Authority Management (Authorization) : https://www.programmersought.com/article/1095315821/

 

 

2020-10-27 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, Hive tunning, 하이브 튜닝, 하이브 보안, 하이브 인증, 하이브 권한, Hive Security, Hive Authorization, Hive Authority Management

+ Recent posts