Ace-T's Blog 내 검색 [네이버 커넥트 이웃 합니다~^-^/ 요청 大 환영~~]

Spring Boot + Spring Batch 분석_02

OpenSource/Spring Batch 2018.10.23 19:14
[Good Comment!!, Good Discussion!!, Good Contens!!]
[ If you think that is useful, please click the finger on the bottom~^-^good~ ]
by ace-T

2018/10/12 - [OpenSource/Spring Batch] - Spring Boot + Spring Batch 분석_01

 저번 분석에서는 Job에 대해서 알아보았습니다. 

이제 Step에 대해 알아보도록 하겠습니다.

설명하고 있는 소스는 https://spring.io/guides/gs/batch-processing/ 를 참고!

// tag::jobstep[]
    @Bean
    public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
        return jobBuilderFactory.get("importUserJob")
            .incrementer(new RunIdIncrementer())
            .listener(listener)
            .flow(step1)
            .end()
            .build();
    }

    @Bean
    public Step step1(JdbcBatchItemWriter<Person> writer) {
        return stepBuilderFactory.get("step1")
            .<Person, Person> chunk(10)
            .reader(reader())
            .processor(processor())
            .writer(writer)
            .build();
    }
    // end::jobstep[]
  • Step의 메소드명은 step1
  • 파라미터는 JdbcBatchItemWriter<Person> writer 
  • return은 stepBuilder
  • 내용을 파악하기 전에 SpringBatch의 Flow를 파악해보면 좋을것 같다.
    왜? 나는 chunk, reader, processor, writer를 알아야하는가?에 대한 답변이 될꺼라 생각한다.
  • SpringBatch Flow
  • 이제 하나하나씩 알아가보자.
  • chunk를 보자.
    • 우선 chunk(청크)란 배치선 덩어리 데이터들을 단위별로 묶어서 처리되어지는 수!
      즉, 위에 10이라는 뜻은 
      10개를 모아서 Chuck단위(10)로 트랜잭션을 이루고 있다고 보면 된다.
      트랜잭션 수행이기 때문에 실패 시 
      Chunk단위로 롤백이되고, 이전에 커밋된 트랜잭션까지는 반영이 된다는 뜻이다.
    • <Person, Person> chunk(10)에서 <Person, Person>은 제네릭 타입으로
      각 청크의 input과 output type을 나타낸다. 
    • ItemReader<Person>과 ItemWriter<Person>로 생각하면 된다.
  • reader(reader())를 보자.
    • reader? 뜻 그대로 읽어들이는 것이다. 무엇을? 데이터를~(txt, api, db 등등등)
       @Bean
          public FlatFileItemReader<Person> reader() {
              return new FlatFileItemReaderBuilder<Person>()
                  .name("personItemReader")
                  .resource(new ClassPathResource("sample-data.csv"))
                  .delimited()
                  .names(new String[]{"firstName", "lastName"})
                  .fieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
                      setTargetType(Person.class);
                  }})
                  .build();
          }
      
    • 위의 FlatFileItemReader는 SpringBatch에서 제공해주는 녀석이다.
      json, xml 형태가 아닌 말그대로 flat file을 읽어들인다.
      import org.springframework.batch.item.file.FlatFileItemReader;
      import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
    • FlatFileItemReaderBuilder! 이녀석 또한 Builder Pattern. 
      • name : reader instance명 
      • resource : 근원지 즉, read할 flat file.
      • delimited() : 명시적이지 않을 때 사용!
        DelimitedLineTokenizer를 작성하기위한 FlatFileItemReaderBuilder.DelimitedBuilder의 인스턴스를 리턴합니다. 이 빌더에 의해 구성된 DelimitedLineTokenizer는 lineTokenizer를 통해 명시적으로 구성되지 않은 경우에만 사용됩니다.
      • names : sample-data.csv의 내용과 names에서 선언한 포맷에 맞게 들어오게 되며 이 데이터는
      • fieldSetMapper()를 통해 DTO에 매핑 되어진다.
      • 예를 들어 아래의 데이터 중 Jane, Doe라고 한다면  String[]{"firstName", "lastName"}에 담긴다는 것이고 이것은 fieldSetMapper를 통해 객체에 담기게 된다. 

                  


    • processor(processor)
      • PersonItemProcessor는 ItemProcessor의 구현체이다.
        • Person객체를 input으로 하여 가공한 뒤에 output으로 Person을 리턴한다. 
          @Bean
              public PersonItemProcessor processor() {
                  return new PersonItemProcessor();
              }
          package hello;
          
          import org.slf4j.Logger;
          import org.slf4j.LoggerFactory;
          
          import org.springframework.batch.item.ItemProcessor;
          
          public class PersonItemProcessor implements ItemProcessor<Person, Person> {
          
              private static final Logger log = LoggerFactory.getLogger(PersonItemProcessor.class);
          
              @Override
              public Person process(final Person person) throws Exception {
                  final String firstName = person.getFirstName().toUpperCase();
                  final String lastName = person.getLastName().toUpperCase();
          
                  final Person transformedPerson = new Person(firstName, lastName);
          
                  log.info("Converting (" + person + ") into (" + transformedPerson + ")");
          
                  return transformedPerson;
              }
          
          }
        • 정리하면 processor의 역할은 read한 것을 가공하여 write에 주는 것이다.


  • writer(writer)
    • 이제 마지막으로 writer입니다.
      여기에서는 데이터베이스 관련 writer중 JdbcBatchItemWriter가 사용되어집니다.
@Bean
    public JdbcBatchItemWriter<Person> writer(DataSource dataSource) {
        return new JdbcBatchItemWriterBuilder<Person>()
            .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
            .sql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)")
            .dataSource(dataSource)
            .build();
    }
    • JdbcBatchItemWriterBuilder가 사용.
      • itemSqlParameterSourceProvider()
        • 작성자가 사용할 ItemSqlParameterSourceProvider를 구성합니다.
          beanMapped ()가 호출되지 않은 경우에만 사용해야합니다.
        • BeanPropertyItemSqlParmeterSourceProvider
          • SQL구문에서 파라미터에 사용되어지는 명명 중 JavaBean(Person)에 속성에 해당되면 
            공하여준다.
      • sql : sql구문
      • dataSource : @EnableBatchProcessing에 의해 생성.



'OpenSource > Spring Batch' 카테고리의 다른 글

Spring Boot + Spring Batch 분석_02  (0) 2018.10.23
Spring Boot + Spring Batch 분석_01  (0) 2018.10.12
SpringBatch 예제  (0) 2018.09.12
MyBatisPagingItemReader를 사용할 때 유의점  (0) 2015.10.02
Spring Batch 환경 셋팅  (0) 2012.09.03

acet 박태하가 추천하는 readtrend 추천글!

설정

트랙백

댓글

:::: facebook을 이용하시는 분들은 로그인 후 아래에 코멘트를 남겨주세요 ::::

Spring Boot + Spring Batch 분석_01

OpenSource/Spring Batch 2018.10.12 15:51
[Good Comment!!, Good Discussion!!, Good Contens!!]
[ If you think that is useful, please click the finger on the bottom~^-^good~ ]
by ace-T


주저리 

   spring boot를 사용하여 
   spring batch를 해보려는데 막상 spring batch를 잘모르면 제대로 못할것 같은 생각이 들었다.
   springframework를 spring boot기반으로 해볼때도 마찬가지였다.


구성

  • Job과 Step으로 구성.
    • Job
      • 여러개의 Step으로 구성.
        • Step은 ItemReader, ItemProcessor, ItemWriter의 구조이거나 
          이런 전형적인 구조가 아닐 경우 Tasklet 구조.

분석

    2018/09/12 - [OpenSource/Spring Batch] - SpringBatch 예제

    에서 처럼 https://spring.io/guides/gs/batch-processing/
   공식 사이트를 살펴보도록 하자.


org.springframework.boot:spring-boot-starter-batch 디펜던시는 요녀석!

Batch Job을 구성할 때 
Spring Batch는 따로 작성할 필요없이 비즈니스 로직에 집중할 수 있도록 많은 유틸리티를 제공한다.


BatchConfiguration! 이부분은 옛날 Spring Batch에서 xml로 구성되던 녀석이다.

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {


하나하나씩 보도록 하자. 우선 Factory를 DI 하는 것을 볼수 있다.

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

Factory는 Job과 Step에서 사용!
// tag::jobstep[]
    @Bean
    public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
        return jobBuilderFactory.get("importUserJob")
            .incrementer(new RunIdIncrementer())
            .listener(listener)
            .flow(step1)
            .end()
            .build();
    }

    @Bean
    public Step step1(JdbcBatchItemWriter<Person> writer) {
        return stepBuilderFactory.get("step1")
            .<Person, Person> chunk(10)
            .reader(reader())
            .processor(processor())
            .writer(writer)
            .build();
    }
    // end::jobstep[]


그리고 Step에서 사용되어지는 reader, processor, writer도 함께 구성.

    // tag::readerwriterprocessor[]
    @Bean
    public FlatFileItemReader<Person> reader() {
        return new FlatFileItemReaderBuilder<Person>()
            .name("personItemReader")
            .resource(new ClassPathResource("sample-data.csv"))
            .delimited()
            .names(new String[]{"firstName", "lastName"})
            .fieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
                setTargetType(Person.class);
            }})
            .build();
    }

    @Bean
    public PersonItemProcessor processor() {
        return new PersonItemProcessor();
    }

    @Bean
    public JdbcBatchItemWriter<Person> writer(DataSource dataSource) {
        return new JdbcBatchItemWriterBuilder<Person>()
            .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
            .sql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)")
            .dataSource(dataSource)
            .build();
    }
    // end::readerwriterprocessor[]


구조는 이러하고..이제 조금 더 자세하게 보도록 하자.

More and More


BatchConfiguration.java

  1. @Configuration : 설정 파일임을 알려준다. @MVC에서 @service @controller와 같다고 보면 된다.
  2. @EnableBatchProcessing : Batch 관련 유용한 유틸을 제공가능케 한다. 영어 고대로 Enable하겠다는 뜻.
  3. 위에서 언급한 내용처럼 Factory를 DI 하여 Job과 Step을 구성한다.
    1. Job은 Step으로 구성하여 만들어지고 Step은 reader, processor, writer를 구성할 수 있다.
  • 어노테이션 @Autowired로 DI 해주는 부분.
    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;
  • Job과 Step을 설정 해주는 부분.
    @Bean
    public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
        return jobBuilderFactory.get("importUserJob")
            .incrementer(new RunIdIncrementer())
            .listener(listener)
            .flow(step1)
            .end()
            .build();
    }

    @Bean
    public Step step1(JdbcBatchItemWriter<Person> writer) {
        return stepBuilderFactory.get("step1")
            .<Person, Person> chunk(10)
            .reader(reader())
            .processor(processor())
            .writer(writer)
            .build();
    } 
    • Job은 아래와 같이 importUserJob이라는 함수명을 가지며, 파라미터로는 listener, step
    • return으로는 JobBuilderFactory를 이용하여 Job을 리턴하는 구조이다.
      • jobBuilderFactory.get은 job builder를 생성하고 JobRepository를 초기화 시킨다.

[ Spring Batch 흐름도]

         

      • 아래를 좀 더 심화있게 이해하려면 builder pattern을 이해해야한다. 
      • 하지만 우선적으로 Spring Batch에 대해서 파악하는게 우선이다. 
      • 이제 돌아와서 incremeter를 보자.
        • JobBuilderHelper Class에 속해있는 method이다. 
        • JobBuilderHelper는 JobBuilder의 부모 클래스이다.
        • 포맷은 아래와 같다.
          • public B incrementer(JobParametersIncrementer jobParametersIncrementer)
          • 파라미터로 JobPrametersIncrementer를 가지는데 이것은 Interface 형태이다.
          • 이 Interface를 구현한 녀석이 위에 사용되어진 RunIdIncrementer Class 이다.
        • 그리고 incrementer 이녀석이 하는 역할은 JobParametersIncrementer 인터페이스의 
          역할을 보면 알수 있다. JobParameters를 취득하기 위한 인터페이스이기 때문이다.
        • JobParameters..! 이녀석을 이해하려면 아래의 그림을 이해해야한다.
        • 동시 다발적으로 돌아가는 Job들의 차이는 어떻게 알수가 있나? Job들 간의 구별? 그 해답은 JobParameters에 있다. 그래서 batch job을 시작할 때 이처럼 JobParameters를 취득한다.
          더욱 더 자세한 내용은 해당 링크를 참조. 

           

        • 그 다음으로 listener.
          • JobBuilderHelper Class에 속해 있는 Method이며, format은 아래와 같다.
            public B listener(JobExecutionListener listener)
          • JobExecutionListener도 Interface이며 지금 설명하는 소스에서는 
            JobCompletionNotificationListener Class에서 extends하고 있다.
          • JobCompletionNotificationListener.java
            package hello;
            
            import org.slf4j.Logger;
            import org.slf4j.LoggerFactory;
            import org.springframework.batch.core.BatchStatus;
            import org.springframework.batch.core.JobExecution;
            import org.springframework.batch.core.listener.JobExecutionListenerSupport;
            import org.springframework.beans.factory.annotation.Autowired;
            import org.springframework.jdbc.core.JdbcTemplate;
            import org.springframework.stereotype.Component;
            
            @Component
            public class JobCompletionNotificationListener extends JobExecutionListenerSupport {
            
            	private static final Logger log = LoggerFactory.getLogger(JobCompletionNotificationListener.class);
            
            	private final JdbcTemplate jdbcTemplate;
            
            	@Autowired
            	public JobCompletionNotificationListener(JdbcTemplate jdbcTemplate) {
            		this.jdbcTemplate = jdbcTemplate;
            	}
            
            	@Override
            	public void afterJob(JobExecution jobExecution) {
            		if(jobExecution.getStatus() == BatchStatus.COMPLETED) {
            			log.info("!!! JOB FINISHED! Time to verify the results");
            
            			jdbcTemplate.query("SELECT first_name, last_name FROM people",
            				(rs, row) -> new Person(
            					rs.getString(1),
            					rs.getString(2))
            			).forEach(person -> log.info("Found <" + person + "> in the database."));
            		}
            	}
            }
          • 위의 소스는 job이 BatchStatus.COMPLETED인가에 대해서 listen하고 있다. 그리고나서 JdbcTemplate를 사용한다.
        • 다음으로 flow.
          • JobBuilder Class에 속해 있는 Method이며, format은 아래와 같다.
            public JobFlowBuilder flow(Step step)
            딱 봐도 job과 step의 연결 & 수행. return으로는 a SimpleJobBuilder.
        • 다음으로 end. 즉, builder를 종료.
        • 다음으로 build() : 호출하여 최종적으로 a job builder를 리턴. 

지금까지 Job 관련 내용들을 살펴 보았습니다.

다음 포스팅에서는 비즈니스 로직을 당담하고 있는 Step에 대해서 알아보도록 하겠습니다.

2018/10/23 - [OpenSource/Spring Batch] - Spring Boot + Spring Batch 분석_02




'OpenSource > Spring Batch' 카테고리의 다른 글

Spring Boot + Spring Batch 분석_02  (0) 2018.10.23
Spring Boot + Spring Batch 분석_01  (0) 2018.10.12
SpringBatch 예제  (0) 2018.09.12
MyBatisPagingItemReader를 사용할 때 유의점  (0) 2015.10.02
Spring Batch 환경 셋팅  (0) 2012.09.03

acet 박태하가 추천하는 readtrend 추천글!

설정

트랙백

댓글

:::: facebook을 이용하시는 분들은 로그인 후 아래에 코멘트를 남겨주세요 ::::

BATCH, OLTP,OLAP,DW 정의

OS/Linux&Unix 2016.09.28 11:07
[Good Comment!!, Good Discussion!!, Good Contens!!]
[ If you think that is useful, please click the finger on the bottom~^-^good~ ]
by ace-T


OLTP,OLAP,DW 정의

Batch Processing

작업을 몰아두었다가 한번에 처리하는 시스템. 
예: 쇼핑몰로 예를 들면 하루가 지난 뒤에 전체 매장의 재고를 체크하고 현재의 상품에 대해 가격과 재고 등을 맞추는 작업을주기적으로 수행하는 작업을 말한다! 간단히 말해 데이터를 실시간이 아닌 전체적으로 맞추는 작업을 하거나 주기적으로 발생하는 것들에 대한 처리를 하는 것! 예시는 넘나어려운것..


OLTP: OnLine Transaction Processing

Batch 와 반대되는 개념으로 실시간으로 db의 데이터를 트랜잭션 단위로 갱신/조회하는 처리방식.
은행, 증권사 등에서 씀. 기존과 달리 다수의 client가 거의 동시에 이용할수 있도록 송수신자료를 트랜잭션단위로 
압축한것이 특징.


DW: Data Warehouse

수년간 발생한 데이터를 모아서 주제별로 합쳐 분석할 수 있게 하는 통합시스템.

예) 운영데이터, 분산데이터, 시장데이터를 추출하여 DW를 구축하고 그걸 DSS나 OLAP로 분석


※Data Mart: DW의 하위단위라고 볼 수 있으며, DW는 중앙집중식 데이터 집합체의 개념을 가지나, data mart는 데이터 저장소의 역할을 하고 특정 목적을 위해 쉬운 접근성과 사용성을 가진다. DW는 기존 데이터를 어떻게 수집/분석하고 어떻게 재사용할 것인가에 초점을 맞춤


OLAP:OnLine Analytical Processing

위의 DW에서 데이터를 분석해서 의미있는 형태로 만들기 위한 과정 및 도구.  
의사결정 지원 시스템의 하나.

※ 의사결정 지원 시스템(DSS, Decision Support System)

단순히 정보를 수집, 저장, 분배하기 위한 시스템을 넘어서 사용자들이 기업의 의사결정을 쉽게 내릴 수 있도록 사업 자료를 분석해주는 역할을 하는 컴퓨터 응용 프로그램이다.

예로 로그 분석을 통해 지표를 제공하는것이라고할 수 있을 것 같다.


출처 : http://neo-vector.blogspot.kr/2012/03/oltpolapdw.html

너무 잘 정리해주신!! 고맙삼다! 








'OS > Linux&Unix' 카테고리의 다른 글

top 명령&옵션  (0) 2016.12.21
Crontab을 이용해보자!  (0) 2016.11.11
BATCH, OLTP,OLAP,DW 정의  (0) 2016.09.28
SSH 유용정보!  (0) 2016.08.29
아직도 nohup으로 돌리세요?? - daemon ( daemon-0.6.4.tar.gz)  (0) 2016.06.21
펌] linux 디스크 용량 확인(df / du)  (0) 2016.01.19

acet 박태하가 추천하는 readtrend 추천글!

설정

트랙백

댓글

:::: facebook을 이용하시는 분들은 로그인 후 아래에 코멘트를 남겨주세요 ::::

티스토리 툴바