Range Partitioning 예제 - 설정

2018. 12. 17. 23:08Spring Batch

반응형

Range Partitioning 설정

테이블이 특정 컬럼을 지정하여 분할하고자 하는 수 만큼의 작업을 분할하여 대용량 데이터를 처리를 위한 예제이다.

 

 

사전준비

예제를 작성하기 앞서 샘플 데이터 입수, 테이블 생성, 샘플 데이터 등록, Partitioning 처리를 위한 자바 클래스를 작성한다.

 

 

 

샘플데이터준비


Kaggle 사이트에서 Black Friday 자료를 다운 받는다.

다운로드사이트: https://www.kaggle.com/sdolezel/black-friday

 

 

데이터베이스 테이블 생성


MySQL 테이블 생성 스크립트

CREATE TABLE `black_friday` (
	`user_id` varchar(10) NOT NULL,
	`product_id` varchar(10) NOT NULL,
	`gender` varchar(5) NOT NULL,
	`age` varchar(10) DEFAULT NULL,
	`occupation` varchar(2) DEFAULT NULL,
	`city_category` varchar(5) DEFAULT NULL,
	`stay_in_current_city_years` varchar(4) DEFAULT NULL,
	`marital_status` varchar(5) DEFAULT NULL,
	`product_category_1` varchar(5) DEFAULT NULL,
	`product_category_2` varchar(5) DEFAULT NULL,
	`product_category_3` varchar(5) DEFAULT NULL,
	`purchase` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

 

Oralce 테이블 생성 스크립트

CREATE TABLE BLACK_FRIDAY (
	USER_ID VARCHAR2(10 BYTE) NULL, 
	PRODUCT_ID VARCHAR2(10 BYTE) NULL, 
	GENDER VARCHAR2(5 BYTE) NULL, 
	AGE VARCHAR2(10 BYTE) NULL, 
	OCCUPATION VARCHAR2(2 BYTE) NULL, 
	CITY_CATEGORY VARCHAR2(5 BYTE) NULL, 
	STAY_IN_CURRENT_CITY_YEARS VARCHAR2(4 BYTE) NULL, 
	MARITAL_STATUS VARCHAR2(5 BYTE) NULL, 
	PRODUCT_CATEGORY_1 VARCHAR2(5 BYTE) NULL, 
	PRODUCT_CATEGORY_2 VARCHAR2(5 BYTE) NULL, 
	PRODUCT_CATEGORY_3 VARCHAR2(5 BYTE) NULL, 
	PURCHASE VARCHAR2(10 BYTE) NULL
)

 

 

CSV 파일 자료 DB 등록


MySQL 테이블에 FileDelimiterDbToJob 예제를 이용하여 다운로드 받은 CSV 자료를 INSERT 한다.
자료를 더 추가하위해 아래 처럼 원하는 만큼 쿼리를 수행한다.  

 

insert into black_friday
select cast(user_id as unsigned) + 1000000
	, product_id
	, gender
	, age
	, occupation
	, city_category
	, stay_in_current_city_years
	, marital_status
	, product_category_1
	, product_category_2
	, product_category_3
	, purchase
from black_friday

insert into black_friday
select cast(user_id as unsigned) + 2000000
	, product_id
	, gender
	, age
	, occupation
	, city_category
	, stay_in_current_city_years
	, marital_status
	, product_category_1
	, product_category_2
	, product_category_3
	, purchase
from black_friday
where substr(user_id,1,1) = 1

 

 

ColumnRagePartitioner.java 작성


프로그램의 역할은 사용자가 설정한 수 만큼의 쓰레드를 생성 하여 주며 사용자가 지정한 테이블의 컬럼을 이용하여 나누어준 쓰레드수 만큼데이터를 분할 처리 할 수 있도록 하여 준다.

 

소스출처: https://github.com/spring-projects/spring-batch/blob/master/spring-batch-samples/src/main/java/org/springframework/batch/sample/common/ColumnRangePartitioner.java

 

package com.batchguide.partitioner;

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.partition.support.Partitioner;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;

public class ColumnRangePartitioner implements Partitioner {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(ColumnRangePartitioner.class);

	private JdbcOperations jdbcTemplate;

	private String table;

	private String column;

	/**
	 * 테이블이름 설정
	 *
	 * @param table the name of the table
	 */
	public void setTable(String table) {
		this.table = table;
	}

	/**
	 * 분할대상 컬럼명 설정
	 *
	 * @param column the column name.
	 */
	public void setColumn(String column) {
		this.column = column;
	}

	/**
	 * 데이터베이스 접속을 위한 DataSource 설정
	 *
	 * @param dataSource a {@link DataSource}
	 */
	public void setDataSource(DataSource dataSource) {
		jdbcTemplate = new JdbcTemplate(dataSource);
	}

	/**
	 * 테이블에 지정된 열의 최소값과 최대값을 반환한다.
	 *
	 * @see Partitioner#partition(int)
	 */
	@Override
	public Map<String, ExecutionContext> partition(int gridSize) {
		int min = jdbcTemplate.queryForObject("SELECT MIN(" + column + ") from " + table, Integer.class);
		int max = jdbcTemplate.queryForObject("SELECT MAX(" + column + ") from " + table, Integer.class);
		int targetSize = (max - min) / gridSize + 1;

		Map<String, ExecutionContext> result = new HashMap<>();
		int number = 0;
		int start = min;
		int end = start + targetSize - 1;

		while (start <= max) {
			ExecutionContext value = new ExecutionContext();
			result.put("partition" + number, value);

			if (end >= max) {
				end = max;
			}
			value.putInt("minValue", start);
			value.putInt("maxValue", end);
			start += targetSize;
			end += targetSize;

			LOGGER.info("partition#{} minValue is {} and maxValue {}", number, start, end);
			
			number++;
		}

		return result;
	}
}

 

- grid-size 만큼 사용자가 지정한 테이블의 컬럼의 minValue, maxValue 계산하여서 반환 처리한다.

 

 

[소스레파지토리]

☞ https://github.com/roopy1210/springbatch/blob/master/spring_batch_tutorial

반응형

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

ORA_HASH를 이용한 Partitioning 구현  (1) 2018.12.26
Range Partitioning 예제 - 구현  (0) 2018.12.18
CompositeItemWriter 예제 - 구현  (0) 2018.12.02
CompositeItemWriter 예제 - 설정  (0) 2018.12.02
DB To File 예제  (0) 2018.11.14