W-JAX 2013 Spring Batch - Performance und Skalierbarkeit

Preview:

DESCRIPTION

Slides to our (Dennis Schulte and me) talk at the German Java conference W-JAX 2013 in Munich. Subject is the batch processing framework Spring Batch, general hints regarding performance in batch applications and scalability options in Spring Batch. Slides are in German.

Citation preview

Tobias Flohre / Dennis Schulte | codecentric AG

Spring Batch – Performance und Skalierbarkeit

codecentric AG

Dennis Schulte

Düsseldorf

@denschu

www.github.com/denschu

blog.codecentric.de/author/dsc

dennis.schulte@codecentric.dewww.codecentric.de

codecentric AG

Tobias Flohre

Düsseldorf

@TobiasFlohre

www.github.com/tobiasflohre

blog.codecentric.de/en/author/tobias.flohre

tobias.flohre@codecentric.dewww.codecentric.de

codecentric AG

AGENDA

- Grundlagen Spring Batch

- Vier Aussagen zu Performance im Batch

- Skalierungsstrategien

codecentric AG

AGENDA

- Grundlagen Spring Batch

- Vier Aussagen zu Performance im Batch

- Skalierungsstrategien

codecentric AG

Traditionelles Batch-Pattern

Read Process Write

WAS IST EIN BATCH?

codecentric AG

SPRING BATCH

Automatisches Transaktionsmanagement

Skip

Retry

Persistente Job-Metadaten

Restart

Skalierungsfeatures

codecentric AG

DOMAIN / KONFIGURATION / ABLAUF

Item

ItemReader

ItemProcessor

StepJob

ItemWriter

Chunk

codecentric AG

- Job wird als Spring-Konfiguration erstellt

- Domain Specific Language manifestiert sich in XML-Namespace

- Zentrale Elemente- job

- step

- tasklet

- chunk

- reader- processor- writer- commit-interval

DOMAIN / KONFIGURATION / ABLAUF

13.04.2023 9

<job id="myJob" ><step id="myStep" > <tasklet> <chunk reader="myReader"

processor="myProcessor" writer="myWriter" commit-interval="1" />

</tasklet></step>

</job>

codecentric AG

- Reader, Processor und Writer implementieren bestimmte Interfaces- ItemReader<T>

- T read()- ItemProcessor<I,O>

- O process(I item)- ItemWriter<T>

- void write(List<? extends T> items)- Spring Batch bietet für sehr viele Use Cases Implementierungen an

- Lesen/Schreiben aus/in eine Datenbank

- Lesen/Schreiben aus/in ein Flat-File

- Lesen/Schreiben aus/in ein XML-File

- Lesen/Schreiben aus/in eine JMS-Queue

- Lesen/Schreiben mit JPA

- und viele mehr

DOMAIN / KONFIGURATION / ABLAUF

13.04.2023 10

codecentric AG

DOMAIN / KONFIGURATION / ABLAUF

13.04.2023 11

1Begin Step

Commit transactio

n

Finish Step

2

For each item

item == null ||

completionPolicy fulfilled

true

false

list of items

list of items

item == null

true

false

Open transactio

n

ItemReaderItem read()

ItemProcessorprocess(Item)

ItemWriterwrite(List<Item

>)

codecentric AG

*

*

*

*

DOMAIN / KONFIGURATION / ABLAUF

StepJob

JobInstance

JobExecution

StepExecution

JobParameters

Inkasso Kraftfahrt

Inkasso Kraftfahrt am 22.03.13

Inkasso Kraftfahrt am 22.03.13 erster Versuch

codecentric AG

- Infrastrukturkomponenten

DOMAIN / KONFIGURATION / ABLAUF

13.04.2023 13

JobRepository

JobLauncherPlatformTransaction

Manager

codecentric AG

AGENDA

- Grundlagen Spring Batch

- Vier Aussagen zu Performance im Batch

- Skalierungsstrategien

codecentric AG

VIER THESEN ZU PERFORMANCE IM BATCH

Kenne EVA

Aussage 1

Eingabe Verarbeitung Ausgabe

codecentric AG

VIER THESEN ZU PERFORMANCE IM BATCH

Aussage 1

<job id=“step-job"><step id=“xml-einlesen“>...</step><step

id=“xml-verarbeiten“>...</step><step id=“xml-schreiben“>...</step>

</job>

codecentric AG

VIER THESEN ZU PERFORMANCE IM BATCH

Aussage 1

<job id=“eva-job"><step id=“xml-step">

<tasklet><chunk reader=“xml-einlesen“

processor=“xml-verarbeiten" writer=“xml-schreiben“ />

</tasklet></step>

</job>

codecentric AG

VIER THESEN ZU PERFORMANCE IM BATCH

Aussage 1

- ExecutionContext ist kein Datenspeicher für Nutzdaten, sondern:- Zählerstände

- Steuerdaten

- Problem: HeapSize

- Processor und Writer sollten stateless sein- Parallelisierung

codecentric AG

VIER THESEN ZU PERFORMANCE IM BATCH

Kenne Deine nicht-funktionalen Anforderungen

Aussage 2

codecentric AG

VIER THESEN ZU PERFORMANCE IM BATCH

Aussage 2

- Mengengerüste

- Zu erreichender Durchsatz

- Was läuft parallel?

- Minimiere den Aufwand!

codecentric AG

VIER THESEN ZU PERFORMANCE IM BATCH

Kenne Deine Persistenzschicht

Aussage 3

codecentric AG

VIER THESEN ZU PERFORMANCE IM BATCH

Aussage 3

- Datenlokalität

- Art des DB-Zugriffs- JDBC

- ORM

- Transaktionsgröße (commit-interval)

codecentric AG

VIER THESEN ZU PERFORMANCE IM BATCH

Zahlen sind besser als Vermutungen

Aussage 4

codecentric AG

VIER THESEN ZU PERFORMANCE IM BATCH

Aussage 4

- Messen, Messen, Messen!- Wiederholbarkeit

- Immer nur einen Parameter ändern

- Immer im Blick: CPU, Speicher, Datenquellen

- Ergebnisse protokollieren

- Testdaten- Stetiger Verbesserungsprozess

- Randsysteme abdecken

- Tools verwenden- Profiling lokal

- Application Performance Management tools

codecentric AG

AGENDA

- Grundlagen Spring Batch

- Vier Aussagen zu Performance im Batch

- Skalierungsstrategien

codecentric AG

SKALIERUNGSSTRATEGIEN

- Multi-threaded Step

- AsyncItemProcessor -> AsyncItemWriter

- Parallel Steps

- Partitioning

- Remote Chunking

codecentric AG

SKALIERUNGSSTRATEGIEN

- Woher kommen die Threads?- java.util.concurrent.Executor

- ThreadPoolExecutor

<task:executor id="taskExecutor" pool-size="5"/>- ApplicationServer verwalten eigene Threadpools

codecentric AG

SKALIERUNGSSTRATEGIEN

- Multi-threaded Step

- AsyncItemProcessor -> AsyncItemWriter

- Parallel Steps

- Partitioning

- Remote Chunking

codecentric AG

MULTI-THREADED STEP

<job id="multithreadedStepJob">

<step id="step">

<tasklet task-executor="taskExecutor" throttle-limit="4">

<chunk reader="reader" processor="processor" writer="writer"

commit-interval="3" />

</tasklet>

</step>

</job>

<task:executor id="taskExecutor" pool-size="5"/>

codecentric AG

MULTI-THREADED STEP

13.04.2023 30

1Begin Step

Commit transactio

n

Finish Step

2

For each item

Open transactio

n

ItemProcessorprocess(Item)

ItemWriterwrite(List<Item

>)

ItemReaderItem read()

Threadsafe

File vs. DB vs. JMS

codecentric AG

+ Hoch skalierbar

+ Einfach zu konfigurieren

- Alle Komponenten müssen thread-safe sein

MULTI-THREADED STEP

codecentric AG

SKALIERUNGSSTRATEGIEN

- Multi-threaded Step

- AsyncItemProcessor -> AsyncItemWriter

- Parallel Steps

- Partitioning

- Remote Chunking

codecentric AG

ASYNCITEMPROCESSOR -> ASYNCITEMWRITER

Thread 1

Thread 3

Thread 2

process(item)

ItemReader

AsyncItemProcessor

AsyncItemWriter

process(item)

process(item)

codecentric AG

ASYNCITEMPROCESSOR -> ASYNCITEMWRITER

- AsyncItemProcessor and AsyncItemWriter

- Java Concurrency API- Future

- FutureTask

- Sehr einfach zu konfigurieren

- Optimal für aufwändige process-Schritte- Anreicherung von Daten über langsame APIs

- Komplexe Berechnungen

codecentric AG

ASYNCITEMPROCESSOR -> ASYNCITEMWRITER

<bean id="processor" class="org.sfw.batch.integration.async.AsyncItemProcessor">

<property name="delegate" ref="delegateProcessor"/>

<property name="taskExecutor" ref="taskExecutor"/>

</bean>

<bean id="writer" class="org.sfw.batch.integration.async.AsyncItemWriter">

<property name="delegate" ref="delegateWriter"/>

</bean>

<task:executor id="taskExecutor" pool-size="5"/>

- Achtung: commit-interval > 1

codecentric AG

SKALIERUNGSSTRATEGIEN

- Multi-threaded Step

- AsyncItemProcessor -> AsyncItemWriter

- Parallel Steps

- Partitioning

- Remote Chunking

codecentric AG

PARALLEL STEPS

Thread 2Thread 1

databaseJob

importTablePartner

loadTablePartner

importTableVertrag

loadTableVertrag

codecentric AG

PARALLEL STEPS

<job id="importJob">

<split id="splitStep" task-executor="taskExecutor">

<flow>

<step id="partnerStep">

<tasklet ref="partnerTasklet"/>

</step>

</flow>

<flow>

<step id="vertragStep">

<tasklet ref="vertragTasklet"/>

</step>

</flow>

</split>

</job>

codecentric AG

SKALIERUNGSSTRATEGIEN

- Multi-threaded Step

- AsyncItemProcessor -> AsyncItemWriter

- Parallel Steps

- Partitioning

- Remote Chunking

codecentric AG

PARTITIONING

Partitioner

Name … … Kategorie

Tobias … … A

Dennis … … A

Frank … … A

Daniel … … B

Ben … … B

Max … … B

Christian

… … C

Dirk … … C

Thomas … … C

codecentric AG

PARTITIONING

Partitioner

File 1

File 2

File 3

Name … … Kategorie

Tobias … … A

Dennis … … A

Frank … … A

Daniel … … B

Ben … … B

Max … … B

Christian

… … C

Dirk … … C

Thomas … … C

codecentric AG

PARTITIONING

Partitioner

File 1

File 2

File 3

Name … … Kategorie

Tobias … … A

Dennis … … A

Frank … … A

Daniel … … B

Ben … … B

Max … … B

Christian

… … C

Dirk … … C

Thomas … … C

codecentric AG

PARTITIONING

Partitioner

PartitionHandler

erzeugt Partitionen

verteilt Partitionen an Worker

Lokaler Prozess (TaskExecutor)

Spring Remoting

JMS

Hadoop YARN

codecentric AG

PARTITIONING

Finish Step

Begin Step

Commit transactio

n

For each item

false

Open transactio

n

ItemReaderItem read()

ItemProcessor

process(Item)ItemWriter

write(List<Item>)

Commit transactio

n

For each item

false

Open transactio

n

ItemReaderItem read()

ItemProcessor

process(Item)ItemWriter

write(List<Item>)

Commit transactio

n

For each item

false

Open transactio

n

ItemReaderItem read()

ItemProcessor

process(Item)ItemWriter

write(List<Item>)

Partitioner

codecentric AG

<job id="flatfilePartitioningJob">

<step id="partitionedStep" >

<partition step="flatfilePartitioningStep" partitioner="partitioner">

<handler task-executor="taskExecutor" />

</partition>

</step>

</job>

<bean id="partitioner" class="org.sfw...support.MultiResourcePartitioner">

<property name="resources" value="file:src/test/resources/*.csv" />

</bean>

PARTITIONING

codecentric AG

PARTITIONING

+ Hoch skalierbar

+ Kein Bottleneck beim ItemReader

+ Datenlokalität

- Struktur der Input Daten muss bekannt sein

codecentric AG

SKALIERUNGSSTRATEGIEN

- Multi-threaded Step

- AsyncItemProcessor -> AsyncItemWriter

- Parallel Steps

- Partitioning

- Remote Chunking

codecentric AG

REMOTE CHUNKING

Master Slave Node 1

Chunk Processor

Step 1

ItemReader

Ch

un

kPro

vid

er

ItemWriter

Slave Node 2

Chunk Processor

ItemWriter

codecentric AG

REMOTE CHUNKING

1Begin Step

Commit transactio

n

Finish Step

2

For each item

Open transactio

n

ItemReaderItem read()

ItemProcessor

process(Item)

ItemWriterwrite(List<Item>)

JMS

Commit transactio

n

JMS

Open transactio

n

codecentric AG

REMOTE CHUNKING

+ Hoch skalierbar

+ Struktur der Input Daten muss bekannt sein

- Ggf. Bottleneck beim ItemReader

- Transaktionale Middleware

- Alle Items werden serialisiert

codecentric AG

FRAGEN?

Dennis Schulte / Tobias Flohre

codecentric AGMerscheider Straße 142699 Solingen

tobias.flohre@codecentric.de

dennis.schulte@codecentric.de

www.codecentric.de

blog.codecentric.de

www.meettheexperts.de

13.04.2023 51

Recommended