自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SpringBoot與Apache Drill整合,實(shí)現(xiàn)非結(jié)構(gòu)化數(shù)據(jù)的實(shí)時(shí)查詢(xún)與數(shù)據(jù)湖分析系統(tǒng)

開(kāi)發(fā) 前端
隨著業(yè)務(wù)的發(fā)展,我們公司堆積了大量的非結(jié)構(gòu)化數(shù)據(jù),如日志文件、社交媒體數(shù)據(jù)、傳感器數(shù)據(jù)等。傳統(tǒng)數(shù)據(jù)倉(cāng)庫(kù)難以有效處理這些多樣化的數(shù)據(jù)類(lèi)型。

隨著業(yè)務(wù)的發(fā)展,我們公司堆積了大量的非結(jié)構(gòu)化數(shù)據(jù),如日志文件、社交媒體數(shù)據(jù)、傳感器數(shù)據(jù)等。傳統(tǒng)數(shù)據(jù)倉(cāng)庫(kù)難以有效處理這些多樣化的數(shù)據(jù)類(lèi)型。為了更好地利用這些數(shù)據(jù)資產(chǎn),提高數(shù)據(jù)分析效率,我們需要一個(gè)實(shí)時(shí)查詢(xún)能力、靈活的數(shù)據(jù)存儲(chǔ)和管理方案。

Apache Drill在我們項(xiàng)目中的優(yōu)勢(shì)

靈活性:

  • 我們的數(shù)據(jù)來(lái)源多樣,包括 JSON 日志文件、CSV 文件和 MongoDB 數(shù)據(jù)庫(kù)。Drill 的 Schema-Free 特性使得我們可以輕松地查詢(xún)這些不同類(lèi)型的數(shù)據(jù),而無(wú)需提前定義模式。

性能:

  • Drill 的分布式架構(gòu)使其能夠高效地處理大規(guī)模數(shù)據(jù)集。這對(duì)于我們的大數(shù)據(jù)分析需求至關(guān)重要。

易于集成:

  • Drill 支持標(biāo)準(zhǔn)的 SQL 接口,便于與現(xiàn)有的 BI 工具(如 Tableau、Power BI)和 Spring Boot 應(yīng)用程序集成。

低成本:

  • 使用 Drill 可以避免購(gòu)買(mǎi)昂貴的商業(yè)查詢(xún)引擎許可證,從而降低整體運(yùn)營(yíng)成本。

Apache Drill

Apache Drill是一個(gè)開(kāi)源的分布式 SQL 查詢(xún)引擎,專(zhuān)為大規(guī)模數(shù)據(jù)湖和 NoSQL 存儲(chǔ)系統(tǒng)設(shè)計(jì)。它允許用戶(hù)通過(guò)標(biāo)準(zhǔn)的 SQL 接口查詢(xún)結(jié)構(gòu)化、半結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù),而無(wú)需預(yù)先定義模式或架構(gòu)。

Schema-Free 查詢(xún):

  • Drill 不需要預(yù)先定義數(shù)據(jù)模式即可進(jìn)行查詢(xún)。它可以動(dòng)態(tài)地讀取和解析多種數(shù)據(jù)格式,包括 JSON、Parquet、Avro、CSV 等。

分布式架構(gòu):

  • Drill 采用分布式架構(gòu),可以處理 PB 級(jí)別的數(shù)據(jù)。它可以在多臺(tái)機(jī)器上并行執(zhí)行查詢(xún)?nèi)蝿?wù),提供高性能和可擴(kuò)展性。

標(biāo)準(zhǔn) SQL 支持:

  • Drill 支持標(biāo)準(zhǔn)的 SQL 語(yǔ)法,使得現(xiàn)有的 BI 工具和應(yīng)用程序可以無(wú)縫集成。這降低了學(xué)習(xí)曲線,并提高了開(kāi)發(fā)效率。

插件機(jī)制:

  • Drill 使用插件機(jī)制來(lái)支持不同的數(shù)據(jù)存儲(chǔ)系統(tǒng)。內(nèi)置插件包括 HDFS、MapR-FS、MongoDB、Cassandra 等,還可以通過(guò)編寫(xiě)自定義插件來(lái)擴(kuò)展支持更多數(shù)據(jù)源。

實(shí)時(shí)查詢(xún)能力:

  • Drill 提供低延遲的數(shù)據(jù)訪問(wèn)和查詢(xún)能力,適用于實(shí)時(shí)數(shù)據(jù)分析場(chǎng)景。

嵌套數(shù)據(jù)支持:

  • Drill 能夠處理嵌套數(shù)據(jù)結(jié)構(gòu)(如 JSON 和 Avro),并且可以遞歸地展開(kāi)這些結(jié)構(gòu)以進(jìn)行查詢(xún)。

Web UI:

  • Drill 提供了一個(gè)簡(jiǎn)單的 Web 界面,用于監(jiān)控集群狀態(tài)、查看查詢(xún)?nèi)罩竞凸芾砼渲谩?/span>

哪些公司使用了Apache Drill?

Intel

  • 用途: Intel 使用 Apache Drill 進(jìn)行芯片設(shè)計(jì)和制造過(guò)程中的數(shù)據(jù)分析,以提高產(chǎn)品質(zhì)量和生產(chǎn)效率。
  • 優(yōu)勢(shì): Drill 的高性能和可擴(kuò)展性滿(mǎn)足了 Intel 復(fù)雜的數(shù)據(jù)處理需求。

Yahoo!

  • 用途: Yahoo! 使用 Apache Drill 進(jìn)行大規(guī)模的數(shù)據(jù)分析和報(bào)告生成。
  • 優(yōu)勢(shì): Drill 的插件機(jī)制支持多種數(shù)據(jù)源,便于整合不同的數(shù)據(jù)存儲(chǔ)系統(tǒng)。

Airbnb

  • 用途: Airbnb 使用 Apache Drill 進(jìn)行房源數(shù)據(jù)和用戶(hù)行為分析,以提升用戶(hù)體驗(yàn)和平臺(tái)性能。
  • 優(yōu)勢(shì): Drill 的 Schema-Free 查詢(xún)特性使得 Airbnb 能夠快速適應(yīng)不斷變化的數(shù)據(jù)需求。

PayPal

  • 用途: PayPal 使用 Apache Drill 進(jìn)行交易數(shù)據(jù)和用戶(hù)活動(dòng)的分析,以提高欺詐檢測(cè)和風(fēng)險(xiǎn)評(píng)估的能力。
  • 優(yōu)勢(shì): Drill 的高性能和可擴(kuò)展性滿(mǎn)足了 PayPal 大規(guī)模數(shù)據(jù)處理的需求。

eBay

  • 用途: eBay 使用 Apache Drill 進(jìn)行大規(guī)模的日志分析和用戶(hù)行為分析。
  • 優(yōu)勢(shì): Drill 的 Schema-Free 查詢(xún)特性使得 eBay 能夠輕松地分析各種格式的數(shù)據(jù)。

LinkedIn

  • 用途: LinkedIn 使用 Apache Drill 進(jìn)行大規(guī)模的社會(huì)網(wǎng)絡(luò)數(shù)據(jù)分析和用戶(hù)行為跟蹤。
  • 優(yōu)勢(shì): Drill 的靈活查詢(xún)能力使其能夠處理復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和關(guān)系。

Adobe

  • 用途: Adobe 使用 Apache Drill 進(jìn)行數(shù)字營(yíng)銷(xiāo)數(shù)據(jù)的分析,特別是在客戶(hù)體驗(yàn)管理和廣告投放優(yōu)化方面。
  • 優(yōu)勢(shì): Drill 的標(biāo)準(zhǔn) SQL 支持使得 Adobe 可以利用現(xiàn)有的 BI 工具進(jìn)行復(fù)雜的報(bào)表生成。

Uber

  • 用途: Uber 使用 Apache Drill 進(jìn)行運(yùn)營(yíng)數(shù)據(jù)和地理空間數(shù)據(jù)分析,以?xún)?yōu)化路線規(guī)劃和司機(jī)調(diào)度。
  • 優(yōu)勢(shì): Drill 的分布式架構(gòu)和高性能查詢(xún)能力使其能夠處理實(shí)時(shí)數(shù)據(jù)流。

啟動(dòng)Apache Drill

我這邊已經(jīng)啟動(dòng)了Apache Drill。

你可以從Apache Drill官方網(wǎng)站 (https://drill.apache.org/download/)下載并按照官方文檔進(jìn)行安裝。超級(jí)簡(jiǎn)單!

代碼實(shí)操

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>data-lake-analysis</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath/><!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.drill.exec</groupId>
            <artifactId>drill-jdbc-all</artifactId>
            <version>1.21.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-validation</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

配置Drill

application.properties文件中配置Drill:

# 數(shù)據(jù)庫(kù)連接配置
spring.datasource.url=jdbc:drill:zk=local
spring.datasource.driver-class-name=org.apache.drill.jdbc.Driver
spring.jpa.show-sql=true

# 服務(wù)器端口配置
server.port=8080

Controller

package com.example.datalakeanalysis.controller;

import com.example.datalakeanalysis.exception.ApiRequestException;
import com.example.datalakeanalysis.service.DataLakeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 控制器類(lèi),處理HTTP請(qǐng)求
@RestController
@RequestMapping("/api/v1")
publicclass DataLakeController {

    @Autowired
    private DataLakeService dataLakeService;  // 自動(dòng)注入數(shù)據(jù)湖服務(wù)

    // 處理GET請(qǐng)求,執(zhí)行銷(xiāo)售數(shù)據(jù)查詢(xún)
    @GetMapping("/sales/query")
    public List<Map<String, Object>> executeSalesQuery(@RequestParam@Valid String sql) throws SQLException {
        return dataLakeService.executeQuery(sql);  // 調(diào)用服務(wù)層方法執(zhí)行查詢(xún)并返回結(jié)果
    }

    // 處理驗(yàn)證異常,返回400 Bad Request狀態(tài)碼
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map<String, String> handleValidationExceptions(
            MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();  // 獲取字段名
            String errorMessage = error.getDefaultMessage();     // 獲取錯(cuò)誤信息
            errors.put(fieldName, errorMessage);                 // 將字段名和錯(cuò)誤信息放入Map
        });
        return errors;                                         // 返回錯(cuò)誤信息Map
    }

    // 處理SQL異常,返回500 Internal Server Error狀態(tài)碼
    @ExceptionHandler(SQLException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Map<String, String> handleSQLExceptions(SQLException ex) {
        Map<String, String> error = new HashMap<>();
        error.put("message", "Database query failed: " + ex.getMessage());  // 設(shè)置錯(cuò)誤消息
        return error;                                                         // 返回錯(cuò)誤信息Map
    }

    // 處理所有其他異常,返回500 Internal Server Error狀態(tài)碼
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Map<String, String> handleGenericExceptions(Exception ex) {
        Map<String, String> error = new HashMap<>();
        error.put("message", "An unexpected error occurred: " + ex.getMessage());  // 設(shè)置錯(cuò)誤消息
        return error;                                                             // 返回錯(cuò)誤信息Map
    }
}

自定義API請(qǐng)求異常類(lèi)

package com.example.datalakeanalysis.exception;

// 自定義API請(qǐng)求異常類(lèi)
publicclass ApiRequestException extends RuntimeException {

    // 構(gòu)造函數(shù),接受錯(cuò)誤消息
    public ApiRequestException(String message) {
        super(message);
    }

    // 構(gòu)造函數(shù),接受錯(cuò)誤消息和原因
    public ApiRequestException(String message, Throwable cause) {
        super(message, cause);
    }
}

異常響應(yīng)類(lèi)

package com.example.datalakeanalysis.exception;

import lombok.AllArgsConstructor;
import lombok.Data;

// 異常響應(yīng)類(lèi),包含錯(cuò)誤消息和詳細(xì)信息
@Data
@AllArgsConstructor
public class ApiRequestExceptionResponse {
    private String message;  // 錯(cuò)誤消息
    private String details;  // 詳細(xì)信息
}

全局異常處理器

package com.example.datalakeanalysis.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;

// 全局異常處理器,處理所有未捕獲的異常
@ControllerAdvice
publicclass GlobalExceptionHandler {

    // 處理ApiRequestException異常,返回400 Bad Request狀態(tài)碼
    @ExceptionHandler(ApiRequestException.class)
    public ResponseEntity<Object> handleApiRequestException(ApiRequestException e, WebRequest request) {
        ApiRequestExceptionResponse exceptionResponse = new ApiRequestExceptionResponse(e.getMessage(), request.getDescription(false));
        returnnew ResponseEntity<>(exceptionResponse, HttpStatus.BAD_REQUEST);
    }

    // 處理所有其他異常,返回500 Internal Server Error狀態(tài)碼
    @ExceptionHandler(Exception.class)
    public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) {
        ApiRequestExceptionResponse exceptionResponse = new ApiRequestExceptionResponse(ex.getMessage(),
                request.getDescription(false));
        returnnew ResponseEntity<>(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

銷(xiāo)售數(shù)據(jù)模型類(lèi)

package com.example.datalakeanalysis.model;

import lombok.Data;

// 銷(xiāo)售數(shù)據(jù)模型類(lèi),使用Lombok簡(jiǎn)化getter和setter方法的編寫(xiě)
@Data
public class Sale {
    private String id;          // 銷(xiāo)售記錄ID
    private String product;     // 產(chǎn)品名稱(chēng)
    private double amount;      // 銷(xiāo)售金額
    private String date;        // 銷(xiāo)售日期
}

數(shù)據(jù)湖服務(wù)類(lèi)

package com.example.datalakeanalysis.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 數(shù)據(jù)湖服務(wù)類(lèi),負(fù)責(zé)執(zhí)行SQL查詢(xún)并返回結(jié)果
@Service
publicclass DataLakeService {

    @Autowired
    private DataSource dataSource;  // 自動(dòng)注入數(shù)據(jù)源

    // 執(zhí)行SQL查詢(xún)的方法
    public List<Map<String, Object>> executeQuery(String sql) throws SQLException {
        try (Connection connection = dataSource.getConnection();  // 獲取數(shù)據(jù)庫(kù)連接
             Statement statement = connection.createStatement();       // 創(chuàng)建Statement對(duì)象
             ResultSet resultSet = statement.executeQuery(sql)) {      // 執(zhí)行SQL查詢(xún)并獲取結(jié)果集

            List<Map<String, Object>> result = new ArrayList<>();   // 存儲(chǔ)查詢(xún)結(jié)果的列表
            while (resultSet.next()) {                              // 遍歷結(jié)果集中的每一行
                Map<String, Object> row = new HashMap<>();            // 每一行的數(shù)據(jù)存儲(chǔ)在一個(gè)Map中
                for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {  // 遍歷每一列
                    row.put(resultSet.getMetaData().getColumnName(i), resultSet.getObject(i));  // 將列名和值放入Map
                }
                result.add(row);                                      // 將Map添加到結(jié)果列表中
            }

            return result;                                          // 返回查詢(xún)結(jié)果
        }
    }
}

啟動(dòng)類(lèi)

package com.example.datalakeanalysis;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// 主啟動(dòng)類(lèi),用于啟動(dòng)Spring Boot應(yīng)用程序
@SpringBootApplication
public class DataLakeAnalysisApplication {

    // 程序入口點(diǎn)
    public static void main(String[] args) {
        SpringApplication.run(DataLakeAnalysisApplication.class, args);
    }
}


責(zé)任編輯:武曉燕 來(lái)源: Java知識(shí)日歷
相關(guān)推薦

2021-12-12 08:37:18

結(jié)構(gòu)化數(shù)據(jù)非結(jié)構(gòu)化數(shù)據(jù)數(shù)據(jù)

2024-05-27 00:32:45

2018-04-03 14:00:03

結(jié)構(gòu)化數(shù)據(jù)非結(jié)構(gòu)化數(shù)據(jù)數(shù)據(jù)庫(kù)

2025-03-11 09:28:34

2017-11-16 05:22:34

非結(jié)構(gòu)化數(shù)據(jù)分析數(shù)據(jù)

2019-07-13 15:00:17

結(jié)構(gòu)化SQLNOSQL數(shù)據(jù)庫(kù)

2011-05-25 15:16:55

非結(jié)構(gòu)化數(shù)據(jù)庫(kù)異構(gòu)數(shù)據(jù)庫(kù)

2023-01-06 08:00:00

關(guān)系數(shù)據(jù)庫(kù)數(shù)據(jù)庫(kù)機(jī)器學(xué)習(xí)

2025-04-01 08:38:41

2019-10-18 13:07:14

PB數(shù)據(jù)非結(jié)構(gòu)化數(shù)據(jù)數(shù)據(jù)集

2014-02-09 09:53:05

2009-07-28 11:44:37

布線系統(tǒng)結(jié)構(gòu)化

2025-04-14 01:00:00

Calcite電商系統(tǒng)MySQL

2023-10-13 07:25:50

2023-02-26 00:12:10

Hadoop數(shù)據(jù)湖存儲(chǔ)

2017-05-20 10:36:37

非結(jié)構(gòu)化數(shù)據(jù)分析技術(shù)

2024-05-10 12:52:01

2018-05-14 12:30:49

數(shù)據(jù)備份非結(jié)構(gòu)

2009-02-16 15:41:04

非結(jié)構(gòu)化數(shù)據(jù)SQL Server SQL Server
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)