今日の世界でインターネットは私たちの生活の方法を変え、その大きな理由の1つは、毎日の雑用のほとんどにインターネットが使用されているためです。 3313>
膨大なデータを扱う例としては、給与明細、銀行明細、利息計算などの処理が挙げられます。 もし、これらの仕事をすべて手作業で行わなければならないとしたら、これらの仕事を終えるのに何年もかかるでしょう。
現代ではどのように行われているのでしょうか。
はじめに
バッチ処理はバルクデータに対して行われ、人手を介さず、長時間にわたって実行される。 データまたは計算を大量に必要とする場合があります。 バッチジョブは事前に定義されたスケジュールで実行することも、要求に応じて開始することもできます。 また、バッチジョブは通常、長時間実行されるジョブであるため、一定のチェックと特定の障害からの再開がバッチジョブに見られる一般的な機能である
1.1 Javaバッチ処理の歴史
Javaプラットフォームのバッチ処理は、Java EE 7プラットフォームの一部であるJSR 352仕様の一部として導入され、バッチアプリケーションのプログラミングモデルに加えて、バッチジョブを実行および管理するランタイムを定義する。
1.2 Javaバッチのアーキテクチャ
以下の図にバッチ処理の基本コンポーネントを示す。
Java バッチ処理のためのアーキテクチャ
バッチアプリケーションのためのアーキテクチャは、ジョブ、ステップ、リポジトリ、リーダープロセッサ、ライターパターン、チャンク、チェックポイント、並列処理、フロー、リトライ、シーケンス、パーティショニングなどのバッチ処理に関する問題を解決する。
- ジョブリポジトリには、実行する必要があるジョブが格納されています。
-
JobLauncher
は、ジョブリポジトリからジョブを取り出します。 - Item Readerはデータを読み込むものです。
- Item Processはビジネスロジックに基づいてデータを処理するものです。
- アイテムライターは、定義されたソースにデータを書き戻します。
1.3 バッチ処理コンポーネント
ここで、バッチ処理コンポーネントを詳しく理解しましょう。 ジョブは、バッチ処理全体を構成するものです。 1つまたは複数のステップが含まれます。 ジョブは、ステップの実行順序を指定するJob Specification Language (JSL)を使ってまとめられる。 JSR352では、JSLはジョブXMLファイルとして知られるXMLファイルで指定される。 ジョブは基本的にステップを保持するコンテナである
JobOperator
はこのリポジトリにアクセスするためのAPIを提供します。 以下のセクションは、バッチアーキテクチャの一般的な特徴を理解するのに役立ちます。
1.3 ジョブのステップ
ステップは、ジョブの独立したフェーズです。 上述したように、ジョブのステップには2つのタイプがあります。
1.3.1 チャンク指向ステップ
チャンクステップは一度に1つのアイテムを読み込んで処理し、その結果をチャンクにまとめます。 そして、チャンクがあらかじめ定義されたサイズに達すると、結果が格納されます。 チャンク指向処理は、データセットが巨大な場合に結果の保存をより効率的にする。
- アイテムリーダーは、データベース、フラットファイル、ログファイルなどのデータソースから次々と入力を読み取る。
- プロセッサは、定義されたビジネスロジックに基づいてデータを1つずつ処理する。 チャンクのサイズはあらかじめ定義されており、設定可能です
チャンクのステップの一部として、チャンクの完了のための情報をフレームワークに提供するチェックポイントがあります。
1.3.2 タスク指向ステップ
これは、データソースからのアイテムの処理以外のタスクを実行するものです。 ディレクトリの作成・削除、ファイルの移動、データベーステーブルの作成・削除などが含まれます。
通常のシナリオでは、タスク指向のステップは、クリーンアップが必要なチャンク指向のステップの後に使用されます。 たとえば、アプリケーションの出力としてログファイルを取得します。
1.3.3 並列処理
バッチジョブはしばしば高価な計算処理を実行し、大量のデータを処理します。 バッチアプリケーションは、2つのシナリオで並列処理の恩恵を受けることができます。
- 本質的に独立したステップは、異なるスレッドで実行できます。
- 各項目の処理が前の項目の処理結果から独立しているジャンク指向のステップは、複数のスレッドで実行できます。
バッチ処理は、巨大なデータに対してより速くタスクを完了し、処理を実行するのに役立ちます。
ツールとテクノロジー
プログラム構築に使用したテクノロジーとツールを見てみましょう。 Release (4.7.2)
プロジェクトの構造
プロジェクトの構造は下の画像のようになる予定です。
Java Batchのプロジェクト構造
上記のプロジェクト構造は、Gradleを使用しています。 このプロジェクトは、maven を使用して作成することもでき、build.gralde は pom.xml ファイルに置き換えられます。
An objective of the Program
As a part of the program, we will try to create a simple java batch application using spring boot.プロジェクトの構造は、ビルドにMavenを使用することで若干延期されるでしょう。 このアプリケーションは、次のタスクを実行します。
- 読み込み: – CSVファイルから社員データを読み込みます。
- データを処理します。 – 従業員データをすべて大文字に変換します。 – 処理した社員データをデータベースに書き戻す.
4.1 Gradle build
プログラムの一部として、ビルドにGradleを使用しています。 build.gradle
ファイルは以下のようになります。
build.gradle
buildscript { repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.1.RELEASE") }}apply plugin: 'java'apply plugin: 'eclipse'apply plugin: 'idea'apply plugin: 'org.springframework.boot'apply plugin: 'io.spring.dependency-management'bootJar { baseName = 'java-batch' version = '1.0'}repositories { mavenCentral()}sourceCompatibility = 1.8targetCompatibility = 1.8dependencies { compile("org.springframework.boot:spring-boot-starter-batch") compile("org.hsqldb:hsqldb") testCompile("junit:junit")}
上記の build.gradle
ファイルで apply plugin: 'java'
は設定する必要があるプラグインを示します。 repositories{}
は依存関係が引き出されるべきリポジトリを知らせています。 私たちは、依存関係の jar を取得するために mavenCentral
を選択しました。 jcenter
もそれぞれの依存性 jar を取得するために使用できます。
dependencies {}
タグは、プロジェクトに取得する必要がある jar ファイルの詳細を提供するために使用されます。 apply plugin: 'org.springframework.boot'
このプラグインは、spring-boot プロジェクトを指定するために使用されます。 boot jar{}
は、ビルドから生成される jar のプロパティを指定します。
4.2 サンプル データ ファイル
読み取りフェーズにデータを提供するために、従業員データを含む CSV ファイルを使用します。
4.3 SQLスクリプト
メモリベースのデータベースであるHSQLデータベースを使用しています。
SQL スクリプト
DROP TABLE employee IF EXISTS;CREATE TABLE employee ( person_id BIGINT IDENTITY NOT NULL PRIMARY KEY, first_name VARCHAR(20), last_name VARCHAR(20));
Spring Boot は起動時に schema-@@platform@@.sql
を自動的に実行します。 -all
はすべてのプラットフォームでデフォルトです。 そのため、テーブルの作成はアプリケーションの起動時に勝手に行われ、アプリケーションが稼働するまで利用できます。
4.4 モデルクラス
モデルクラスとしてEmployee.java
クラスを作成することにします。
プログラムのモデルクラス
package com.batch;public class Employee { private String lastName; private String firstName; public Employee() { } public Employee(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } @Override public String toString() { return "firstName: " + firstName + ", lastName: " + lastName; }}
@Override
は、toString()
メソッドのデフォルト実装をオーバーライドするために使用します。
4.5 設定クラス
バッチ処理用の設定クラスとなる BatchConfiguration.java
クラスを作成する予定です。
BatchConfiguration.java
package com.batch.config;import javax.sql.DataSource;import org.springframework.batch.core.Job;import org.springframework.batch.core.JobExecutionListener;import org.springframework.batch.core.Step;import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;import org.springframework.batch.core.launch.support.RunIdIncrementer;import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;import org.springframework.batch.item.database.JdbcBatchItemWriter;import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder;import org.springframework.batch.item.file.FlatFileItemReader;import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;import org.springframework.batch.item.file.mapping.DefaultLineMapper;import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.ClassPathResource;import org.springframework.jdbc.core.JdbcTemplate;import com.batch.Employee;import com.batch.processor.EmployeeItemProcessor;@Configuration@EnableBatchProcessingpublic class BatchConfiguration { @Autowired public JobBuilderFactory jobBuilderFactory; @Autowired public StepBuilderFactory stepBuilderFactory; // tag::readerwriterprocessor @Bean public FlatFileItemReader reader() { return new FlatFileItemReaderBuilder() .name("EmployeeItemReader") .resource(new ClassPathResource("sample-data.csv")) .delimited() .names(new String{"firstName", "lastName"}) .fieldSetMapper(new BeanWrapperFieldSetMapper() {{ setTargetType(Employee.class); }}) .build(); } @Bean public EmployeeItemProcessor processor() { return new EmployeeItemProcessor(); } @Bean public JdbcBatchItemWriter writer(DataSource dataSource) { return new JdbcBatchItemWriterBuilder() .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>()) .sql("INSERT INTO employee (first_name, last_name) VALUES (:firstName, :lastName)") .dataSource(dataSource) .build(); } // end::readerwriterprocessor // 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 writer) { return stepBuilderFactory.get("step1") .<Employee, Employee> chunk(10) .reader(reader()) .processor(processor()) .writer(writer) .build(); } // end::jobstep}
@EnableBatchProcessing
アノテーションはバッチ処理を有効にするために使用します。JobBuilderFactory
はジョブの構築に使用するファクトリーです。 これは、入力を定義されたサイズにチャンキングするために使用されるプロパティです。
4.6 Item Processor
Itemプロセッサは、データの処理を担当するインターフェースである。 このインターフェイスをEmployeeItemProcessor.java
で実装する。
EmployeeItemProcessor.java
package com.batch.processor;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.batch.item.ItemProcessor;import com.batch.Employee;public class EmployeeItemProcessor implements ItemProcessor<Employee, Employee> { private static final Logger log = LoggerFactory.getLogger(EmployeeItemProcessor.class); @Override public Employee process(Employee emp) throws Exception { final String firstName = emp.getFirstName().toUpperCase(); final String lastName = emp.getLastName().toUpperCase(); final Employee transformedEmployee = new Employee(firstName, lastName); log.info("Converting (" + emp + ") into (" + transformedEmployee + ")"); return transformedEmployee; }}
process()
メソッドでデータを取得し、大文字の名前に変換します。
4.7 JobExecutionSupportListenerクラス
JobExecutionListenerSupport
ジョブが終了すると通知を行うためのインターフェイスです。 インターフェイスの一部として、afterJob
メソッドがあります。
JobCompletionNotificationListener.java
package com.batch.config;import java.util.List;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.jdbc.core.RowMapper;import org.springframework.stereotype.Component;import com.batch.Employee;@Componentpublic class JobCompletionNotificationListener extends JobExecutionListenerSupport {private static final Logger log = LoggerFactory.getLogger(JobCompletionNotificationListener.class);private final JdbcTemplate jdbcTemplate;@Autowiredpublic JobCompletionNotificationListener(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}@Overridepublic void afterJob(JobExecution jobExecution) {RowMapper rowMapper = (rs, rowNum) -> {Employee e = new Employee();e.setFirstName(rs.getString(1));e.setLastName(rs.getString(2));return e;};if(jobExecution.getStatus() == BatchStatus.COMPLETED) {log.info("!!! JOB FINISHED! Time to verify the results");List empList= jdbcTemplate.query("SELECT first_name, last_name FROM employee",rowMapper);log.info("Size of List "+empList.size());for (Employee emp: empList) {log.info("Found: "+emp.getFirstName()+" "+emp.getLastName());}}}}
このメソッドでは、ジョブの完了後にデータベースからデータを取得し、データに対して実行された処理を確認するためにコンソールに結果を表示しています。
4.8 アプリケーションクラス
Javaバッチプログラムを起動するメインメソッドを含むアプリケーションクラスを作成する予定です。
Application.java
package com.batch;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class Application { public static void main(String args) throws Exception { SpringApplication.run(Application.class, args); }}
@SpringBootApplication
は、プログラムをSpring Bootプログラムとして指定するためのアノテーションです。
Output
Javaアプリケーションとして実行してみましょう。 コンソールに以下のような出力が得られます。
The output of JavaBatch program
バッチプログラムのワークフローは、出力から非常にわかりやすく入手できます。
ステップ処理の後、コンソールで大文字の結果を見ることができます。
まとめ
このチュートリアルでは、次のことを学びました:
- Javaバッチには複数のステップを含むことができるジョブがあります。
- 各ステップは、読み取り、処理、書き込みの組み合わせです。
- データを異なるサイズに切り出して処理することができます。 Eclipseプロジェクトのダウンロード
SpringBootによるJavaBatchのチュートリアルだった
。