Spring Boot සහ Spark - Big Data වලට SC Guide

Spring Boot සහ Spark - Big Data වලට SC Guide

කොහොමද යාලුවනේ! Tech කතා කරන අපේ තවත් අලුත් ලිපියකින් ඔයාලා හැමෝම සාදරයෙන් පිළිගන්නවා. අද අපි කතා කරන්න යන්නේ මේ දවස්වල Software Engineering ලෝකේ හරිම ජනප්‍රිය, වගේම හරිම බලගතු සංකලනයක් ගැන – ඒ තමයි Spring Boot සහ Apache Spark. "Big Data" කියන වචනේ දැන් අපිට අලුත් දෙයක් නෙවෙයිනේ. දත්ත කන්දරාවක් එනකොට ඒවා Analyze කරන්න, Process කරන්න, ඒ වගේම ඒවායින් තේරුමක් ගන්න එක හරිම අභියෝගයක්.

සාමාන්‍ය ක්‍රම වලට ගියාම Slow වෙනවා, Scalability නැති වෙනවා වගේ ප්‍රශ්න එනවා. ඔය වගේ වෙලාවට තමයි Spark වගේ Distributed Processing Engine එකක් අපිට පිහිටට එන්නේ. ඒ වගේම, අපේ Applications ඉක්මනට, පහසුවෙන් හදාගන්න Spring Boot කියන්නේ අතිවිශිෂ්ට Framework එකක්. ඉතින් මේ දෙක එකතු උනාම මොන වගේ බලයක්ද එන්නේ කියලා ඔයාලට හිතාගන්න පුළුවන් ඇති. අද මේ ලිපියෙන් අපි බලමු කොහොමද Spring Boot Application එකක් ඇතුලට Spark ගෙනත්, Big Data Processing වැඩ පහසුවෙන් කරගන්නේ කියලා. පොඩි Practical Example එකකුත් අපි බලමු. එහෙනම් වැඩේට බහිමුද?

මොකක්ද මේ Spring Boot සහ Spark කියන්නේ?

කලබල වෙන්න එපා, මුලින්ම මේ දෙන්නා ගැන පොඩ්ඩක් දැනගෙන ඉමු. මොකද නැතුව වැඩක් නෑනේ!

Spring Boot

ඇත්තටම කිව්වොත්, Spring Boot කියන්නේ Java Framework එකක්. ඒක Spring Framework එකේම කොටසක්. ඒත් Spring Boot වල තියෙන විශේෂත්වය තමයි Application එකක් හදන එක හරිම ලේසි කරන එක. "Convention over Configuration" කියන Concept එකට අනුව තමයි මේක වැඩ කරන්නේ. ඒ කියන්නේ අපිට ගොඩක් දේවල් Manual configure කරන්න ඕනේ නෑ. ඒක තනියම කරනවා. REST APIs හදන්න, Microservices හදන්න, Web Applications හදන්න නම් Spring Boot කියන්නේ අතිවිශිෂ්ට Framework එකක්. ඒකෙන් අපිට පුළුවන් ඉක්මනට Applications Deploy කරන්න, Test කරන්න. Developersලා අතරේ Spring Boot මේ තරම් ජනප්‍රිය වෙන්න මේකත් එක් හේතුවක්.

Apache Spark

Spark කියන්නේ Distributed Data Processing System එකක්. මේක හැදුණේ Big Data Analyze කරන්න, Process කරන්න. Spark වල තියෙන ලොකුම වාසිය තමයි ඒක හරිම වේගවත්. ඒක In-memory processing කරන නිසා සාමාන්‍ය MapReduce වගේ ක්‍රම වලට වඩා 100 ගුණයකට වඩා වේගවත් වෙන්න පුළුවන්. Spark එකෙන් අපිට පුළුවන් Stream Processing, Machine Learning, Graph Processing, SQL Queries වගේ ගොඩක් දේවල් කරන්න. Java, Scala, Python, R වගේ Languages වලින් Spark එක්ක වැඩ කරන්න පුළුවන්. ඉතින් ඔයාලගේ දත්ත ගොඩක් තියෙනවා නම්, ඒවා ඉක්මනට Process කරන්න ඕනේ නම්, Spark තමයි නියම විසඳුම.

ඇයි මේ දෙක එකට?

හිතන්නකෝ, අපිට Backend Application එකක් හදන්න ඕනේ. ඒක Client requests handle කරන්න ඕනේ, ඒ වගේම Big Data Process කරන්නත් ඕනේ. Spring Boot එකෙන් අපිට පුළුවන් ඉක්මනට REST Endpoints හදලා Client requests handle කරන්න. ඒ Endpoints වලට එන Data, නැත්නම් වෙනත් Source එකකින් එන Big Data Process කරන්න අපි Spark පාවිච්චි කරනවා. උදාහරණයක් විදියට, Web Application එකකට Usersලා ලොකු Data Set එකක් Upload කරනවා කියමු. මේ Data Set එක Analyze කරලා, Report එකක් හදලා Usersලාට දෙන්න ඕනේ. මේ වගේ වෙලාවට Spring Boot වලින් File Upload එක Handle කරලා, Spark වලට Data Processing එක භාර දෙන්න පුළුවන්. ඒක හරිම සුපිරි Combination එකක්.

ඇයි Spring Boot එක්ක Spark පාවිච්චි කරන්නේ? (Why Spark with Spring Boot?)

මේ දෙන්නාගේ එකතුවෙන් අපිට ලැබෙන වාසි ටිකක් අපි බලමු.

  • Scalability (ප්‍රසාරණය වීමේ හැකියාව): Spring Boot Microservices විදිහට Deploy කරන්න පහසුයි. ඒ වගේම Spark කියන්නේ Distributed System එකක් නිසා කොච්චර Data ආවත් Cluster එකක් විදිහට Run කරලා Scalable විදිහට Process කරන්න පුළුවන්. මේ දෙන්නම Scalability වලට හොඳටම Support කරනවා.
  • Performance (කාර්ය සාධනය): Spark වල In-memory processing නිසා Big Data operations හරිම වේගවත්. Spring Boot වල Lightweight ස්වභාවය නිසා Overall Application Performance එක වැඩි වෙනවා.
  • Ease of Use (පහසුව): Spring Boot වලින් Application එකක් හදන එක හරිම ලේසියි. ඒ වගේම Spark API එක හරිම Simple. මේ දෙකම එකට පාවිච්චි කරනකොට Developersලාට වැඩ කරන්න හරිම පහසුවක් දැනෙනවා.
  • Rich Ecosystem (විශාල Ecosystem එක): Spring Boot වලට Spring Data, Spring Security වගේ ගොඩක් Modules තියෙනවා. Spark වලට Spark SQL, MLlib, GraphX, Spark Streaming වගේ Components තියෙනවා. මේ Ecosystem දෙකම එකට පාවිච්චි කරනකොට අපිට පුළුවන් ඕනෑම Requirement එකකට Solution එකක් දෙන්න.
  • Unified Development (ඒකාබද්ධ සංවර්ධනය): අපි Java වලින් Spring Boot Application එක හදන නිසා, Spark වලින් Data Processing වලටත් Java (or Scala) පාවිච්චි කරන්න පුළුවන්. ඒක Developersලාට හරිම වාසියක්.

ඉතින් මේ වගේ වාසි ගොඩක් තියෙන නිසා තමයි මේ සංකලනය මේ තරම් ජනප්‍රිය වෙලා තියෙන්නේ.

ප්‍රැක්ටිකල් කතාව: Spring Boot එක්ක Spark Application එකක් හදමු!

දැන් අපි කතා කරලා ඇති, වැඩේට බහිමු! අපි හදමු පොඩි Spring Boot Application එකක්. ඒකෙන් අපි CSV File එකක් Read කරලා Spark පාවිච්චි කරලා ඒක Analyze කරමු.

අවශ්‍ය දේවල් (Prerequisites):

මේ වැඩේට කලින් ඔයාලගේ Computer එකේ මේ ටික තියෙන්න ඕනේ:

  • Java Development Kit (JDK) 8 or higher: අපි Java වලින් වැඩ කරන නිසා JDK එක අනිවාර්යයි.
  • Maven: Project එක Build කරන්න අපි Maven පාවිච්චි කරනවා.
  • Apache Spark (Local Mode): අපි Local Machine එකේ Run කරන නිසා Spark Setup එකක් ඕනේ. ඒක Download කරලා Environment Variables හදාගන්න.
  • IDE (Integrated Development Environment): IntelliJ IDEA, VS Code, Eclipse වගේ එකක්.

පියවරෙන් පියවර (Step-by-Step):

1. Spring Boot Project එකක් හදමු:

මුලින්ම අපි Spring Initializr පාවිච්චි කරලා අලුත් Spring Boot Project එකක් හදමු. Dependencies විදිහට අපි 'Spring Web' එකතු කරගමු. Project එකට නමක් දෙන්න 'SpringBootSparkDemo'.

2. Spark Dependencies එකතු කරමු:

දැන් අපි pom.xml file එකට Spark Dependencies එකතු කරමු. මේකෙන් තමයි අපිට Spark functionality Application එකට ගන්න පුළුවන් වෙන්නේ.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-core_2.12</artifactId>
        <version>3.5.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-sql_2.12</artifactId>
        <version>3.5.0</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<!-- Spark version for Scala 2.12 -->
<properties>
    <scala.version>2.12.18</scala.version>
    <spark.version>3.5.0</spark.version>
</properties>

සැලකිය යුතුයි: Spark Version එක (3.5.0) සහ Scala Version (2.12) එක ගැළපෙන විදිහට තෝරාගන්න. නැත්නම් Errors එන්න පුළුවන්. (ඔබේ Spark installation එකේ Scala version එකට ගැලපෙන Spark artifact version එකක් තෝරාගන්න.)

3. Sample Data File එකක් හදමු:

Project එකේ root folder එකේ data.csv කියලා file එකක් හදලා මේ Data එක දාගමු:

transactionId,productId,customerId,amount,timestamp
1,P001,C001,1500.00,2023-01-01T10:00:00Z
2,P002,C002,2500.00,2023-01-01T10:05:00Z
3,P001,C003,1200.00,2023-01-01T10:10:00Z
4,P003,C001,3000.00,2023-01-01T10:15:00Z
5,P002,C004,1800.00,2023-01-01T10:20:00Z
6,P001,C001,500.00,2023-01-01T10:25:00Z

4. Spark Configuration සහ Data Processing Service එකක් හදමු:

දැන් අපි SparkSession එක Configure කරලා Data Processing Logic එක ලියමු.

src/main/java/com/example/springbootsparkdemo/config/SparkConfig.java

package com.example.springbootsparkdemo.config;

import org.apache.spark.sql.SparkSession;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SparkConfig {

    @Bean
    public SparkSession sparkSession() {
        return SparkSession.builder()
                .appName("SpringBootSparkDemo")
                .master("local[*]") // Use local machine with all available cores
                .config("spark.executor.memory", "2g")
                .config("spark.driver.memory", "2g")
                .getOrCreate();
    }
}

src/main/java/com/example/springbootsparkdemo/service/DataProcessingService.java

package com.example.springbootsparkdemo.service;

import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import static org.apache.spark.sql.functions.*;

@Service
public class DataProcessingService {

    private final SparkSession sparkSession;

    @Autowired
    public DataProcessingService(SparkSession sparkSession) {
        this.sparkSession = sparkSession;
    }

    public String analyzeTransactions(String filePath) {
        // Read the CSV file into a DataFrame
        Dataset<Row> df = sparkSession.read()
                .option("header", "true") // First line of file is header
                .option("inferSchema", "true") // Spark infers data types
                .csv(filePath);

        df.printSchema();
        df.show();

        StringBuilder resultBuilder = new StringBuilder();
        resultBuilder.append("Transaction Data Loaded:\n");
        resultBuilder.append(df.showString(10, 20, false));

        // 1. Calculate total revenue per product
        resultBuilder.append("\n\nTotal Revenue per Product:\n");
        Dataset<Row> revenuePerProduct = df.groupBy("productId")
                .agg(sum("amount").as("totalRevenue"))
                .orderBy(col("totalRevenue").desc());
        revenuePerProduct.show();
        resultBuilder.append(revenuePerProduct.showString(10, 20, false));

        // 2. Find the customer with the highest total spending
        resultBuilder.append("\n\nCustomer with Highest Spending:\n");
        Dataset<Row> customerSpending = df.groupBy("customerId")
                .agg(sum("amount").as("totalSpent"))
                .orderBy(col("totalSpent").desc());

        Row topCustomer = customerSpending.first();
        if (topCustomer != null) {
            resultBuilder.append("Customer ID: " + topCustomer.getString(0));
            resultBuilder.append(", Total Spent: " + topCustomer.getDouble(1));
        } else {
            resultBuilder.append("No customer data available.");
        }

        return resultBuilder.toString();
    }

    // Method to stop SparkSession if needed (e.g., on application shutdown)
    public void stopSparkSession() {
        if (sparkSession != null) {
            sparkSession.stop();
        }
    }
}

5. REST Controller එකක් හදමු:

දැන් අපි REST Endpoint එකක් හදමු. මේකෙන් තමයි අපි Data Processing Service එක Call කරන්නේ.

src/main/java/com/example/springbootsparkdemo/controller/DataAnalysisController.java

package com.example.springbootsparkdemo.controller;

import com.example.springbootsparkdemo.service.DataProcessingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DataAnalysisController {

    private final DataProcessingService dataProcessingService;

    @Autowired
    public DataAnalysisController(DataProcessingService dataProcessingService) {
        this.dataProcessingService = dataProcessingService;
    }

    @GetMapping("/analyze-transactions")
    public String analyzeTransactions() {
        // Path to the data.csv file relative to the project root
        String filePath = "data.csv";
        return dataProcessingService.analyzeTransactions(filePath);
    }
}

6. Application එක Run කරමු:

දැන් ඔයාලට පුළුවන් Spring Boot Application එක Run කරන්න. IDE එකෙන් හෝ Maven Command එකකින් Run කරන්න පුළුවන්.

mvn spring-boot:run

Application එක Start උනාට පස්සේ Browser එක Open කරලා මේ URL එකට යන්න:

http://localhost:8080/analyze-transactions

එතකොට ඔයාලට Console එකේ Spark Processing Output එකයි, Browser එකේ Summarized Results එකයි බලාගන්න පුළුවන් වෙයි. මේකෙන් අපිට පේනවා Spring Boot Application එකක් ඇතුලේ කොහොමද Spark පාවිච්චි කරලා Big Data Analyze කරන්නේ කියලා. තව ගොඩක් Complex Analytics මේ විදිහට කරන්න පුළුවන්.

සැලකිලිමත් විය යුතු දේවල් සහ Best Practices

Spring Boot එක්ක Spark පාවිච්චි කරනකොට අපිට හිතන්න ඕන දේවල් ටිකක් තියෙනවා.

  • Resource Management (සම්පත් කළමනාකරණය): Spark කියන්නේ Memory ගොඩක් පාවිච්චි කරන Engine එකක්. ඒ නිසා Production Environments වලදී Spark Cluster එකේ Memory, CPU වගේ දේවල් හොඳට Monitor කරන්න ඕනේ. Spring Boot Application එකයි, Spark Job එකයි දෙකටම අවශ්‍ය Resources හොඳට Allocate කරන්න ඕනේ. spark.executor.memory, spark.driver.memory වගේ Configs වලින් මේක Manage කරන්න පුළුවන්.
  • Deployment Strategies (Deployment ක්‍රම): අපි මේ දැක්කේ Local Mode එක. Production වලදී Spark Application එකක් Deploy කරන්නේ YARN, Kubernetes, Mesos වගේ Cluster Managers එක්ක. Spring Boot Application එක Docker container එකක් විදිහට Build කරලා Kubernetes Cluster එකක Deploy කරන්න පුළුවන්. Spark Job එක වෙනම Submit කරන්න පුළුවන්.
  • SparkSession Lifecycle (SparkSession චක්‍රය): SparkSession එක Application එකේ lifecycle එකට අනුව Manage කරන්න ඕනේ. Bean එකක් විදිහට Spring Context එකට දාපු එක හොඳයි. ඒත් Application Shutdown වෙනකොට SparkSession එක Stop කරන්න අමතක කරන්න එපා. (අපේ උදාහරණයේ stopSparkSession() Method එකක් දැම්මා).
  • Error Handling and Monitoring (දෝෂ හඳුනාගැනීම සහ අධීක්ෂණය): Distributed Systems වලදී Errors එන්න තියෙන ඉඩ වැඩියි. ඒ නිසා Proper Error Handling, Logging, Monitoring මේ වගේ Systems වලට අත්‍යවශ්‍යයි. Spring Boot Actuator වගේ දේවල් පාවිච්චි කරලා Application එකේ Health Check කරන්න පුළුවන්. Spark UI එකෙන් Spark Jobs Monitor කරන්න පුළුවන්.
  • Data Locality: Spark හොඳම Performance දෙන්නේ Data එකට ළඟින්ම Processing එක කරනකොට. ඒ නිසා Data Source එක Spark Cluster එකට ළඟින් තියාගන්න බලන්න. S3, HDFS වගේ Distributed Storage Systems එක්ක වැඩ කරන එක හොඳයි.
  • Performance Tuning: Spark Jobs වල Performance වැඩි කරගන්න Partitioning, Caching, Broadcast variables වගේ Techniques පාවිච්චි කරන්න පුළුවන්.

අවසන් වශයෙන්...

ඉතින් යාලුවනේ, Spring Boot සහ Apache Spark කියන්නේ Big Data ලෝකයේ බලගතුම සංකලනයක්. Spring Boot වල පහසුවත්, Spark වල වේගයත් එකතු උනාම අපිට පුළුවන් ගොඩක් Complex Problems වලට Smart Solutions දෙන්න. අපි අද පොඩි Example එකකින් මේක කොහොමද කරන්නේ කියලා බැලුවා. මේක ඔයාලට හොඳ ආරම්භයක් වෙයි කියලා මම හිතනවා.

දැන් ඉතින් ඔයාලගේ වාරේ. මේ Concepts ටික Practical කරලා බලන්න. ඔයාලගේම Project එකක් හදලා මේක Implement කරන්න. ගැටලු ආවොත් බය වෙන්න එපා. Google කරන්න, Stack Overflow බලන්න, ඒ වගේම අපේ Comments Section එකේ ප්‍රශ්න අහන්න. ඔයාලගේ අත්දැකීම් ගැනත් අපිට කියන්න අමතක කරන්න එපා. මොකද මේවා තමයි අපි ඉගෙනගන්න හොඳම ක්‍රම.

එහෙනම් තවත් වටිනා ලිපියකින් හමුවෙන තුරු, සියලු දෙනාටම සුභ දවසක්!