স্প্রিং ব্যাচ (Spring Batch) একটি শক্তিশালী ফ্রেমওয়ার্ক যা বড় পরিমাণে ডেটা প্রক্রিয়া (ডেটা মাইগ্রেশন, ডেটা ট্রান্সফরমেশন, ইত্যাদি) করতে ব্যবহৃত হয়। তবে, যখন ডেটার পরিমাণ বিশাল হয়ে ওঠে, তখন কার্যক্ষমতা এবং পারফরম্যান্স আরও উন্নত করতে Partitioning ব্যবহার করা হয়। স্প্রিং ব্যাচে Local Partitioning এবং Remote Partitioning দুইটি প্রধান পার্টিশনিং কৌশল রয়েছে, যা ব্যাচ প্রসেসিংয়ের কর্মক্ষমতা এবং স্কেলেবিলিটি উন্নত করতে সহায়তা করে।
Partitioning কী?
Partitioning হল একটি পদ্ধতি যার মাধ্যমে একটি বৃহত্তর কাজকে (যেমন ডেটার বিশাল সেট) ছোট ছোট উপ-উপকারে ভাগ করা হয় এবং একাধিক থ্রেড বা প্রসেসে সমান্তরালভাবে প্রক্রিয়া করা হয়। এটি পারফরম্যান্স উন্নত করতে এবং কাজের সম্পন্ন সময় কমাতে সহায়ক হয়। স্প্রিং ব্যাচে দুটি প্রধান ধরনের Partitioning রয়েছে:
- Local Partitioning
- Remote Partitioning
১. Local Partitioning
Local Partitioning হল একটি পদ্ধতি যেখানে একটি কাজকে বিভিন্ন অংশে ভাগ করা হয় এবং প্রতিটি অংশ একই JVM বা মেশিনের মধ্যে সমান্তরালভাবে প্রসেস করা হয়। এতে একটি কাজের প্রতিটি পার্টিশন আলাদা Step হিসেবে কার্যকর করা হয়, এবং প্রতিটি Step একটি নির্দিষ্ট ডেটা অংশ প্রক্রিয়া করে।
Local Partitioning সাধারণত কম্পিউটিং শক্তির একক মেশিন বা ক্লাস্টারের মধ্যে কাজের জন্য ব্যবহৃত হয়।
উদাহরণ: Local Partitioning
ধরা যাক, আমাদের একটি ব্যাচ প্রসেসিং কাজ রয়েছে যা Users টেবিল থেকে ডেটা পড়বে, এবং আমরা ডেটা ভলিউম বেশি হলে এটি পার্টিশনিং করে সমান্তরালভাবে প্রসেস করতে চাই।
Step 1: স্প্রিং ব্যাচ কনফিগারেশন
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private DataSource dataSource;
@Bean
public ItemReader<User> reader() {
JdbcCursorItemReader<User> reader = new JdbcCursorItemReader<>();
reader.setDataSource(dataSource);
reader.setSql("SELECT id, name, email FROM users");
reader.setRowMapper(new BeanPropertyRowMapper<>(User.class));
return reader;
}
@Bean
public ItemProcessor<User, User> processor() {
return new UserItemProcessor();
}
@Bean
public ItemWriter<User> writer() {
JdbcBatchItemWriter<User> writer = new JdbcBatchItemWriter<>();
writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
writer.setSql("UPDATE users SET processed = true WHERE id = :id");
writer.setDataSource(dataSource);
return writer;
}
@Bean
public Step partitionedStep() {
return stepBuilderFactory.get("partitionedStep")
.partitioner("partitionedStep", new UserPartitioner())
.step(step1()) // Here step1() is the actual step that processes data
.build();
}
@Bean
public Job partitionedJob() {
return jobBuilderFactory.get("partitionedJob")
.start(partitionedStep())
.build();
}
}
Step 2: Partitioner Implementation
UserPartitioner একটি কাস্টম ক্লাস যা ডেটা ভাগ করার জন্য ব্যবহার করা হয়।
public class UserPartitioner implements Partitioner {
@Override
public Map<String, ExecutionContext> partition(int gridSize) {
Map<String, ExecutionContext> partitionMap = new HashMap<>();
int partitionSize = 100; // number of records per partition
int totalRecords = 1000; // total number of records in your dataset
for (int i = 0; i < gridSize; i++) {
ExecutionContext context = new ExecutionContext();
context.putInt("partitionNumber", i);
context.putInt("start", i * partitionSize);
context.putInt("end", (i + 1) * partitionSize);
partitionMap.put("partition" + i, context);
}
return partitionMap;
}
}
এখানে, UserPartitioner ক্লাস partition() মেথডে ডেটা অংশে ভাগ করে। প্রতিটি পার্টিশনের জন্য একটি ExecutionContext তৈরি হয়, যা প্রক্রিয়ার জন্য start এবং end সীমা সংরক্ষণ করে।
২. Remote Partitioning
Remote Partitioning একটি উন্নত পার্টিশনিং কৌশল যা একাধিক মেশিন বা JVM-এ সমান্তরালভাবে কাজ করতে সহায়তা করে। এটি সাধারণত স্কেলেবল এবং ক্লাস্টার-ভিত্তিক অ্যাপ্লিকেশনগুলির জন্য ব্যবহৃত হয়, যেখানে মূল সিস্টেম (master) কাজের ভাগ (partitions) বিভক্ত করে, এবং প্রতিটি সিস্টেম (worker) নির্দিষ্ট অংশের জন্য কাজ করে।
স্প্রিং ব্যাচে রিমোট পার্টিশনিং করার জন্য স্প্রিং মেসেজিং (Spring Messaging) বা JMS (Java Message Service) ব্যবহার করা হয়। এখানে মূল সিস্টেমটি (Master) Worker সিস্টেমগুলিকে পার্টিশন তথ্য পাঠায় এবং Worker সিস্টেমগুলো তাদের নির্দিষ্ট অংশে কাজ সম্পন্ন করে।
উদাহরণ: Remote Partitioning
Step 1: স্প্রিং ব্যাচ কনফিগারেশন
@Configuration
@EnableBatchProcessing
public class RemoteBatchConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private DataSource dataSource;
@Bean
public ItemReader<User> reader() {
// Configuring remote partitioning reader
}
@Bean
public ItemProcessor<User, User> processor() {
return new UserItemProcessor();
}
@Bean
public ItemWriter<User> writer() {
// Configuring remote partitioning writer
}
@Bean
public Step partitionedStep() {
return stepBuilderFactory.get("partitionedStep")
.partitioner("partitionedStep", new RemoteUserPartitioner())
.step(step1()) // Actual step that processes data
.build();
}
@Bean
public Job remotePartitionedJob() {
return jobBuilderFactory.get("remotePartitionedJob")
.start(partitionedStep())
.build();
}
}
Step 2: Remote Partitioner
RemoteUserPartitioner ক্লাস মূলত পার্টিশন তৈরি করে এবং বিভিন্ন মেশিন বা সার্ভারে তথ্য পাঠানোর জন্য ব্যবহৃত হয়।
public class RemoteUserPartitioner implements Partitioner {
@Override
public Map<String, ExecutionContext> partition(int gridSize) {
Map<String, ExecutionContext> partitionMap = new HashMap<>();
// Distribute partitions across different worker nodes
return partitionMap;
}
}
Local এবং Remote Partitioning এর পার্থক্য
| বিষয় | Local Partitioning | Remote Partitioning |
|---|---|---|
| কোডের অবস্থান | একই JVM বা মেশিনে কাজ করে। | একাধিক JVM বা মেশিনে কাজ করে। |
| পারফরম্যান্স | ছোট স্কেল প্রসেসিংয়ের জন্য উপযুক্ত। | বড় স্কেল প্রসেসিং এবং ক্লাস্টারিংয়ের জন্য উপযুক্ত। |
| স্কেলেবিলিটি | স্কেলিং সীমাবদ্ধ (একই মেশিনে)। | উচ্চ স্কেলেবিলিটি এবং একাধিক মেশিনে প্রসেসিংয়ের ক্ষমতা। |
| কমপ্লেক্সিটি | সহজ কনফিগারেশন, কমপ্লেক্সিটি কম। | আরও জটিল কনফিগারেশন এবং মেসেজিং সিস্টেমের প্রয়োজন হয়। |
| উদাহরণ | একই সার্ভারে ডেটা প্রসেসিং। | ডিস্ট্রিবিউটেড সিস্টেমে কাজ করার জন্য (Master-Worker Architecture)। |
উপসংহার
স্প্রিং ব্যাচে Local Partitioning এবং Remote Partitioning দুটি অত্যন্ত গুরুত্বপূর্ণ কৌশল যা ব্যাচ প্রসেসিংয়ের কর্মক্ষমতা এবং স্কেলেবিলিটি বৃদ্ধি করতে ব্যবহৃত হয়।
- Local Partitioning সহজ কনফিগারেশনের মাধ্যমে একাধিক অংশে ডেটা ভাগ করে এবং একক মেশিনে সমান্তরালভাবে প্রক্রিয়া করে।
- Remote Partitioning একাধিক সিস্টেমে ডেটা ভাগ করে এবং প্রতিটি সিস্টেম তার নির্দিষ্ট অংশে কাজ করে, যা বড় ডেটাসেট এবং স্কেলেবিলিটির জন্য আদর্শ।
আপনার প্রকল্পের আকার এবং প্রক্রিয়ার জটিলতা অনুসারে আপনি যে কোনো একটি পার্টিশনিং কৌশল বেছে নিতে পারেন।