[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 김용환 '김용환'


mysql의 경우 reserved word를 table의 컬럼명으로 쓰인다면 back quote(`)을 사용해야 한다.


https://dev.mysql.com/doc/refman/5.7/en/identifiers.html



The identifier quote character is the backtick (`):

mysql> SELECT * FROM `select` WHERE `select`.id > 100;




마찬가지로 hive에서도 reserved word를 table의 컬럼명으로 쓰인다면 back quote(`)을 사용해야 한다.



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

 Any column name that is specified within backticks (`) is treated literally. 


hive> select * from googleplus_log where `date`='2037-08-23' and label='birthday' and `to`='11935385';

Posted by 김용환 '김용환'


json 데이터를 저장할 hive 테이블을 생성하는 예시이다. 

CREATE TABLE if not exists member

(

   name STRING,

   id INT, 

   props STRUCT <

       departname:STRING,

       alias:STRING

   >

) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'

STORED AS TEXTFILE





json 데이터를 hive에 저장할 때 개행 문자가 있으면 에러가 발생한다. 


$ cat "test.json"

{

  "name":"samuel",

  "id":1,

  "props": {

    "departname":"none",

    "alias":"kim"

  }

}


다음 에러로 발생한다. 

Failed with exception java.io.IOException:org.apache.hadoop.hive.serde2.SerDeException: Row is not a valid JSON Object - JSONException: A JSONObject text must end with '}' at 2 [character 3 line 1]


따라서 개행 문자 없이 사용해야 한다. 


$ cat "test.json"

{  "name":"samuel",  "id":1,  "props":{    "departname":"none",    "alias":"kim"  }}






이제 하둡에 json 파일을 업로드한다.


$ hadoop fs -put test.json /lib/test.json


hive 실행을 실행해서 데이터를 읽게 한다.



hive> LOAD DATA INPATH '/lib/test.json' OVERWRITE INTO TABLE member;



hive> select * from member;

OK

samuel 1 {"departname":"none","alias":"kim"}

Time taken: 0.614 seconds, Fetched: 1 row(s)


SELECT props.alias FROM member WHERE props.departname="none";

kim



Posted by 김용환 '김용환'



hive에서 json 컬럼에 대해서 json 쿼리를 진행할 수 있다. 



hive> select * from googleplus_log where date_id='2037-08-23' and label='birthday' and get_json_object(props, '$.id')='11935385';




json_tuple도 사용할 수 있지만, lateral view도 써야 하고 parittion table이라면 strict 모드로 바꾸라 한다. 


hive> select log.date_id, b.* from googleplus_log log lateral view json_tuple(log.props, 'result', 'birth', 'id', 'action') b where date_id='2017-02-23' and label='birthday'; 


This happens cos the hive is set to strict mode. this allow the partition table to access the respective partition /folder in hdfs .



hive>  set hive.mapred.mode=unstrict; 


hive> select log.date_id, b.* from googleplus_log log lateral view json_tuple(log.props, 'result', 'birth', 'id', 'action') b where date_id='2017-02-23' and label='birthday'; 

##잘 동작한다.






Posted by 김용환 '김용환'


Hive - get_json_object 호출시 에러 


hive에서 hive udf의 json을 사용하려 할 때(get_json_object를 사용, ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'를 사용) 다음 에러가 발생한다. 


Error while compiling statement: FAILED: RuntimeException MetaException(message:java.lang.ClassNotFoundException Class org.openx.data.jsonserde.JsonSerDe not found)
class org.apache.hive.service.cli.HiveSQLException



에러가 발생하지 않고 정상적으로 실행하려면,다음과 같이 실행하면 get_json_object가 실행된다.

$ wget http://www.congiu.net/hive-json-serde/1.3.7/cdh5/json-serde-1.3.7-jar-with-dependencies.jar
$ hive
hive> add jar /위치/json-serde-1.3.7-jar-with-dependencies.jar


세션이 실행될 때마다 동작시키려면 .hiverc를 수정한다.


$ vi ~/.hiverc

..

add jar /위치/json-serde-1.3.7-jar-with-dependencies.jar











Posted by 김용환 '김용환'