sqoop 성능 튜닝

hadoop 2019.01.11 18:33



sqoop에서 무거운 DB덤프 잡을 빨리 하려면 다음 옵션을  고려하길 바란다. 확실히 빨라진다. 10분 배치를 1분대로..



1)  mapper 메모리는 크게


           -Dmapreduce.map.memory.mb=(크게, 그러나 적절하게) -Dmapreduce.map.java.opts=-Xmx(크게, 그러나 적절하게)



2) mapper 개수는 많이 


        --num-mappers (크게, 그러나 적절하게)                                                




3) split-by와 $CONDITIONS



--split-by id : 쪼개는 컬럼 이름

$CONDITIONS : 내부 튜닝 값




https://sqoop.apache.org/docs/1.4.2/SqoopUserGuide.html


If you want to import the results of a query in parallel, then each map task will need to execute a copy of the query, with results partitioned by bounding conditions inferred by Sqoop. Your query must include the token $CONDITIONS which each Sqoop process will replace with a unique condition expression. You must also select a splitting column with --split-by.

For example:

$ sqoop import \
  --query 'SELECT a.*, b.* FROM a JOIN b on (a.id == b.id) WHERE $CONDITIONS' \
  --split-by a.id --target-dir /user/foo/joinresults

Alternately, the query can be executed once and imported serially, by specifying a single map task with -m 1:

$ sqoop import \
  --query 'SELECT a.*, b.* FROM a JOIN b on (a.id == b.id) WHERE $CONDITIONS' \
  -m 1 --target-dir /user/foo/joinresults





4) --boundary-query <sql 문>


전체를 덤프를 뜨려고 하면 속도가 통 나지 않는다. split-by id를 사용할 때 index가 있는 id를 기반으로 경계문을 전송하면 빠르게 쿼리 결과를 받을 수 있다.


Posted by 김용환 '김용환'



spark 애플리케이션-haoop(yarn)  연동 잡을 실행하던 중에 


애플리케이션을 종료하려면.. 스파크 스케줄러(또는 hadoop 스케줄러)에서 


인스턴스 id인 application_11123123131321을 얻은 후,


yarn 커맨드의 kill 커맨드에 인스턴스 id를 추가한다.  



yarn application -kill application_11123123131321 





Posted by 김용환 '김용환'








org.apache.hadoop.ipc.RemoteException: No lease on /google/public_plus/20181127/23_merged (inode 2683729964): File does not exist. [Lease.  Holder: DFSClient_NONMAPREDUCE_-39928930_1, pending creates: 8]





하둡 소스를 보면, 파일이 없거나 디렉토리이면 위의 에러가 발생한다. lease 이슈는 아니다..




https://github.com/facebookarchive/hadoop-20/blob/master/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java#L3105


private void checkLease(String src, String holder, INode file) 

                                                     throws IOException {


    if (file == null || file.isDirectory()) {

      Lease lease = leaseManager.getLease(holder);

      throw new LeaseExpiredException("No lease on " + src +

                                      " File does not exist. " +

                                      (lease != null ? lease.toString() :

                                       "Holder " + holder + 

                                       " does not have any open files"));

    }




참고로 lease는 write lock과 비슷한 개념이다.


Leases

In HDFS these locks are called Leases. Leases are granted to a client which request to open a file for a write operation (e.g. create / append / truncate a file.) 


https://www.raviprak.com/research/hadoop/leaseManagement.html






사실 생각해보면. 실제로 있어야 하는데 존재했다가 삭제된 것이다. 


이는 병렬 이슈인 것이다.


https://stackoverflow.com/questions/7559880/leaseexpiredexception-no-lease-error-on-hdfs




spark이라면. 다음과 같이 설정을 해서 speculative optimization 알고리즘(병렬)을 끄도록 한다.



sparkConf.set("spark.speculation", "false");

sparkConf.set("spark.hadoop.mapreduce.map.speculative", "false");

sparkConf.set("spark.hadoop.mapreduce.reduce.speculative", "false")



hive라면 다음과 같은 설정을 진행한다. 



set mapreduce.map.speculative=false;

set mapreduce.reduce.speculative=false;

set hive.mapred.reduce.tasks.speculative.execution=false;

Posted by 김용환 '김용환'


apache phoenix 에서 timestamp 타입을 utc로 저장했다.



이를 현재 시간(gmt +9)로 보고 싶다면 아래와 같은 쿼리를 실행한다.




select CONVERT_TZ(timestamp, 'UTC', 'Asia/Seoul')




기타 phoenix 함수는 아래를 참조한다.


https://phoenix.apache.org/language/functions.html


Posted by 김용환 '김용환'




Phoenix에서 create schema을 실행하려면



phoenix/bin/hdfs-site.xml과 hbase/conf/hdfs-site.xml에 다음 속성을 추가해야 한다.




<property>

<name>phoenix.schema.isNamespaceMappingEnabled</name> 

<value>true</value> 

</property> 




만약 설정되어 있지 않도록 sqline,py에서 다음 에러가 발생한다.


Cannot create schema because config phoenix.schema.isNamespaceMappingEnabled for enabling name space mapping isn't enabled \


Posted by 김용환 '김용환'


Apache Phoenix driver를 사용할 때 유의해야 할 부분이 있다.



zookeeper를 이용한 분산 hbase 위에 phoenix를 사용할 때와


standalone의 hbase 위에 phoenix를 사용할 때의 jdbc url은 다르다.


(https://phoenix.apache.org/faq.html)



1. Thick driver

zookeeper를 이용한 분산 hbase 위에 phoenix를 사용할 때를 thick driver라 한다.



스키마는 다음과 같고.. lib는 phoenix-4.14.0-Hbase-1.4-client.jar를 사용한다.

jdbc:phoenix:[comma-separated ZooKeeper Quorum [:port [:hbase root znode [:kerberos_principal [:path to kerberos keytab] ] ] ]



예)


jdbc:phoenix:localhost



jdbc:phoenix:zookeeper1.domain,zookeeper2.domain,zookeeper3.domain:2181:/hbase-1:phoenix@EXAMPLE.COM:/etc/security/keytabs/phoenix.keytab






2. Thin driver



standalone의 hbase 위에 phoenix를 사용할 때의 jdbc url은 thin driver라 한다.


스키마는 다음과 같고.. lib는 phoenix-4.14.0-Hbase-1.4-thin-client.jar를 사용한다.


(라이브러리 파일이 다르고..특별히 Dirver Class는 org.apache.phoenix.querserver.client.Driver임을 잘 기억해야 한다.)



jdbc:phoenix:thin:[key=value[;key=value...]]



예)



jdbc:phoenix:thin:url=http://localhost:8765



jdbc:phoenix:thin:url=http://queryserver.domain:8765;serialization=PROTOBUF;authentication=SPENGO;principal=phoenix@EXAMPLE.COM;keytab=/etc/security/keytabs/phoenix.keytab





주의할 점은 기본 phoenix query server를 실행했다면  serialization=PROTOBUF을 넣어줘야 한다!!



json을 사용하고 싶다면. hbase-site.xml에 phoenix.queryserver.serialization=JSON을 설정해야 한다. 

Posted by 김용환 '김용환'




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