반응형


 안녕하세요. 오늘은 ZIP파일 안의 파일 중 한글명으로 된 파일이 있을 경우 해당 파일에 접근하지 못하는 문제를 COMMONS COMPRESS라이브러리를 통해 해결한 방법을 공유하도록 하겠습니다. 최근 작업 중에 고객들이 넣는 문의들 중 파일 첨부된 ZIP 파일의 경우 해당 ZIP파일 내에 .exe파일이 있는지 확인해 인입이 안되도록 처리해야 하는 작업이 있었습니다. 처음엔 COMMONS COMPRESS를 사용하지 않고 ZIP파일내의 파일들의 확장자를 확인하는 방법으로 작업하였습니다. 작업 후 테스트 결과 ZIP 파일 내에 한글명으로 된 파일이 있을 경우 제대로 파일내의 ZIPENTRY에 접근을 하지 못하는 문제점을 발견할 수 있었습니다. COMMONS COMPRESS 라이브러리를 통해 해결하였고 그 방법에 대해 포스팅하도록 하겠습니다.


[ 코 드 ]  

 


코드에서 보면 알겠지만 ZIP파일을 굳이 따로 디렉토리를 만들어 압축을 푼 후 체크하지 않고 ZipEntry를 통해 ZIP파일의 파일들에 접근하는 것을 볼 수 있다. 이렇게 JDK에서 지원하는 java.util.zip을 사용했을 경우 위에서 언급했던 대로 ZIP파일 내에 한글 파일 처리를 할 수 없는 문제가 발생합니다. 이를 해결하기 위한 방법으로는 jazzlib 및 commons-compress를 사용하는 방법이 있는데 jazzlib 같은 경우 라이브러리 자체도 상당히 오래 되었고 라이센스 문제가 발생할 수 있어 commons-compress를 사용하게 되었다. 



[ Commons Compress 적용 ]

먼저 메이븐 프로젝트이기 때문에 dependency를 추가해주었다. 

 


라이브러리를 추가 하고 다음과 같이 변경하였다.

 

다른 점은 ZipArchiveInputStream을 사용하여 인코딩 방식을 EUC-KR로 지정해 주었다. 수정 후 테스트를 해본 결과 ZIP파일 내에 한글명의 파일이 있을 경우에도 정확히 처리하는 것을 확인 할 수 있었다.



반응형
반응형

동시성 코드와 블로킹(blocking)콜 그리고 아카(akka)

여러 개의 스레드가 동시에 작업을 수행하더라도 synchronized 블록이나 데이터베이스, 네트워크 API 호출 등을 만날 다른 스레드와 나란히 줄을 서서 순차적으로 작업을 수행해야 하는 경우도 있다. 암달의 법칙은 프로그램이 있는 속도의 상한이 이런 순차적 코드가 사용하는 시간에 의해서 제한된다고 말한다. 이러한 순차적 코드의 다른 이름은 블로킹(blocking)콜이다. 조금 과장해서 말하자면 자바 개발자가 스레드를 이용해서 만들어내는 '동시성' 코드는 일종의 신기루다. 사실은 코드 곳곳에 존재하는 블로킹 , 순차적 코드 때문에 전체적인 프로그램의 처리율은 이미 상한이 정해져 있지만 여러개의 스레드가 '동시에' 동작한다는 사실로부터 위안을 받을 뿐이다.


아카(akka) 스칼라(scala)언어로 작성되었지만 아래로 내려가면 자바의 동시성 패키지를 사용하기 때문에 아카를 사용하는 것은 궁극적으로 자바의 Thread Task 사용하는 것과 마찬가지다. 하지만 아카를 사용하면 프로그램 곳곳에 존재하는 순차적 부분, 블로킹 콜을 전부 없애거나 최소한으로 만드는 것이 가능해진다. 아카(akka) 이용해서 프로그램을 설계하는 것은 블로킹 호출이 일어나는 지점을 논블로킹 호출로 전환하는 작업을 수행하는 것을 의미한다.



반응형
반응형

 

데이터 엔지니어로 살아가기 212일째(리타겟팅 시스템)

리타겟팅 시스템에 대해 요즘 매력을 느끼고 있다. 

어떻게 보면 단순한 프로세스이지만 단순한 프로세스로 부터나오는 효율은 단순하다고 말하기 힘들 같다내가 상품에 대한 데이터를 가지고 있다가 후에 내가 다른 사이트에 접근 했을 해당 광고를 내보낸다는게 쉬워보이지만  대상이 100만명 200만명이 되면 말이 달라진다. 

이면에는 수많은 작업들이 돌아가고 있을 것이고 작업 혹은 시스템에 문제가 없는지에 대해 모니터링을 하기 위한 시스템들이 열심히 돌아가고 있을 것이다.  많은 작업들 위에서 데이터 엔지니어들은 작업들이 정상적으로 돌아가고 있는지, 예외적인 케이스로 인해 문제가 발생하지 않는지에 대해 경계하며  효율적으로 작업들을 처리하기 위한 방안들을 모색하고 있다. 

요즘 모색하고 있는 방안 중에 하나는 현재 리타겟팅을 위해 광고주별로 추천 상품을 뽑고, 상품들에 대한 비슷한 맥락의 추천상품을 뽑아내는 작업에 대한 부분이다. 부분이 현재 pyspark으로 작업이 돌고 있는데 pyspark javaspark 비해서도 성능이 많이 떨어진다. 추후에 기회가 된다면 pyspark으로 작업되어 있는 부분들에 대한 개선 작업을 진행해보고 싶다는 것이다. 


반응형
반응형


hadoop(하둡)을 운영하다 보면 특정한 경우 hdfs에 나누어 저장되어 있는 파일들을 합쳐서 로컬로 받고 싶은 경우가 있다.

이 때 -getmerge명령어를 쓰면되는데 -text명령어로도 동일한 기능을 수행할 수 있다.

다만 주의해야할 차이점은 -text명령의 경우는 hdfs에 파일이 gz으로 묶여 쌓여있는 경우 압축을 풀어 라인을 읽어 로컬에 쓸 수 있는 반면에

-getmerge의 경우는 그렇지 않다. 따라서 합치고자 하는 파일이 .gz형태라면 -text를 사용해서 합쳐 로컬로 받는 방법이 훨씬 더 간편하다.


[ hdfs 예시 파일 ] 

!주의 .gz의 경우에는 -getmerge가 정상적으로 먹히지 않는다. (.gz일 때는 -text사용)

-rw-r--r--   3 irteam irteam      36997 2017-09-22 16:50 /log/temp/manual/part-00000

-rw-r--r--   3 irteam irteam    8828447 2017-09-22 16:59 /log/temp/manual/part-00001

-rw-r--r--   3 irteam irteam      38420 2017-09-22 16:49 /log/temp/manual/part-00002


[ -getmerge 사용법 ] 

hadoop fs -getmerge [hdfs경로] [로컬디렉토리]

 hadoop fs -getmerge  /log/temp/manual  /local/directory


[ -text 사용법 ] 

hadoop fs -text [hdfs경로] > [로컬디렉토리] 

hadoop fs -text /log/temp/manual/part-* > /local/direcotory


명령어 실행 후 로컬디렉토리에 저장된 파일의 개수를 세어보면 두 명령어로 실행한 데이터 개수가 동일한 것을 확인할 수 있다.

텍스트파일로 hdfs에 저장된 총 1241517라인(50M)로 테스트 해봤을 떄 로컬로 쓰는데 까지 두 명령어 모두 약 5초정도 걸렸다.

따라서 편한방법으로 사용하시길:)


반응형
반응형

[ 데이터 분석 정의 ]

데이터 분석은 데이터가 이해되고, 지식이 되고, 통찰을 얻게 되는 과정이다.

"Data analysis is the process which data becomes understanding, knowledge and insight"

-Hadley Wickham(해들리 위컴)-


R의 왕고수라고 불리운다...

Hadley Wickham, Chief Scientist at RStudio, and an Adjunct Professor of Statistics at the University of Auckland, Stanford University, and Rice University. 



반응형
반응형

하둡1.0과 하둡2.0의 차이는 YARN으로 인해 많은 부분이 변화되었다.

그 차이에 대해서 알아보도록 하자.

[ 아키텍처의 변화 ]


[ 하둡 1.0과 2.0에서 리소스 관리 차이 ]

하둡 1.0에서 맵리듀스를 실행할 때는 슬롯 단위로 맵/리듀스 태스크 갯수를 관리했다.따라서 맵퍼는 모두 동작하는데 리듀서는 놀고 있거나 반대의 경우로 인해 클러스터 전체 사용률이 낮았다.

하지만 하둡 2.0에서 YARN(얀)이 도입되면서 슬롯이 아닌 컨테이너 단위로 리소스를 할당하게 되었다. 얀의 리소스 매니저는 전체 클러스터의 리소스 정보를 토대로 할당 가능한 컨테이너 개수를 계산하며, 맵리듀스는 필요한 컨테이너들을 할당 받아서 맵리듀스 태스크를 실행하게 된다. 

이 때 컨테이너 개수와 맵과 리듀스 태스크의 관계는 1:1의 관계가 아니며, 맵과 리듀스 태스크는 상황에 따라서 하나 이상의 컨테이너를 실행할 수도 있다. 그래서 관리자는 전체 클러스터의 리소스 상황과 얀에서 실행하는 잡들의 워크로드를 고려하여 리소스 설정을 진행해야 한다.


[ YARN의 도입으로 JobTracker의 역할이 Resource Manager와 Application Master로 분리 ] 

하둡 1.0에서는 JobTracker(잡트래커)가 클러스터 리소스 관리 및 어플리케이션 스케쥴링 등을 모두 담당했었다.

하지만 하둡 2.0에서는 클러스터마다 Application Master(어플리케이션 마스터)가 존재하고 각 서버마다 Node Manager(노드 매니저)가 할당되어 있고 리소스관리는 Resource Manager(리소스 매니저)가 어플리케이션 수행 및 스케쥴링 관리는 Application Master(어플리케이션 마스터)로 역할이 분리되어 운영된다.


[ Spark 등 분산처리 환경 지원 ]

하둡의 맵/리듀스 작업보다 성능이 훨씬 개선된 SPARK 및 분산처리 프레임워크를 사용할 수 있게 되었다. 스파크는 배치 처리 작업에 있어서 맵리듀스보다 10배정도 빠르며 인메모리 분석에서 100배나 빠르다고 알려져 있다.




반응형
반응형

책 제목을 보고 굉장히 끌렸다가 내용이 생각보다 괜찮아서 바로 사버린 책


좋았던 내용만 공유해볼게요:)


  • 무엇이든 자주 시도해서 작은 성공의 경험들을 쌓아라. 악기를 배우든, 자격증을 따른, 세상엔 도전할 것이 많다. 세상에는 투입한 시간만큼 정직하게 실력이 느는 일들이 많고, 단계를 밟아 올라설 때마다 나는 성공한 사람이 되는 것이다. 그런 과정을 통해서 얻은 '나도 할 수 있다'는 자신감은 긍정의 바탕이 된다.
  • 한 번에 하루씩을 살며 눈앞의 일에 충실한 태도는 평범한 사람도 대단한 일을 할 수 있게 해준다.
  • 건강한 자신감으로 차 있는 그는 얼마나 매력적인지 모른다. 건강한 자부심은 사람들을 자석처럼 끌어모을 것이고, 앞으로의 인생에서 많은 것을 성취할 수 있는 에너지원이 되어 줄 것이다.
  • 사실 우유부단함은 어린아이의 특징이다. 어린아이는 어느 한쪽을 포기함으로써 생기는 손해를 감내하거나 선택의 결과에 책임을 질 능력이 없어서 어떤 상황에 대해 뚜렷한 입장을 취하는 것을 몹시 어려워한다. 어른이 되고도 우유부단하다는 것은 유아기에서 벗어나지 못했다는 의미이며, 20대 이후에도 그런 태도를 고치지 못하면 자아상이나 인간관계, 남녀관계, 직업적 성취 등 모든 면에서 기본적인 수준에조차 이르기 어렵다.
  • 당신이 누군가의 조언으로 도움을 받는 것은 꼭 자신의 그릇만큼이다. 당신의 그릇을 넘어서는 조언은 아무리 좋은 것이어도 저절로 흘러 넘쳐 쓰레기처럼 버려질 뿐이다.
  • 목표를 이루기 위해 노력을 쏟아부어본 사람은 이후 삶을 대하는 시각이 달라지고, 이전보다 무엇이든 더 잘 이루어 낼 수 있는 사람이 된다. '전혀 안 될 것처럼 보였던 일'이 자신의 힘으로 이루어지는 경험은 인생에서 훨씬 더 넓은 선택의 자유를 주고, 어떤 일을 할까 말까 망설이며 고민하는 시간을 줄여주기 때문이다. 
  • 타인에게 하는 말은 할까 말까 할 때 하지 않는 편이 후회가 적고, 지금 어떤 행동을 할까 말까 하는 갈등을 겪고 있을 때에는 하는 편이 후회가 적다.
  • 공감이 주는 재미는 머리가 띵하도록 웃게 만드는 유머보다 힘이 세다.
  • 돈을 빌려주지 않아서 생긴 섭섭한 감정은 쉽게 잊히지만, 돈이 오가서 문제가 생긴 관계는 절대로 회복되지 않는다.


20대의 막바지에 읽으며 느낀점은 '나름 20대를 잘보냈구나'하는 생각이였다. 다시 돌아간다고 해도 군대에서 화장실에서 몰래 공부하던 그 때, 방학동안 하루 종일 도서관에 틀어박혀 책만 읽던 그 때, 교환학생에서 매일 영어로 일기를 썼었던 그 시절 그 열정만큼 뜨겁게 보내긴 힘들 것 같다는 생각이 들었다. 뒤돌아보았을 때 후회가 적다는 건 그만큼 열심히 살았다는 증거이다. 후에 지금을 돌아봤을 때도 후회가 남지 않도록 하루 하루 감사하며 매순간 최선을 다할 수 있도록 하자~!


반응형
반응형

최근 자바 어플리케이션에서 hdfs파일을 local파일로 쓰는 외부 명령을 실행시켜야 하는 작업이 있었다.


Runtime 객체를 생성하고 exec 메소드를 이용하여 외부 명령을 실행시키는 프로세스를 생성하였다.


코드를 보면 알겠지만 command 명령에 파이프라인(|)이 사용되었다.


Runtime runtime = Runtime.getRuntime();

Process process = null;


String command = "hadoop fs -text /log/dmp_log/2017/09/19/dmp_log.*.1505786400000.gz | head -100"


process = runtime.exec(command);


이렇게 해서 동작을 시키니 100라인만 읽어와야하는데 해당 hdfs파일의 모든 로그를 읽어왔었다...


한참을 헤매다가 파이프라인(|)이 안먹는다는 생각이 들었고 찾아보니 문제가 있었다.


파이프라인(|)을 사용하는 것은 shell 실행 후 또 다른 프로세스로 실행하기 때문에 정상적으로 작동을 안한 것이다.


다음과 같이 해결을 하면 된다.


String commandHdfs = "hadoop fs -text /log/dmp_log/" + date + "/dmp_log.*." + unixTime + "000.gz | head -150";


String[] command = {

      "/bin/sh",

      "-c",

     commandHdfs

};


[ stack overflow 참고 ]

https://stackoverflow.com/questions/5928225/how-to-make-pipes-work-with-runtime-exec


간단히 요약하자면, 자바 어플레케이션에서 exec로 실행하는 system command는 실제로 unix, linux의 shell을 불러와 명령을 실행시키는게 아니라고하네요.


그렇기 때문에 쉘의 기능(shell feature)인 pipeline (파이프라인)을 사용하기 위해서는 명시적으로 shell(/bin/sh)을 불러주고 


해당 쉘 안에서 command를 실행시켜야 한다고 합니다.


더 정확한 원인을 알고 싶다면 참고부탁드려요

https://alvinalexander.com/java/java-exec-system-command-pipeline-pipe

반응형
반응형

스파크 작업을 하다보면 데이터 처리시 쿼리 기반의 spark sql, hive를 이용하기위해 orc로 데이터를 적재하는 경우가 많다.


이 때 spark-shell로 orc파일을 읽어들여 데이터를 보게되면 컬럼보다 데이터내용이 길게되면 잘려서 노출된다.


따라서 데이터 내용을 보고싶다면 dataframe형태의 데이터를 rdd로 만들어서 first나 rdd.take(n).foreach(println)식으로 보도록 하자



1. orc 파일 읽기

val data = sqlContext.read.format("orc").load("hdfs file directory")          //spark1.5,6 version


2. 읽어들인 데이터(dataframe형태)를 rdd로 변경하기

val rdd = data.rdd


3. rdd로 변경한 데이터 보기

rdd.first

rdd.take(n).foreach(println)         //n은 보고싶은 라인 개수




반응형

+ Recent posts