블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 

'batch'에 해당되는 글 5

  1. 2017.04.03 텐서플로우-배치 처리에 대해서 이해하자 (2)
  2. 2013.06.27 Spring Batch 개념 정리
  3. 2013.06.27 SpringBatch HelloWorld
  4. 2009.06.09 무료 ETL 솔루션 (3)
  5. 2007.11.28 SQL Batch
 


텐서플로우 배치 처리


조대협 (http://bcho.tistory.com)


텐서플로우에서 파일에서 데이타를 읽은 후에, 배치처리로 placeholder에서 읽는  예제를 설명한다.

텐서의 shape 의 차원과 세션의 실행 시점등이 헷갈려서 시행착오가 많았기 때문에 글로 정리해놓는다.

큐와 파일처리에 대한 기본적인 내용은 아래글

  • http://bcho.tistory.com/1163

  • http://bcho.tistory.com/1165

를 참고하기 바란다.

데이타 포맷

읽어 드릴 데이타 포맷은 다음과 같다. 비행기 노선 정보에 대한 데이타로 “년도,항공사 코드, 편명"을 기록한 CSV 파일이다.

2014,VX,121

2014,WN,1873

2014,WN,2787

배치 처리 코드

이 데이타를 텐서 플로우에서 읽어서 배치로 place holder에 feeding 하는 코드 이다

먼저 read_data는 csv 파일에서 데이타를 읽어서 파싱을 한 후 각 컬럼을 year,flight,time 으로 리턴하는 함 수이다.

def read_data(file_name):

   try:

       csv_file = tf.train.string_input_producer([file_name],name='filename_queue')

       textReader = tf.TextLineReader()

       _,line = textReader.read(csv_file)

       year,flight,time = tf.decode_csv(line,record_defaults=[ [1900],[""],[0] ],field_delim=',')    

   except:

       print "Unexpected error:",sys.exc_info()[0]

       exit()

   return year,flight,time


string_input_producer를 통해서 파일명들을 큐잉해서 하나씩 읽는데,여기서는 편의상 하나의 파일만 읽도록 하였는데, 여러개의 파일을 병렬로 처리하고자 한다면, [file_name]  부분에 리스트 형으로 여러개의 파일 목록을 지정해주면 된다.

다음 각 파일을 TextReader를 이용하여 라인 단위로 읽은 후 decode_csv를 이용하여, “,”로 분리된 컬럼을 각각  읽어서 year,flight,time 에 저장하여 리턴하였다.


다음 함수는 read_data_batch 라는 함수인데, 앞에서 정의한 read_data 함수를 호출하여, 읽어드린 year,flight,time 을 배치로 묶어서 리턴하는 함수 이다.


def read_data_batch(file_name,batch_size=10):

   year,flight,time = read_data(file_name)

   batch_year,batch_flight,batch_time = tf.train.batch([year,flight,time],batch_size=batch_size)

   

   return  batch_year,batch_flight,batch_time


tf.train.batch 함수가 배치로 묶어서 리턴을 하는 함수인데, batch로 묶고자 하는 tensor 들을 인자로 준 다음에, batch_size (한번에 묶어서 리턴하고자 하는 텐서들의 개수)를 정해주면 된다.


위의 예제에서는 batch_size를 10으로 해줬기 때문에, batch_year = [ 1900,1901….,1909]  와 같은 형태로 10개의 년도를 하나의 텐서에 묶어서 리턴해준다.

즉 입력 텐서의 shape이  [x,y,z] 일 경우 tf.train.batch를 통한 출력은 [batch_size,x,y,z] 가 된다.(이 부분이 핵심)


메인 코드

자 이제 메인 코드를 보자

def main():

   

   print 'start session'

   #coornator 위에 코드가 있어야 한다

   #데이타를 집어 넣기 전에 미리 그래프가 만들어져 있어야 함.

   batch_year,batch_flight,batch_time = read_data_batch(TRAINING_FILE)

   year = tf.placeholder(tf.int32,[None,])

   flight = tf.placeholder(tf.string,[None,])

   time = tf.placeholder(tf.int32,[None,])

   

   tt = time * 10


tt = time * 10 이라는 공식을 실행하기 위해서 time 이라는 값을 읽어서 피딩하는 예제인데 먼저 read_data_batch를 이용하여 데이타를 읽는 그래프를 생성한다. 이때 주의해야할점은 이 함수를 수행한다고 해서, 바로 데이타를 읽기 시작하는 것이 아니라, 데이타의 흐름을 정의하는 그래프만 생성된다는 것을 주의하자


다음으로는 year,flight,time placeholder를 정의한다.

year,flight,time 은 0 차원의 scalar 텐서이지만, 값이 연속적으로 들어오기 때문에, [None, ] 로 정의한다.

즉  year = [1900,1901,1902,1903,.....] 형태이기 때문에 1차원 Vector 형태의 shape으로 [None, ] 로 정의한다.

Placeholder 들에 대한 정의가 끝났으면, 세션을 정의하고 데이타를 읽어드리기 위한 Queue runner를 수행한다. 앞의 과정까지 텐서 그래프를 다 그렸고, 이 그래프 값을 부어넣기 위해서, Queue runner 를 수행한 것이다.


   with tf.Session() as sess:

       try:


           coord = tf.train.Coordinator()

           threads = tf.train.start_queue_runners(sess=sess, coord=coord)


Queue runner를 실행하였기 때문에 데이타가 데이타 큐로 들어가기 시작하고, 이 큐에 들어간 데이타를 읽어드리기 위해서, 세션을 실행한다.

               y_,f_,t_ = sess.run([batch_year,batch_flight,batch_time])

               print sess.run(tt,feed_dict={time:t_})

세션을 실행하면, batch_year,batch_flight,batch_time 값을 읽어서 y_,f_,t_ 변수에 각각 집어 넣은 다음에, t_ 값을 tt 공식의 time 변수에 feeding 하여, 값을 계산한다.


모든 작업이 끝났으면 아래와 같이 Queue runner를 정지 시킨다.

           coord.request_stop()

           coord.join(threads)


다음은 앞에서 설명한 전체 코드이다.


import tensorflow as tf

import numpy as np

import sys


TRAINING_FILE = '/Users/terrycho/dev/data/flight.csv'


## read training data and label

def read_data(file_name):

   try:

       csv_file = tf.train.string_input_producer([file_name],name='filename_queue')

       textReader = tf.TextLineReader()

       _,line = textReader.read(csv_file)

       year,flight,time = tf.decode_csv(line,record_defaults=[ [1900],[""],[0] ],field_delim=',')    

   except:

       print "Unexpected error:",sys.exc_info()[0]

       exit()

   return year,flight,time


def read_data_batch(file_name,batch_size=10):

   year,flight,time = read_data(file_name)

   batch_year,batch_flight,batch_time = tf.train.batch([year,flight,time],batch_size=batch_size)

   

   return  batch_year,batch_flight,batch_time


def main():

   

   print 'start session'

   #coornator 위에 코드가 있어야 한다

   #데이타를 집어 넣기 전에 미리 그래프가 만들어져 있어야 함.

   batch_year,batch_flight,batch_time = read_data_batch(TRAINING_FILE)

   year = tf.placeholder(tf.int32,[None,])

   flight = tf.placeholder(tf.string,[None,])

   time = tf.placeholder(tf.int32,[None,])

   

   tt = time * 10


   with tf.Session() as sess:

       try:


           coord = tf.train.Coordinator()

           threads = tf.train.start_queue_runners(sess=sess, coord=coord)


           for i in range(10):

               y_,f_,t_ = sess.run([batch_year,batch_flight,batch_time])

               print sess.run(tt,feed_dict={time:t_})


           print 'stop batch'

           coord.request_stop()

           coord.join(threads)

       except:

           print "Unexpected error:", sys.exc_info()[0]


main()


다음은 실행결과이다.



Spring Batch 개념 정리

프로그래밍/Spring & Maven | 2013.06.27 20:43 | Posted by 조대협


Spring Batch의 주요 개념

 




Job

하나의 배치 작업을 정의. 예를 들어 "API 서버의 사용로그 테이블의 데이타를 로그 분석 시스템으로 옮기는 배치"

Job Instance

배치가 실제 실행되면, 각각의 실행을 Instance라고 한다. 예를 들어 Batch Job이 매주 한번씩 수행된다고 할때, 각각의 수행되는 Batch Job Batch Instance라고 한다.

Job Execution

배치가 실행될때, 각 배치의 실행시, 실제 수행된 Execution을 정의한다. 예를 들어 Batch Job이 월요일 오전에 수행되었을때, 첫번째 실패하고, 두번째에 Retry에 의해 성공되었다면, 이 각각은 다른 Job Execution이 되고, 같은 작업을 시도하였기 때문에, 같은 Job Instance가 된다.

Job Parameter

매번 배치 작업이 수행될때 마다 전달되는 Parameter이다. 예를 들어 매주 수행되는 배치가 있을때, 시작 시간, 데이타를 읽을 범위 등을 지정하여, Batch Job Instance를 생성한다면, 이렇게 넘어가는 인자가 JobParameter이다.

 

Spring에서 Batch Job의 구성

Step

Spring에서 Batch Job Step의 모음으로 구성된다. Job Step이 순차적으로 수행되게 된다.

Tasklet

Tasklet은 각 Step에서 수행되는 로직이다. 개발자가 Custom Logic을 만들 수 도 있고, 또는 보통 Batch의 경우 데이타를 ETL (Extract, Transform, Loading) 하는 형태이기 때문에, Spring Batch에서 미리 정의해놓은 Reader, Processor,Writer Interface를 사용할 수 있다.

     ItermReader - 데이타를 읽는 컴포넌트

     ItemProcessor - 읽은 이타를 처리

     ItemWriter - 처리한 데이타를 저장

 

이해를 돕기 위한 Sample Configuraion

<job id="ioSampleJob">

        <step id="step1“ next=“step2”>

            <tasklet>

                <chunk reader="itemReader" writer="itemWriter" commit-interval="2"/>

            </tasklet>

        </step>

       <step id=“step2”>

          <tasklet ref=“CustomTaskletClass />

       </step>

</job>

 

※ Custom Tasklet을 이용한 간단한 예제 http://bcho.tistory.com/762

'프로그래밍 > Spring & Maven' 카테고리의 다른 글

Spring boot 살펴본 느낌  (2) 2014.11.25
Spring Batch (DB2File)  (0) 2013.06.27
Spring Batch 개념 정리  (0) 2013.06.27
SpringBatch HelloWorld  (0) 2013.06.27
Eclipse에서 Spring Maven 개발환경 설정하기  (0) 2013.03.19
Maven 스터디  (0) 2013.03.19

SpringBatch HelloWorld

프로그래밍/Spring & Maven | 2013.06.27 16:35 | Posted by 조대협

SpringBatch 2.0을 이용하여, HelloWorld를 출력하는 가장 기본적인 Job 만들기


hellobatch1.zip


Spring 3.1, SpringBatch 2.2 사용

maven으로 되어 있음

압축풀고 run.cmd 로 실행


'프로그래밍 > Spring & Maven' 카테고리의 다른 글

Spring Batch (DB2File)  (0) 2013.06.27
Spring Batch 개념 정리  (0) 2013.06.27
SpringBatch HelloWorld  (0) 2013.06.27
Eclipse에서 Spring Maven 개발환경 설정하기  (0) 2013.03.19
Maven 스터디  (0) 2013.03.19
Spring 프레임웍 Hadoop-Hive 통합  (0) 2013.03.19

무료 ETL 솔루션

아키텍쳐 | 2009.06.09 10:30 | Posted by 조대협
Enterprise Architecture 에서 중요한것중의 하나가 ETL (Extract Transformation Loading)이다. 쉽게 이야기 하면, 비동기적으로 파일이나 DB간에 데이타를 동기화 해주는 솔루션인데 기업 아키텍쳐에서 흔히 Near Real Time이라는 형태의 Async로 구현되거나 또는 Batch성 작업으로 분류되는데. 사실 이 ETL 솔루션이 만만한것이 그리 많지 않다. 대부분 EAI에서 ETL 기능을 구현해서 사용하는데, 데이타 양이 많다 보니 성능이나 구현의 생산성에서 애로점이 있는 것이 사실이다. 그래서 EAI 솔루션 위에서 Custom Module로 개발을 하거나 Spring Batch와 같은 오픈소스 프레임웍을 이용해서 구현하는 경우가 많은데 오늘 아주 어이없는 툴을 소개받았다. http://www.talend.com/store/index.php# 오픈소스다. 물론 Support나 Consulting은 유료다. 그러나 그게 더 낫지 않은가? 오픈소스라고 보기에는 완성도가 너무나도 높다... 국내에는 아직 사용하는 사람이 없는것 같은데, ETL 아키텍쳐 구현에 저 비용을 고려하고 있다면 아주 좋은 대안이 되지 않을까? 이런 오픈소스들 몇개 모아다가 사업해도 되겠다. Talend, Liferay 포탈, Durupal 이런것들...

== 덧붙임 ==
이미 오픈소스 ETL 솔루션을 쓰시는 분이 계셨군요.
http://mixellaneous.tistory.com
Talend 뿐만 아니라, 또 다른 ETL 도구인 POI에 대해서도 설명이 잘 나와 있습니다. 참고하시길.

'아키텍쳐' 카테고리의 다른 글

아키텍쳐 설계 프로세스  (1) 2012.09.04
Open source http proxy tool  (0) 2009.12.24
무료 ETL 솔루션  (3) 2009.06.09
재미있는 X.25 관련 장비 (Athena X.25 switch)  (0) 2008.06.17
Velocity & Sitemesh  (1) 2008.03.31
WLS 10.3 진화는 어디까지?  (0) 2007.11.08

SQL Batch

프로그래밍/프로그래밍팁 | 2007.11.28 15:27 | Posted by 조대협

대용량 SQL을  한꺼번에 수행할때

for(..){
 pstmt.setXX
 pstmt.executeUpdateXX
}
tx.commit

이 코드는 느리다.
for(..){
 pstmt.setXX
 pstmt.addBatch
}
pstmt.executeBatchXX
tx.commit

이렇게 하는게 성능에 5~10배까지 차이가 난다.

===

아래는 직접 테스트 한 코드 10배 정도 차이가 나는것을 볼 수 있다.

<%

        Context ctx = new InitialContext();
        javax.sql.DataSource ds = (javax.sql.DataSource)
                ctx.lookup("bchoDS");
        Connection conn = ds.getConnection();
        conn.setAutoCommit(false);
        Statement stmt = conn.createStatement();
        stmt.executeUpdate("delete from bcho");
        conn.commit();
        stmt.close();

        long start = System.currentTimeMillis();
        out.println("start :"+start);

        String sql = "insert into bcho values( ?,'seoul')";
        PreparedStatement pstmt = conn.prepareStatement(sql);

        for(int j=0;j<10;j++){
          for(int i=0;i<10000;i++){
                pstmt.setString(1,"DUMMY");
                pstmt.executeUpdate();
          }
          Statement cstmt = conn.createStatement();
          cstmt.executeUpdate("commit work write batch nowait");
          cstmt.close();

        }// for j
        pstmt.close();
        conn.close();

        long end = System.currentTimeMillis();
        out.println("<BR>end :"+end);
        out.println("<BR>elapsed :"+(end-start));

%>


==== 아래는 BATCH

<%

        Context ctx = new InitialContext();
        javax.sql.DataSource ds = (javax.sql.DataSource)
                ctx.lookup("bchoDS");
        Connection conn = ds.getConnection();
        conn.setAutoCommit(false);
        Statement stmt = conn.createStatement();
        stmt.executeUpdate("delete from bcho");
        conn.commit();
        stmt.close();

        long start = System.currentTimeMillis();
        out.println("start :"+start);

        String sql = "insert into bcho values( ?,'seoul')";
        PreparedStatement pstmt = conn.prepareStatement(sql);

        for(int j=0;j<10;j++){
          for(int i=0;i<10000;i++){
                pstmt.setString(1,"DUMMY");
                pstmt.addBatch();
          }
          pstmt.executeBatch();
          conn.commit();

        }// for j
        pstmt.close();
        conn.close();

        long end = System.currentTimeMillis();
        out.println("<BR>end :"+end);
        out.println("<BR>elapsed :"+(end-start));

%>


BATCH elapsed :270  msec
COMMIT elapsed :24512 msec

===

애플리케이션에서 다른 업무와 함께 테스트 했을때는 2배 정도 차이가 났음.

'프로그래밍 > 프로그래밍팁' 카테고리의 다른 글

NIO  (0) 2008.02.27
JDK 1.5 부터 등장한 ThreadPool  (0) 2008.02.27
SQL Batch  (0) 2007.11.28
대용량 Record select  (0) 2007.11.28
Java Application의 Locking 처리문제  (0) 2007.08.21
업그레이드된 개발자 되기  (6) 2007.08.20