Spring Batchとは?

Spring Batchの概要

  • Spring Batchは、Springを開発したPivotalのプロジェクトの一つです。
  • 従来スケジューラーで行っていた処理を、大規模なバッチ処理として切り出すためのフレームワークです。
  • 従来のスケジューリング処理ではログの確認が困難でした。
  • Spring Batchではデータを一括処理できます。
  • mysql.sqlなどのスキーマを使用して、Spring Batchのメタデータ用テーブルを作成できます。

Spring Batchの基本概念

Job

  • Jobはバッチ処理の最も大きな単位であり、実行単位です。
  • JobをBeanとして登録し、パラメータを指定して実行できます。
  • 複数のJobを作成できます。
  • Jobは一つ以上のStepで構成されます。非常に複雑なJobでない限り、2から10個のStepが推奨されます。

Step

  • StepはJobに含まれる作業単位です。
  • Tasklet方式と、reader、processor、writerを使用するチャンク指向方式をサポートします。
  • 読み込み、加工、書き込みをまとめた処理をチャンク処理と呼び、一つのトランザクションとして考えられます。これは再実行の重要な単位でもあります。

Tasklet

  • TaskletはStepに含まれる作業です。

Chunk

  • Chunkは一度にコミットする行数です。
  • チャンク単位でトランザクションを実行するため、失敗時には現在のチャンクがロールバックされます。
  • チャンク指向処理は次の3段階で実行されます。
    • Read: データベースから処理対象データを読み込みます。
    • Process: 読み込んだデータを加工します。この処理は任意です。
    • Write: 加工したデータをデータベースに保存します。

ChunkとPage

  • Page: 処理対象データから一定数を取得します。
  • Chunk: 取得したデータを一定数ずつ処理して保存します。
  • page = chunk * nに設定すると効率がよいとされます。一般的にはpage = chunkです。

ItemReader

  • ItemReaderはデータを読み込む必須コンポーネントです。
  • 主な実装:
    • CursorItemReader: ストリーム方式で1件ずつ処理します。
    • PagingItemReader: ページサイズ単位で取得して処理します。

ItemProcessor

  • ItemProcessorはItemReaderからオブジェクトを受け取り、加工してItemWriterへ渡します。一度に一つのアイテムを処理します。
  • 任意のコンポーネントです。
  • 主な実装:
    • CompositeItemProcessor: 複数のprocessorを連結して順番に実行します。

ItemWriter

  • ItemWriterはItemReaderまたはItemProcessorから受け取ったデータを蓄積して保存します。
  • 必須のコンポーネントです。
  • 主な実装:
    • CompositeItemWriter
    • FlatFileItemWriter
    • HibernateItemWriter
    • JdbcBatchItemWriter
    • JsonFileItemWriter
    • MongoItemWriter

JobLauncher

JobLauncherはJobを実行します。

JobRepository

JobRepositoryは、JobやStepなどのバッチ処理に関するメタデータを管理するインターフェースです。メタデータ管理はSpring Batchが提供する主要機能の一つです。

Spring Batchのメタデータスキーマ

Spring Batchには6個のメタデータテーブルと3個のシーケンスがあります。Jobが実行されるたびに、実行情報が保存されます。

通常、Spring Batchはメタデータテーブルなしでは実行できません。カスタマイズによってテーブルなしで実行することもできますが、運用環境で実行履歴や失敗履歴を確認するためには一般に必要です。

spring-batch-coreには、DBMS別にschema-{DBMS}.sqlという名前のスキーマが含まれています。ここではMySQL用のschema-mysql.sqlを確認します。MySQLにはシーケンスがないため、シーケンスの役割を持つテーブルも作成します。

BATCH_JOB_INSTANCE

BATCH_JOB_INSTANCEにはJobInstanceの情報が保存され、階層構造の最上位になります。

CREATE TABLE BATCH_JOB_INSTANCE  (
    JOB_INSTANCE_ID BIGINT  NOT NULL PRIMARY KEY ,
    VERSION BIGINT ,
    JOB_NAME VARCHAR(100) NOT NULL,
    JOB_KEY VARCHAR(32) NOT NULL,
    constraint JOB_INST_UN unique (JOB_NAME, JOB_KEY)
) ENGINE=InnoDB;

主キーはBATCH_JOB_SEQによって生成されます。

CREATE TABLE BATCH_JOB_SEQ (
    ID BIGINT NOT NULL,
    UNIQUE_KEY CHAR(1) NOT NULL,
    constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
) ENGINE=InnoDB;

INSERT INTO BATCH_JOB_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_JOB_SEQ);

BATCH_JOB_EXECUTION

BATCH_JOB_EXECUTIONには、JobInstanceの実行ごとの開始時刻、終了時刻、終了コードなどのJobExecution情報が保存されます。

CREATE TABLE BATCH_JOB_EXECUTION  (
    JOB_EXECUTION_ID BIGINT  NOT NULL PRIMARY KEY ,
    VERSION BIGINT  ,
    JOB_INSTANCE_ID BIGINT NOT NULL,
    CREATE_TIME DATETIME(6) NOT NULL,
    START_TIME DATETIME(6) DEFAULT NULL ,
    END_TIME DATETIME(6) DEFAULT NULL ,
    STATUS VARCHAR(10) ,
    EXIT_CODE VARCHAR(2500) ,
    EXIT_MESSAGE VARCHAR(2500) ,
    LAST_UPDATED DATETIME(6),
    JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL,
    constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID)
    references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
) ENGINE=InnoDB;

主キーはBATCH_JOB_EXECUTION_SEQによって生成されます。

CREATE TABLE BATCH_JOB_EXECUTION_SEQ (
    ID BIGINT NOT NULL,
    UNIQUE_KEY CHAR(1) NOT NULL,
    constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
) ENGINE=InnoDB;

INSERT INTO BATCH_JOB_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_JOB_EXECUTION_SEQ);

BATCH_JOB_EXECUTION_PARAMS

BATCH_JOB_EXECUTION_PARAMSには、Jobの実行に使用したJobParametersが保存されます。

CREATE TABLE BATCH_JOB_EXECUTION_PARAMS  (
    JOB_EXECUTION_ID BIGINT NOT NULL ,
    TYPE_CD VARCHAR(6) NOT NULL ,
    KEY_NAME VARCHAR(100) NOT NULL ,
    STRING_VAL VARCHAR(250) ,
    DATE_VAL DATETIME(6) DEFAULT NULL ,
    LONG_VAL BIGINT ,
    DOUBLE_VAL DOUBLE PRECISION ,
    IDENTIFYING CHAR(1) NOT NULL ,
    constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
    references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;

BATCH_STEP_EXECUTION

BATCH_STEP_EXECUTIONにはStepExecution情報が保存されます。BATCH_JOB_EXECUTIONと似ていますが、読み込み数、コミット数、スキップ数なども保存されます。

CREATE TABLE BATCH_STEP_EXECUTION  (
    STEP_EXECUTION_ID BIGINT  NOT NULL PRIMARY KEY ,
    VERSION BIGINT NOT NULL,
    STEP_NAME VARCHAR(100) NOT NULL,
    JOB_EXECUTION_ID BIGINT NOT NULL,
    START_TIME DATETIME(6) NOT NULL ,
    END_TIME DATETIME(6) DEFAULT NULL ,
    STATUS VARCHAR(10) ,
    COMMIT_COUNT BIGINT ,
    READ_COUNT BIGINT ,
    FILTER_COUNT BIGINT ,
    WRITE_COUNT BIGINT ,
    READ_SKIP_COUNT BIGINT ,
    WRITE_SKIP_COUNT BIGINT ,
    PROCESS_SKIP_COUNT BIGINT ,
    ROLLBACK_COUNT BIGINT ,
    EXIT_CODE VARCHAR(2500) ,
    EXIT_MESSAGE VARCHAR(2500) ,
    LAST_UPDATED DATETIME(6),
    constraint JOB_EXEC_STEP_FK foreign key (JOB_EXECUTION_ID)
    references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;

主キーはBATCH_STEP_EXECUTION_SEQによって生成されます。

CREATE TABLE BATCH_STEP_EXECUTION_SEQ (
    ID BIGINT NOT NULL,
    UNIQUE_KEY CHAR(1) NOT NULL,
    constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
) ENGINE=InnoDB;

INSERT INTO BATCH_STEP_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_STEP_EXECUTION_SEQ);

BATCH_JOB_EXECUTION_CONTEXT

BATCH_JOB_EXECUTION_CONTEXTにはJobExecutionのExecutionContext情報が保存されます。通常、失敗したJobInstanceを停止位置から再開するための情報が含まれます。

CREATE TABLE BATCH_STEP_EXECUTION_CONTEXT  (
    STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
    SHORT_CONTEXT VARCHAR(2500) NOT NULL,
    SERIALIZED_CONTEXT TEXT ,
    constraint STEP_EXEC_CTX_FK foreign key (STEP_EXECUTION_ID)
    references BATCH_STEP_EXECUTION(STEP_EXECUTION_ID)
) ENGINE=InnoDB;

BATCH_STEP_EXECUTION_CONTEXT

BATCH_STEP_EXECUTION_CONTEXTにはStepExecutionのExecutionContext情報が保存されます。通常、失敗したJobInstanceを停止位置から再開するための情報が含まれます。

CREATE TABLE BATCH_JOB_EXECUTION_CONTEXT  (
    JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
    SHORT_CONTEXT VARCHAR(2500) NOT NULL,
    SERIALIZED_CONTEXT TEXT ,
    constraint JOB_EXEC_CTX_FK foreign key (JOB_EXECUTION_ID)
    references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;