স্প্রিং ব্যাচ (Spring Batch) হলো একটি ফ্রেমওয়ার্ক যা উচ্চ-পারফরম্যান্স ব্যাচ প্রসেসিং এর জন্য ব্যবহৃত হয়। এটি ডেটা প্রসেসিংয়ের জন্য নির্ভরযোগ্য এবং স্কেলেবল সমাধান প্রদান করে। স্প্রিং ব্যাচ সাধারণত ব্যাচ জব (Batch Job) চালানোর সময় ডেটা রিড, প্রসেস এবং রাইট করার জন্য ব্যবহৃত হয়।
পার্টিশনিং (Partitioning) স্প্রিং ব্যাচের একটি কৌশল যা বড় বড় ডেটাসেটকে ছোট ছোট অংশে ভাগ করে সমান্তরালভাবে প্রসেস করতে সহায়তা করে, ফলে পারফরম্যান্স বাড়ে।
পার্টিশনিং কনফিগারেশন (Partitioning Configuration)
স্প্রিং ব্যাচে পার্টিশনিং দুইভাবে করা যায়:
- লোকাল পার্টিশনিং (Local Partitioning): একক JVM-এ কার্য সম্পাদিত হয়।
- রিমোট পার্টিশনিং (Remote Partitioning): একাধিক JVM জুড়ে কার্য সম্পাদিত হয়।
উদাহরণ: লোকাল পার্টিশনিং কনফিগারেশন
নিচের উদাহরণে একটি স্প্রিং ব্যাচ জব কনফিগার করা হয়েছে যেখানে বড় ডেটাসেটকে পার্টিশনে ভাগ করে সমান্তরালভাবে প্রসেস করা হচ্ছে।
Step 1: মডেল ক্লাস তৈরি
public class Employee {
private Long id;
private String name;
private String department;
// Getter এবং Setter
}
Step 2: রিডার, প্রসেসর এবং রাইটার কনফিগার করা
@Bean
public ItemReader<Employee> itemReader() {
return new FlatFileItemReaderBuilder<Employee>()
.name("employeeReader")
.resource(new ClassPathResource("employees.csv"))
.delimited()
.names("id", "name", "department")
.fieldSetMapper(new BeanWrapperFieldSetMapper<>() {{
setTargetType(Employee.class);
}})
.build();
}
@Bean
public ItemProcessor<Employee, Employee> itemProcessor() {
return employee -> {
employee.setDepartment(employee.getDepartment().toUpperCase());
return employee;
};
}
@Bean
public ItemWriter<Employee> itemWriter() {
return items -> items.forEach(System.out::println);
}
Step 3: পার্টিশনিং স্টেপ তৈরি
@Bean
public Step slaveStep(StepBuilderFactory stepBuilderFactory, ItemReader<Employee> itemReader,
ItemProcessor<Employee, Employee> itemProcessor, ItemWriter<Employee> itemWriter) {
return stepBuilderFactory.get("slaveStep")
.<Employee, Employee>chunk(10)
.reader(itemReader)
.processor(itemProcessor)
.writer(itemWriter)
.build();
}
@Bean
public Step masterStep(StepBuilderFactory stepBuilderFactory, TaskExecutorPartitionHandler partitionHandler) {
return stepBuilderFactory.get("masterStep")
.partitioner("slaveStep", partitioner())
.partitionHandler(partitionHandler)
.build();
}
@Bean
public Partitioner partitioner() {
return gridSize -> {
Map<String, ExecutionContext> partitions = new HashMap<>();
for (int i = 0; i < gridSize; i++) {
ExecutionContext context = new ExecutionContext();
context.putInt("partitionNumber", i);
partitions.put("partition" + i, context);
}
return partitions;
};
}
Step 4: জব কনফিগার করা
@Bean
public Job partitioningJob(JobBuilderFactory jobBuilderFactory, Step masterStep) {
return jobBuilderFactory.get("partitioningJob")
.start(masterStep)
.build();
}
Step 5: টাস্ক এক্সিকিউটর (Task Executor) যোগ করা
@Bean
public TaskExecutorPartitionHandler partitionHandler(Step slaveStep) {
TaskExecutorPartitionHandler handler = new TaskExecutorPartitionHandler();
handler.setStep(slaveStep);
handler.setTaskExecutor(taskExecutor());
handler.setGridSize(5);
return handler;
}
@Bean
public TaskExecutor taskExecutor() {
return new SimpleAsyncTaskExecutor("partitioning-");
}
কর্মপদ্ধতি ব্যাখ্যা
- Partitioner: ডেটাসেটকে বিভক্ত করে বিভিন্ন পার্টিশনে ভাগ করে।
- Slave Step: প্রতিটি পার্টিশন প্রক্রিয়া করে।
- Master Step: পার্টিশনের দায়িত্ব বণ্টন করে।
- Task Executor: সমান্তরাল প্রসেসিং নিশ্চিত করে।
আউটপুট
এই কনফিগারেশনে, ডেটা ফাইলটি ৫টি পার্টিশনে বিভক্ত হবে এবং প্রতিটি পার্টিশন সমান্তরালভাবে প্রসেস হবে।