hive 쿼리 사용시 필드의 이름에 특수 문자가 포함될 수 있다.

이럴 때는 regexp_replace를 사용해 필드 문자열을 변경해야 한다. 



SELECT  get_json_object(regexp_replace(data, 'error.url', 'url'), '$.url'), data

FROM google_log_src

WHERE dt = '20180426'  and hr='10'  limit 10;




참조


https://jprakashblog.wordpress.com/2015/08/11/hive-get_json_object-having-special-characters/






Posted by 김용환 '김용환'


커보러스를 사용하고 있고 보안 존에 있는 hadoop와 연관된 작업을 할 때 keytab 파일을 받는다.


특히 Spark Job 또는 Apache Zepplin을 사용할 때 사용한다.


(Apache NIFI처럼 Apache Zepplin이 이런 커보러스 인증 기능을 제공하면 참 좋을 듯 싶다

참고로 NIFI는 keytab 파일을 파일로 복사하면 설정으로 가능케 한다)



먼저 keytab 파일이 정상적인지 확인한다. 



$ klist -kt /home/www/samuel-kim.keytab

Keytab name: FILE:/home/www/samuel-kim.keytab

KVNO Timestamp           Principal

---- ------------------- ------------------------------------------------------

   2 12/01/2017 00:00:00 samuel-kim@GOOGLE


   


3시간마다 보안 존에 있는 hadoop과의 통신이 끊어지지 않도록 cron 작업을 추가한다.

   

$ cat /etc/cron.d/keytab_update

0 */3 * * * /bin/bash -c "kinit -kt /home/www/samuel-kim.keytab samuel-kim@GOOGLE"



Posted by 김용환 '김용환'



하둡이나 스파크에 data locality 라는 단어가 종종 나오는데.. 의미는..


데이터 지역성은 계산하기 위해 데이터를 이동하는 것이 아니라 데이터를 그대로 두고 계산을 이동시키는 개념이다.


빅 데이터를 계산하기 위해 데이터를 이동(move)를 최대한 줄여


시스템 쓰루풋(throughput)과 혼잡도를 늦추게 하는 것이다. 


따라서 통신 대역폭이 당연히 줄어들고 성능은 늘어난다.

Posted by 김용환 '김용환'



apache phoenix의 qps에 jdbc를 연동하려면 다음 코드를 참조해 개발할 수 있다. 


https://www.javaworld.com/article/3030214/big-data/open-source-java-projects-apache-phoenix.html?page=2



내가 테스트한 버전은 다음과 같다.


<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>4.11.0-HBase-1.2</version>
</dependency>


phoenix 상황에 따라서는 설정 값을 주어야 하는데. 

sqlline.py를 실행할 때 hbase-site.xml를 설정하는데. 이에 맞게 jdbc의 속성에도 추가하는 것이 좋다. 



Properties props = new Properties();
props.setProperty("phoenix.schema.isNamespaceMappingEnabled", "true");
props.setProperty("phoenix.functions.allowUserDefinedFunctions", "true");
connection = DriverManager.getConnection("jdbc:phoenix:...", props);


만약 설정을 모른다 해도 어짜치 에러가 난다. pheonix를 jdbc로 연동할 때 에러가 발생하면 https://github.com/apache/phoenix/blob/master/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java를 참조하는 것이 좋다.





아래 문제는 phoenix.schema.isNamespaceMappingEnabled를 추가해서. 해결했다.


java.sql.SQLException: ERROR 726 (43M10):  Inconsistent namespace mapping properites.. Cannot initiate connection as SYSTEM:CATALOG is found but client does not have phoenix.schema.isNamespaceMappingEnabled enabled





아래 문제는 phoenix.functions.allowUserDefinedFunctions를 추가해서 해결했다. 


org.apache.phoenix.schema.FunctionNotFoundException: ERROR 6001 (42F01): Function undefined. functionName=[CONCAT]




Posted by 김용환 '김용환'

[phoenix] PQS

hadoop 2017.10.11 18:42


apache phoenix server에 접속하기 위해 jdbc 또는 sqlline을 사용할 수 있는 PQS(phoenix query server)가 있다. 


https://phoenix.apache.org/server.html



ha를 구성하기 위해 ha_proxy를 사용할 수 있다. 쓸만할 것 같다. 


https://community.hortonworks.com/articles/9377/deploying-the-phoenix-query-server-in-production-e.html

Posted by 김용환 '김용환'

hadoop의 파일 시스템 용량과 파일 개수를 확인하고 싶을 때에 hadoop dfs, hadoop fs 커맨드를 실행한다. 





hadoop 의 count 커맨드는 hadoop 디렉토리의 내용을 설명한다.


hadoop dfs -count [-q] [-h] <path> 로 실행할 수 있다.


(버전에 따라 hadoop fs로 할 수 있다)



/google1 디렉토리에는 DIR_COUNT, FILE_COUNT, CONTENT_SIZE, PATHNAME 를 보고 싶다면 다음을 실행한다. 



$ hadoop dfs -count /google1


      589243      7518116    191011332057185 /google1



사람이 읽을 수 있는 단위로 보고 싶다면 -h를 붙인다. 


$ hdfs dfs -count -h /google1


     575.4 K        7.2 M            173.7 T /google1




좀 더 자세한 정보를 보려면 -q를 사용한다.  쿼터 정보를 포함한다. 

QUOTA, REMAINING_QUATA, SPACE_QUOTA, REMAINING_SPACE_QUOTA, DIR_COUNT, FILE_COUNT, CONTENT_SIZE, PATHNAME


디렉토리에 쿼터가 없다면 none이라고 뜬다.

$ hdfs dfs -count -h -q /google1
        none             inf            none             inf      575.4 K        7.2 M            173.7 T /google1





디렉토리 쿼터가 있다면 다음처럼 보일 수 있다.


$ hdfs dfs -count -q -h /q-google

      20.8 M          12.1 M           1.5 P         738.1 T      651.0 K        8.1 M            254.0 T /q-goolge




Posted by 김용환 '김용환'






hive 쿼리를 실행시 reducer에 메모리 용량를 많이 할당해야 할 때가 있다.


이 때는 hive.exec.reducers.bytes.per.reducer를 설정하면 된다.



reducer 당 메모리 크기를 설정한다.설정된 메모리 크기를 바탕으로 reducer 개수를 정의한다.  Hive 0.14.0 이후 버전의 hive.exec.reducers.bytes.per.reducer 기본값은 256MB이다. 입력 크기가 1GB이면 4개의 reducer가 적당하는 것이다. 



https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties 문서를 보면 다음과 같다.


hive.exec.reducers.bytes.per.reducer
  • Default Value: 1,000,000,000 prior to Hive 0.14.0; 256 MB (256,000,000) in Hive 0.14.0 and later
  • Added In: Hive 0.2.0; default changed in 0.14.0 with HIVE-7158 (and HIVE-7917)

Size per reducer. The default in Hive 0.14.0 and earlier is 1 GB, that is, if the input size is 10 GB then 10 reducers will be used. In Hive 0.14.0 and later the default is 256 MB, that is, if the input size is 1 GB then 4 reducers will be used.



Hive 0.14.0이전의 기본 값은 1G이지만, 0.14.0이후에는 256MB이다. 256MB는 가장 성능이 잘나오는 HDFS 블럭 사이즈이라 한다. (https://stackoverflow.com/questions/34419869/how-to-set-data-block-size-in-hadoop-is-it-advantage-to-change-it참조)



이외 너무 많은 reducer를 쓰지 않도록 hive.exec.reducers.max의 값을 수정할 수 있다.

hive.exec.reducers.max
  • Default Value: 999 prior to Hive 0.14.0; 1009 in Hive 0.14.0 and later
  • Added In: Hive 0.2.0; default changed in 0.14.0 with HIVE-7158 (and HIVE-7917)

Maximum number of reducers that will be used. If the one specified in the configuration property mapred.reduce.tasks is negative, Hive will use this as the maximum number of reducers when automatically determining the number of reducers.





잡마다 reduce의 기본 개수를 정의할 수 있다.


mapred.reduce.tasks
  • Default Value: -1
  • Added In: Hive 0.1.0

The default number of reduce tasks per job. Typically set to a prime close to the number of available hosts. Ignored when mapred.job.tracker is "local". Hadoop set this to 1 by default, whereas Hive uses -1 as its default value. By setting this property to -1, Hive will automatically figure out what should be the number of reducers.


Posted by 김용환 '김용환'



장치에 남은 공간이 없다는 hive 에러가 발생했다면 로컬(local) 파일 시스템에 용량이 없음을 의미한다.


df로 확인한다.



rom log4j:ERROR Failed to flush writer,

java.io.IOException: 장치에 남은 공간이 없음

at java.io.FileOutputStream.writeBytes(Native Method)

at java.io.FileOutputStream.write(FileOutputStream.java:345)

at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)

at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)

at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)

at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)

at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)

at org.apache.log4j.helpers.QuietWriter.flush(QuietWriter.java:59)

at org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:324)

at org.apache.log4j.DailyRollingFileAppender.subAppend(DailyRollingFileAppender.java:369)

at org.apache.log4j.WriterAppender.append(WriterAppender.java:162)

at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)

at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:66)

at org.apache.log4j.Category.callAppenders(Category.java:206)

at org.apache.log4j.Category.forcedLog(Category.java:391)

at org.apache.log4j.Category.log(Category.java:856)

at org.apache.commons.logging.impl.Log4JLogger.info(Log4JLogger.java:176)

at org.apache.hadoop.hive.ql.session.SessionState.createPath(SessionState.java:641)

at org.apache.hadoop.hive.ql.session.SessionState.createSessionDirs(SessionState.java:578)

at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:508)

at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:671)

at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:615)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:606)

at org.apache.hadoop.util.RunJar.run(RunJar.java:221)

at org.apache.hadoop.util.RunJar.main(RunJar.java:136)




Posted by 김용환 '김용환'




 missing EOF at '...' near ''hdfs://..' 에러는 Location 밑에 tblproperties이 없어서 에러가 발생할 수 있다.



 LOCATION 

 'hdfs://hadoop/goolgleplus/log'

 tblproperties ("orc.compress"="NONE")





external 테이블에 location과 stored as orc라는 프로퍼티를 함꼐 추가하면 에러가 발생할 수 있다.

Posted by 김용환 '김용환'



json을 정보를 저장하는 테이블에 view를 생성해서 json없는 테이블처럼 사용할 수 있다. 

(더 정확히 말하면 general하게 로그 수집을 위한 모델링할 수 있는 로그에 json를 사용할 수 있으면서 

쉽게 정보를 파악할 수 있는 방법이다)




아래와 같은 row를 가진 hive 테이블이 있다. 


1787821114291 service 15 birthday {"result":true,"birth":"0224","id":"15","action":"add"}  2011-02-23


이런 hive테이블을 조회하려면 아래와 같이 실행해야 한다.


select * from googleplus_reqlog where date_id='2011-02-23' and label='birthday' and get_json_object(props, '$.id')='15';





hive 질의 시 get_json_object를 사용하는 것이 불편하기 때문에 새로운 view를 만든다.


CREATE VIEW `stat`.`birthday` COMMENT 'google plus birthday' AS SELECT

`birthday_temp`.`ts` AS `ts`,

`birthday_temp`.`date_id` AS `date_id`,

`birthday_temp`.`result` AS `result`,

`birthday_temp`.`birth` AS `birth`,

`birthday_temp`.`id` AS `id`,

`birthday_temp`.`action` AS `action`,

`birthday_temp`.`from` AS `from`

FROM (

  select

    ts,

    date_id,

    get_json_object(`googleplus_reqlog`.`props`, '$.result') as result,

    get_json_object(`googleplus_reqlog`.`props`, '$.birth') as birth,

    get_json_object(`googleplus_reqlog`.`props`, '$.id') as id,

    get_json_object(`googleplus_reqlog`.`props`, '$.action') as action,

  from `src`.`googleplus_reqlog`

  where label='birthday') `birthday_temp`;

  

  

  

view를 확인한다. 


hive> desc birthday;

OK

ts                   bigint

date_id             string

result               string

birth               string

id           string

action               string




이제 get_json_object 없이 간단하게 hive 질의를 할 수 있다. 

  

 select * from birthday where date_id='2011-02-23' and account_id='15';

  


처음에 소개한 hive 질의와 동일한 결과를 내지만, 훨씬 편하다.


select * from googleplus_reqlog where date_id='2011-02-23' and label='birthday' and get_json_object(props, '$.id')='15';



Posted by 김용환 '김용환'