最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot 集成 Apache IoTDB 詳細(xì)過(guò)程

 更新時(shí)間:2026年05月15日 10:29:32   作者:觀望過(guò)往  
本文介紹了SpringBoot項(xiàng)目集成Apache IoTDB的完整流程,包括集成前準(zhǔn)備、核心依賴配置、配置文件設(shè)置、數(shù)據(jù)操作實(shí)現(xiàn)、高級(jí)特性配置、常見(jiàn)問(wèn)題與排查等內(nèi)容,通過(guò)本文指南,開(kāi)發(fā)者可以快速搭建穩(wěn)定、高效的物聯(lián)網(wǎng)時(shí)序數(shù)據(jù)存儲(chǔ)系統(tǒng),并根據(jù)業(yè)務(wù)需求選擇合適的技術(shù)方案

Apache IoTDB 是一款專為物聯(lián)網(wǎng)場(chǎng)景設(shè)計(jì)的時(shí)序數(shù)據(jù)庫(kù),具備高寫(xiě)入性能、低存儲(chǔ)成本和靈活的查詢能力。本文將詳細(xì)介紹 Spring Boot 項(xiàng)目集成 IoTDB 的完整流程,包括環(huán)境準(zhǔn)備、依賴配置、數(shù)據(jù)讀寫(xiě)操作、連接池優(yōu)化及常見(jiàn)問(wèn)題解決,幫助開(kāi)發(fā)者快速搭建穩(wěn)定的 IoT 數(shù)據(jù)存儲(chǔ)解決方案。

一、集成前準(zhǔn)備

1.1 環(huán)境要求

  • JDK 版本:1.8 及以上(IoTDB 1.0 + 推薦 JDK 11)
  • Spring Boot 版本:2.3.x ~ 3.2.x(本文以 2.7.10 為例)
  • Apache IoTDB 版本:1.2.0(最新穩(wěn)定版,兼容 1.0 + 所有版本)
  • Maven/Gradle:項(xiàng)目構(gòu)建工具(本文以 Maven 為例)

1.2 IoTDB 服務(wù)部署

  • 下載安裝包:從IoTDB 官網(wǎng)下載對(duì)應(yīng)版本的二進(jìn)制包
  • 啟動(dòng)服務(wù)
  • Linux/Mac:執(zhí)行 sbin/``start-server.sh
  • Windows:執(zhí)行 sbin\start-server.bat
  1. 驗(yàn)證服務(wù):通過(guò) telnet ``localhost`` 6667iotdb-cli 工具連接,確認(rèn)服務(wù)正常運(yùn)行

二、核心依賴配置

在 Spring Boot 項(xiàng)目的pom.xml中添加 IoTDB 相關(guān)依賴,主要包括 JDBC 驅(qū)動(dòng)和 Spring 數(shù)據(jù)集成支持(可選)。

2.1 基礎(chǔ)依賴(JDBC 方式)

<!-- IoTDB JDBC驅(qū)動(dòng) -->
<dependency>
         <groupId>org.apache.iotdb</groupId>
         <artifactId>iotdb-jdbc</artifactId>
         <version>1.2.0</version>
</dependency>
<!-- Spring Boot JDBC starter(可選,用于簡(jiǎn)化JDBC操作) -->
<dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 連接池(推薦HikariCP,Spring Boot默認(rèn)集成) -->
<dependency>
         <groupId>com.zaxxer</groupId>
         <artifactId>HikariCP</artifactId>
         <version>5.0.1</version>
</dependency>

2.2 高級(jí)依賴(Spring Data JPA/MyBatis)

若需使用 ORM 框架,需額外添加對(duì)應(yīng)依賴(以 MyBatis 為例):

<!-- MyBatis整合Spring Boot -->
<dependency>
         <groupId>org.mybatis.spring.boot</groupId>
         <artifactId>mybatis-spring-boot-starter</artifactId>
         <version>2.3.1</version>
</dependency>
<!-- 分頁(yè)插件(可選) -->
<dependency>
         <groupId>com.github.pagehelper</groupId>
         <artifactId>pagehelper-spring-boot-starter</artifactId>
         <version>1.4.6</version>
</dependency>

三、配置文件設(shè)置

application.ymlapplication.properties中配置 IoTDB 連接信息,核心包括 JDBC URL、賬號(hào)密碼及連接池參數(shù)。

3.1 基礎(chǔ)配置(application.yml)

spring:
       datasource:
         # IoTDB JDBC URL格式:jdbc:iotdb://<host>:<port>/\[?<params>]
         url: jdbc:iotdb://localhost:6667/?enableAutoCreateSchema=true\&timeZone=UTC+8
         username: root  # 默認(rèn)用戶名
         password: root  # 默認(rèn)密碼
         driver-class-name: org.apache.iotdb.jdbc.IoTDBDriver
         # HikariCP連接池配置
         hikari:
           maximum-pool-size: 10  # 最大連接數(shù)(根據(jù)業(yè)務(wù)調(diào)整)
           minimum-idle: 2        # 最小空閑連接數(shù)
           idle-timeout: 300000   # 空閑連接超時(shí)時(shí)間(5分鐘)
           connection-timeout: 30000  # 連接超時(shí)時(shí)間(30秒)
           max-lifetime: 1800000  # 連接最大生命周期(30分鐘)

3.2 關(guān)鍵參數(shù)說(shuō)明

參數(shù)名說(shuō)明示例值
enableAutoCreateSchema是否自動(dòng)創(chuàng)建時(shí)間序列(新手推薦開(kāi)啟)true
timeZone時(shí)區(qū)配置(避免時(shí)間戳偏差)UTC+8/Asia/Shanghai
fetchSize查詢結(jié)果分頁(yè)大?。ù髷?shù)據(jù)量查詢必備)1000
username/passwordIoTDB 認(rèn)證信息(可通過(guò)iotdb-env.sh修改)root/root

四、數(shù)據(jù)操作實(shí)現(xiàn)

Spring Boot 集成 IoTDB 支持多種數(shù)據(jù)操作方式,包括原生 JDBC、JdbcTemplate、MyBatis 等,以下分別介紹核心用法。

4.1 原生 JDBC 操作(基礎(chǔ))

通過(guò)DriverManager直接創(chuàng)建連接,適用于簡(jiǎn)單場(chǎng)景:

import org.apache.iotdb.jdbc.IoTDBDriver;
import java.sql.*;
@Service
public class IoTDBNativeService {
         // IoTDB連接信息
         private static final String URL = "jdbc:iotdb://localhost:6667/";
         private static final String USER = "root";
         private static final String PASSWORD = "root";
         // 寫(xiě)入時(shí)序數(shù)據(jù)(單條)
         public void insertSingleData() throws SQLException {
             try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
                  PreparedStatement pstmt = conn.prepareStatement(
                      "INSERT INTO root.sensor.demo(timestamp, temperature, humidity) VALUES(?, ?, ?)")) {
                 // 設(shè)置參數(shù):時(shí)間戳(毫秒級(jí))、溫度、濕度
                 pstmt.setLong(1, System.currentTimeMillis());
                 pstmt.setFloat(2, 25.6f);
                 pstmt.setInt(3, 60);
                 pstmt.executeUpdate();
                 System.out.println("數(shù)據(jù)寫(xiě)入成功");
             }
         }
         // 查詢時(shí)序數(shù)據(jù)(時(shí)間范圍)
         public void queryDataByTimeRange() throws SQLException {
             String sql = "SELECT temperature, humidity " +
                          "FROM root.sensor.demo " +
                          "WHERE time >= ? AND time <= ?";
             try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
                  PreparedStatement pstmt = conn.prepareStatement(sql)) {
                 // 設(shè)置查詢時(shí)間范圍(1小時(shí)內(nèi)數(shù)據(jù))
                 long endTime = System.currentTimeMillis();
                 long startTime = endTime - 3600 * 1000;
                 pstmt.setLong(1, startTime);
                 pstmt.setLong(2, endTime);
                 // 處理查詢結(jié)果
                 try (ResultSet rs = pstmt.executeQuery()) {
                     while (rs.next()) {
                         System.out.printf("時(shí)間戳:%d, 溫度:%f, 濕度:%d%n",
                             rs.getLong("time"),  // IoTDB默認(rèn)時(shí)間列名為"time"
                             rs.getFloat("temperature"),
                             rs.getInt("humidity"));
                     }
                 }
             }
         }
}

4.2 JdbcTemplate 操作(推薦)

借助 Spring Boot 的JdbcTemplate簡(jiǎn)化 JDBC 代碼,減少 try-catch 冗余:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class IoTDBJdbcTemplateService {
         @Autowired
         private JdbcTemplate jdbcTemplate;
         // 批量寫(xiě)入數(shù)據(jù)(高效)
         public void batchInsertData(List<Object\[]> dataList) {
             String sql = "INSERT INTO root.sensor.demo(timestamp, temperature, humidity) VALUES(?, ?, ?)";
             // 批量執(zhí)行(推薦一次批量1000-5000條,平衡性能與內(nèi)存)
             jdbcTemplate.batchUpdate(sql, dataList);
             System.out.printf("批量寫(xiě)入成功,共%d條數(shù)據(jù)", dataList.size());
         }
         // 分頁(yè)查詢數(shù)據(jù)
         public List<Map<String, Object>> queryDataWithPage(long startTime, long endTime, int pageNum, int pageSize) {
             // IoTDB分頁(yè)通過(guò)LIMIT和OFFSET實(shí)現(xiàn)
             String sql = String.format(
                 "SELECT time, temperature, humidity " +
                 "FROM root.sensor.demo " +
                 "WHERE time >= ? AND time <= ? " +
                 "ORDER BY time DESC " +
                 "LIMIT %d OFFSET %d",
                 pageSize, (pageNum - 1) * pageSize
             );
             return jdbcTemplate.queryForList(sql, startTime, endTime);
         }
         // 創(chuàng)建時(shí)間序列(手動(dòng)模式,enableAutoCreateSchema=false時(shí)需調(diào)用)
         public void createTimeSeries() {
             String sql = "CREATE TIMESERIES root.sensor.demo.temperature " +
                          "WITH DATATYPE=FLOAT, ENCODING=RLE, COMPRESSOR=SNAPPY; " +
                          "CREATE TIMESERIES root.sensor.demo.humidity " +
                          "WITH DATATYPE=INT32, ENCODING=PLAIN, COMPRESSOR=SNAPPY";
             jdbcTemplate.execute(sql);
             System.out.println("時(shí)間序列創(chuàng)建成功");
         }
}

4.3 MyBatis 操作(ORM 方式)

對(duì)于復(fù)雜 SQL 場(chǎng)景,推薦使用 MyBatis,通過(guò) Mapper 接口實(shí)現(xiàn)數(shù)據(jù)操作。

4.3.1 定義 Mapper 接口

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
public interface IoTDBMapper {
         // 插入單條數(shù)據(jù)
         void insertData(@Param("timestamp") long timestamp,
                         @Param("temperature") float temperature,
                         @Param("humidity") int humidity);
         // 時(shí)間范圍查詢(帶參數(shù))
         List<Map<String, Object>> queryByTimeRange(@Param("startTime") long startTime,
                                                    @Param("endTime") long endTime);
         // 分頁(yè)查詢(使用PageHelper插件)
         List<Map<String, Object>> queryWithPage(@Param("startTime") long startTime,
                                                 @Param("endTime") long endTime);
}

4.3.2 編寫(xiě) Mapper XML(resources/mapper/IoTDBMapper.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"      
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.iotdb.mapper.IoTDBMapper">
         <!-- 插入數(shù)據(jù) -->
         <insert id="insertData">
             INSERT INTO root.sensor.demo(timestamp, temperature, humidity)
             VALUES(#{timestamp}, #{temperature}, #{humidity})
         </insert>
         <!-- 時(shí)間范圍查詢 -->
         <select id="queryByTimeRange" resultType="java.util.Map">
             SELECT time, temperature, humidity
             FROM root.sensor.demo
             WHERE time >= #{startTime} AND time <= #{endTime}
             ORDER BY time ASC
         </select>
         <!-- 分頁(yè)查詢(PageHelper自動(dòng)攔截添加LIMIT) -->
         <select id="queryWithPage" resultType="java.util.Map">
             SELECT time, temperature, humidity
             FROM root.sensor.demo
             WHERE time >= #{startTime} AND time <= #{endTime}
             ORDER BY time DESC
         </select>
</mapper>

4.3.3 服務(wù)層調(diào)用

import com.example.iotdb.mapper.IoTDBMapper;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class IoTDBMyBatisService {
         @Autowired
         private IoTDBMapper ioTDBMapper;
         // 分頁(yè)查詢(使用PageHelper)
         public List<Map<String, Object>> queryWithPageHelper(long startTime, long endTime, int pageNum, int pageSize) {
             // 開(kāi)啟分頁(yè)(PageHelper會(huì)自動(dòng)對(duì)下一次查詢生效)
             PageHelper.startPage(pageNum, pageSize);
             return ioTDBMapper.queryWithPage(startTime, endTime);
         }
}

五、高級(jí)特性配置

5.1 連接池監(jiān)控

通過(guò) Spring Boot Actuator 監(jiān)控連接池狀態(tài),添加依賴:

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

配置監(jiān)控端點(diǎn)(application.yml):

management:
       endpoints:
         web:
           exposure:
             include: hikaricp,health,info  # 暴露HikariCP監(jiān)控端點(diǎn)
       endpoint:
         hikaricp:
           enabled: true  # 啟用HikariCP監(jiān)控

訪問(wèn)http://localhost:8080/actuator/hikaricp即可查看連接池詳情(如活躍連接數(shù)、空閑連接數(shù)等)。

5.2 數(shù)據(jù)分區(qū)與存儲(chǔ)優(yōu)化

IoTDB 支持按時(shí)間分區(qū)(如按天 / 按月),在配置文件中優(yōu)化存儲(chǔ)參數(shù):

# IoTDB服務(wù)端配置(iotdb-engine.properties)
storage_group_partition_strategy=MONTH  # 存儲(chǔ)組按月份分區(qū)
time_partition_interval=86400000        # 時(shí)間分區(qū)間隔(1天,單位:毫秒)
compressor=SNAPPY                       # 全局壓縮算法(SNAPPY/LZ4)

5.3 異常處理與重試機(jī)制

使用 Spring 的@Retryable實(shí)現(xiàn)連接重試,添加依賴:

<dependency>
         <groupId>org.springframework.retry</groupId>
         <artifactId>spring-retry</artifactId>
         <version>1.3.4</version>
</dependency>
<dependency>
         <groupId>org.aspectj</groupId>
         <artifactId>aspectjweaver</artifactId>
         <version>1.9.19</version>
</dependency>

在啟動(dòng)類添加@EnableRetry注解,服務(wù)層方法添加重試邏輯:

import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import java.sql.SQLException;
@Service
public class IoTDBRetryService {
         // 連接失敗時(shí)重試3次,間隔1秒
         @Retryable(value = SQLException.class, maxAttempts = 3, backoff = @Backoff(delay = 1000))
         public void insertWithRetry(long timestamp, float temperature, int humidity) throws SQLException {
             // 數(shù)據(jù)插入邏輯(同4.1/4.2)
         }
}

六、常見(jiàn)問(wèn)題與排查

6.1 連接超時(shí)問(wèn)題

  • 原因 1:IoTDB 服務(wù)未啟動(dòng)或端口被占用
    • 排查:執(zhí)行netstat -tuln | grep 6667查看端口是否被占用,重啟 IoTDB 服務(wù)。
  • 原因 2:防火墻攔截端口
    • 解決:開(kāi)放 6667 端口(Linux:firewall-cmd --add-port=6667/tcp --permanent)。

6.2 時(shí)間序列創(chuàng)建失敗

  • 錯(cuò)誤信息org.apache.iotdb.rpc.TSStatusCode: PATH_ALREADY_EXISTS
    • 原因:重復(fù)創(chuàng)建已存在的時(shí)間序列
    • 解決:刪除重復(fù)的CREATE TIMESERIES語(yǔ)句,或開(kāi)啟enableAutoCreateSchema=true自動(dòng)創(chuàng)建。

6.3 批量寫(xiě)入性能低

  • 優(yōu)化方向
    • 增大批量寫(xiě)入條數(shù)(建議 1000-5000 條 / 批次)
    • 使用Session客戶端而非 JDBC(IoTDB 提供更高效的 Session API)
    • 服務(wù)端配置max_write_batch_size=10000(iotdb-engine.properties)

七、擴(kuò)展:使用 Session API(高性能)

對(duì)于高并發(fā)寫(xiě)入場(chǎng)景,推薦使用 IoTDB 原生 Session API,性能優(yōu)于 JDBC:

import org.apache.iotdb.session.Session;
import org.apache.iotdb.tsfile.write.record.Tablet;
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class IoTDBSessionService {
         private Session session;
         // 初始化Session連接
         public void initSession() throws Exception {
             session = new Session("localhost", 6667, "root", "root");
             session.open();
             // 設(shè)置批量寫(xiě)入?yún)?shù)
             session.setBatchSize(5000);
             session.setFetchSize(5000);
}
	 // 批量寫(xiě)入數(shù)據(jù)(Session API 核心優(yōu)勢(shì):低開(kāi)銷、高吞吐量)
public void batchInsertWithSession (List timestamps, List temperatures, List humidities) throws Exception {
	 // 1. 定義時(shí)間序列路徑(格式:root. 存儲(chǔ)組。設(shè)備。測(cè)量值)
	 String deviceId = "root.sensor.demo";
	 // 2. 定義測(cè)量值 schema(數(shù)據(jù)類型、編碼方式)
	 List measurements = new ArrayList<>();
	 List schemas = new ArrayList<>();
	 // 添加溫度測(cè)量值(FLOAT 類型,RLE 編碼適合連續(xù)數(shù)值)
	 measurements.add ("temperature");
	 schemas.add (new MeasurementSchema ("temperature", TSDataType.FLOAT, TSEncoding.RLE));
	 // 添加濕度測(cè)量值(INT32 類型,PLAIN 編碼適合離散數(shù)值)
	 measurements.add ("humidity");
	 schemas.add (new MeasurementSchema ("humidity", TSDataType.INT32, TSEncoding.PLAIN));
	 // 3. 創(chuàng)建 Tablet(IoTDB 批量數(shù)據(jù)載體,比 JDBC Batch 更高效)
	 Tablet tablet = new Tablet (deviceId, schemas, timestamps.size ());
	 // 4. 填充數(shù)據(jù)(按列填充,減少 IO 開(kāi)銷)
	 int row = 0;
	 for (Long timestamp : timestamps) {
	 // 設(shè)置時(shí)間戳
	 tablet.addTimestamp (row, timestamp);
	 // 設(shè)置溫度值(第 0 列)
	 tablet.addValue (measurements.get (0), row, temperatures.get (row));
	 // 設(shè)置濕度值(第 1 列)
	 tablet.addValue (measurements.get (1), row, humidities.get (row));
	 row++;
	 }
	 // 5. 執(zhí)行批量寫(xiě)入(Session 會(huì)自動(dòng)處理連接復(fù)用和數(shù)據(jù)分片)
	 session.insertTablet (tablet);
	 System.out.printf ("Session API 批量寫(xiě)入成功,共 % d 條數(shù)據(jù)", timestamps.size ());
	 }
	 // 時(shí)間范圍查詢(Session API 支持更靈活的結(jié)果格式)
	 public List<Map<String, Object>> queryWithSession (long startTime, long endTime) throws Exception {
	 List<Map<String, Object>> resultList = new ArrayList<>();
	 // 1. 定義查詢參數(shù)
	 String deviceId = "root.sensor.demo";
	 List measurements = Arrays.asList ("temperature", "humidity");
	 // 2. 執(zhí)行查詢(返回 ResultSet,支持流式處理)
	 try (SessionDataSet resultSet = session.executeQuery (deviceId, measurements, startTime, endTime)) {
	 // 3. 解析查詢結(jié)果
	 while (resultSet.hasNext ()) {
	      Map<String, Object> dataMap = new HashMap<>();
	      // 獲取時(shí)間戳
	      dataMap.put ("timestamp", resultSet.nextTimestamp ());
	      // 獲取測(cè)量值(按順序匹配 measurements 列表)
	      dataMap.put ("temperature", resultSet.nextFloat ());
	      dataMap.put ("humidity", resultSet.nextInt ());
	      resultList.add (dataMap);
	   }
	}
	 return resultList;
}
// 關(guān)閉 Session 連接(建議在服務(wù)銷毀時(shí)調(diào)用)
@PreDestroy
public void closeSession () throws Exception {
	 if (session != null && session.isOpen ()) {
	   session.close ();
	   System.out.println ("Session 連接已關(guān)閉");
	 }
   }
}
### 7.1 Session API 與 JDBC 對(duì)比
| 特性                | Session API                          | JDBC                          |
|---------------------|--------------------------------------|-------------------------------|
| 性能                | 高(直接基于RPC,無(wú)JDBC協(xié)議開(kāi)銷)    | 中(需適配JDBC規(guī)范,額外開(kāi)銷)|
| 批量寫(xiě)入效率        | 極高(Tablet載體,按列存儲(chǔ))         | 中等(Statement Batch,按行處理)|
| 功能完整性          | 專注時(shí)序數(shù)據(jù)操作(寫(xiě)入、查詢、刪除) | 支持標(biāo)準(zhǔn)SQL操作(DDL、DML)   |
| 易用性              | 需熟悉IoTDB特有API                   | 通用SQL語(yǔ)法,學(xué)習(xí)成本低       |
| 適用場(chǎng)景            | 高并發(fā)寫(xiě)入(如設(shè)備實(shí)時(shí)上報(bào)數(shù)據(jù))     | 復(fù)雜查詢、多數(shù)據(jù)源兼容場(chǎng)景    |
## 八、項(xiàng)目實(shí)戰(zhàn):完整業(yè)務(wù)流程示例
以“溫濕度傳感器數(shù)據(jù)采集”為例,整合上述技術(shù)實(shí)現(xiàn)端到端業(yè)務(wù)邏輯。
### 8.1 實(shí)體類定義(封裝傳感器數(shù)據(jù))
\`\`\`java
public class SensorData {
         // 設(shè)備ID
         private String deviceId;
         // 采集時(shí)間戳(毫秒級(jí))
         private long timestamp;
         // 溫度(℃)
         private float temperature;
         // 濕度(%RH)
         private int humidity;
         // 省略getter/setter/構(gòu)造方法
}

8.2 業(yè)務(wù)服務(wù)層(整合 Session API 與異常處理)

@Service
public class SensorDataService {
         @Autowired
         private IoTDBSessionService sessionService;
         // 初始化Session(項(xiàng)目啟動(dòng)時(shí)執(zhí)行)
         @PostConstruct
         public void init() {
             try {
                 sessionService.initSession();
             } catch (Exception e) {
                 throw new RuntimeException("Session初始化失敗", e);
             }
         }
         // 接收傳感器數(shù)據(jù)并批量寫(xiě)入(支持重試)
         @Retryable(value = {Exception.class}, maxAttempts = 3, backoff = @Backoff(delay = 2000))
         public void batchSaveSensorData(List<SensorData> dataList) throws Exception {
             // 1. 數(shù)據(jù)預(yù)處理:按設(shè)備分組(Session API按設(shè)備寫(xiě)入更高效)
             Map<String, List<SensorData>> dataGroupByDevice = dataList.stream()
                     .collect(Collectors.groupingBy(SensorData::getDeviceId));
             // 2. 按設(shè)備批量寫(xiě)入
             for (Map.Entry<String, List<SensorData>> entry : dataGroupByDevice.entrySet()) {
                 String deviceId = entry.getKey();
                 List<SensorData> deviceDataList = entry.getValue();
                 // 3. 轉(zhuǎn)換為Session API所需格式
                 List<Long> timestamps = deviceDataList.stream().map(SensorData::getTimestamp).collect(Collectors.toList());
                 List<Float> temperatures = deviceDataList.stream().map(SensorData::getTemperature).collect(Collectors.toList());
                 List<Integer> humidities = deviceDataList.stream().map(SensorData::getHumidity).collect(Collectors.toList());
                 // 4. 調(diào)用Session API寫(xiě)入
                 sessionService.batchInsertWithSession(timestamps, temperatures, humidities);
             }
         }
         // 查詢指定設(shè)備的歷史數(shù)據(jù)(帶分頁(yè))
         public PageInfo<SensorData> querySensorData(String deviceId, long startTime, long endTime, int pageNum, int pageSize) throws Exception {
             // 1. 調(diào)用Session API查詢?cè)紨?shù)據(jù)
             List<Map<String, Object>> rawDataList = sessionService.queryWithSession(startTime, endTime);
             // 2. 數(shù)據(jù)轉(zhuǎn)換與分頁(yè)(手動(dòng)分頁(yè),避免內(nèi)存溢出)
             List<SensorData> sensorDataList = rawDataList.stream()
                     .map(map -> new SensorData(
                             deviceId,
                             (Long) map.get("timestamp"),
                             (Float) map.get("temperature"),
                             (Integer) map.get("humidity")
                     )).collect(Collectors.toList());
             // 3. 分頁(yè)處理(使用PageHelper工具類)
             PageHelper.startPage(pageNum, pageSize);
             Page<SensorData> page = new Page<>(sensorDataList);
             return new PageInfo<>(page);
         }
         // 重試失敗回調(diào)
         @Recover
         public void recover(Exception e) {
             System.err.println("數(shù)據(jù)寫(xiě)入重試失敗:" + e.getMessage());
             // 此處可添加告警邏輯(如發(fā)送郵件、短信通知運(yùn)維人員)
         }
}

8.3 控制層(提供 RESTful API)

@RestController
@RequestMapping("/api/sensor")
public class SensorDataController {
         @Autowired
         private SensorDataService sensorDataService;
         // 批量接收傳感器數(shù)據(jù)(POST請(qǐng)求)
         @PostMapping("/data/batch")
         public ResponseEntity<String> batchSave(@RequestBody List<SensorData> dataList) {
             try {
                 sensorDataService.batchSaveSensorData(dataList);
                 return ResponseEntity.ok("數(shù)據(jù)接收成功,共" + dataList.size() + "條");
             } catch (Exception e) {
                 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                         .body("數(shù)據(jù)處理失?。? + e.getMessage());
             }
         }
         // 查詢歷史數(shù)據(jù)(GET請(qǐng)求)
         @GetMapping("/data/history")
         public ResponseEntity<PageInfo<SensorData>> queryHistory(
                 @RequestParam String deviceId,
                 @RequestParam long startTime,
                 @RequestParam long endTime,
                 @RequestParam(defaultValue = "1") int pageNum,
                 @RequestParam(defaultValue = "20") int pageSize) {
             try {
                 PageInfo<SensorData> pageInfo = sensorDataService.querySensorData(
                         deviceId, startTime, endTime, pageNum, pageSize);
                 return ResponseEntity.ok(pageInfo);
             } catch (Exception e) {
                 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                         .body(null);
             }
         }
}

九、性能優(yōu)化最佳實(shí)踐

9.1 服務(wù)端優(yōu)化(iotdb-engine.properties)

  1. 內(nèi)存配置:根據(jù)服務(wù)器內(nèi)存調(diào)整,建議設(shè)置為物理內(nèi)存的 50%-70%
# 堆內(nèi)存大小(根據(jù)實(shí)際情況調(diào)整)
jvm_options=-Xms8g -Xmx8g
# 緩存大?。ㄌ嵘樵冃阅埽?
query_cache_size=1024MB
chunk_cache_size=2048MB
  1. 寫(xiě)入優(yōu)化:減少刷盤(pán)頻率,提升寫(xiě)入吞吐量
# 刷盤(pán)策略(周期性刷盤(pán),單位:毫秒)
flush_interval=30000
# 內(nèi)存塊大小(越大寫(xiě)入效率越高,建議16MB-64MB)
page_size=32MB
  1. 分區(qū)優(yōu)化:按業(yè)務(wù)場(chǎng)景選擇分區(qū)粒度
# 時(shí)間分區(qū)策略(MONTH/DAY/HOUR,高頻數(shù)據(jù)建議按小時(shí)分區(qū))
storage_group_partition_strategy=DAY
time_partition_interval=86400000

9.2 客戶端優(yōu)化(Spring Boot 項(xiàng)目)

  1. 連接池優(yōu)化:針對(duì) JDBC 方式
spring:
       datasource:
         hikari:
           maximum-pool-size: 20  # 高頻寫(xiě)入場(chǎng)景可適當(dāng)增大
           connection-timeout: 5000  # 縮短連接超時(shí)時(shí)間,快速失敗
           idle-timeout: 600000  # 空閑連接超時(shí)10分鐘,減少資源占用
  1. 批量寫(xiě)入策略
  • 單批次數(shù)據(jù)量控制在 1000-5000 條(平衡吞吐量與內(nèi)存占用)
  • 使用定時(shí)任務(wù)批量匯總數(shù)據(jù)(如每 5 秒執(zhí)行一次批量寫(xiě)入)
  1. 查詢優(yōu)化
  • 避免全表掃描,必須指定時(shí)間范圍(WHERE time >= ? AND time <= ?
  • 只查詢需要的測(cè)量值,避免SELECT *
  • 大數(shù)據(jù)量查詢使用分頁(yè)(LIMIT + OFFSET)或流式處理

十、總結(jié)與擴(kuò)展

本文詳細(xì)介紹了 Spring Boot 集成 Apache IoTDB 的完整流程,從基礎(chǔ)的 JDBC 連接到高性能的 Session API,再到實(shí)戰(zhàn)業(yè)務(wù)場(chǎng)景,覆蓋了物聯(lián)網(wǎng)時(shí)序數(shù)據(jù)存儲(chǔ)的核心需求。

10.1 擴(kuò)展方向

  • 多節(jié)點(diǎn)部署:IoTDB 支持集群模式,可通過(guò)session.setNodeUrls()配置多個(gè)服務(wù)節(jié)點(diǎn),實(shí)現(xiàn)負(fù)載均衡與高可用
  • 數(shù)據(jù)訂閱:使用 IoTDB 的Consumer API 實(shí)現(xiàn)數(shù)據(jù)實(shí)時(shí)訂閱(如監(jiān)控異常數(shù)據(jù)并實(shí)時(shí)告警)
  • 可視化集成:結(jié)合 Grafana(通過(guò) IoTDB 數(shù)據(jù)源插件)實(shí)現(xiàn)時(shí)序數(shù)據(jù)可視化展示
  • 數(shù)據(jù)備份與恢復(fù):使用 IoTDB 的backup工具實(shí)現(xiàn)定時(shí)備份,避免數(shù)據(jù)丟失

10.2 版本兼容性說(shuō)明

  • IoTDB 1.0+ 版本與 Spring Boot 2.3.x-3.2.x 完全兼容
  • 若使用 Spring Boot 3.x,需確保 JDK 版本為 17+,并升級(jí) IoTDB JDBC 驅(qū)動(dòng)至 1.2.0+
  • Session API 在 IoTDB 0.13+ 版本開(kāi)始支持,推薦使用 1.0+ 穩(wěn)定版

通過(guò)本文的指南,開(kāi)發(fā)者可快速搭建穩(wěn)定、高效的物聯(lián)網(wǎng)時(shí)序數(shù)據(jù)存儲(chǔ)系統(tǒng),并根據(jù)業(yè)務(wù)需求選擇合適的技術(shù)方案(JDBC/MyBatis/Session API),同時(shí)通過(guò)優(yōu)化配置充分發(fā)揮 IoTDB 的性能優(yōu)勢(shì)。

到此這篇關(guān)于Spring Boot 集成 Apache IoTDB 詳細(xì)過(guò)程的文章就介紹到這了,更多相關(guān)Spring Boot 集成 Apache IoTDB內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中Pattern.compile函數(shù)的使用詳解

    Java中Pattern.compile函數(shù)的使用詳解

    這篇文章主要介紹了Java中Pattern.compile函數(shù)的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java輕松實(shí)現(xiàn)權(quán)限認(rèn)證管理的示例代碼

    Java輕松實(shí)現(xiàn)權(quán)限認(rèn)證管理的示例代碼

    我們?cè)趯?shí)際開(kāi)發(fā)中經(jīng)常會(huì)進(jìn)行權(quán)限認(rèn)證管理,給不同的人加上對(duì)應(yīng)的角色和權(quán)限,本文將實(shí)現(xiàn)一個(gè)簡(jiǎn)易的權(quán)限驗(yàn)證管理系統(tǒng),感興趣的小伙伴可以了解下
    2023-12-12
  • Flink ExecutionGraph生成源碼解析

    Flink ExecutionGraph生成源碼解析

    這篇文章主要為大家介紹了Flink ExecutionGraph生成源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • mybatis Interceptor對(duì)UpdateTime自動(dòng)處理的實(shí)現(xiàn)方法

    mybatis Interceptor對(duì)UpdateTime自動(dòng)處理的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于使用mybatis Interceptor對(duì)UpdateTime自動(dòng)處理的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧
    2018-12-12
  • 詳解SpringBoot的Run方法

    詳解SpringBoot的Run方法

    本文給大家介紹了SpringBoot的Run方法,文中通過(guò)實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-10-10
  • Java超詳細(xì)講解ArrayList與順序表的用法

    Java超詳細(xì)講解ArrayList與順序表的用法

    ArrayList 類是一個(gè)可以動(dòng)態(tài)修改的數(shù)組,與普通數(shù)組的區(qū)別就是它是沒(méi)有固定大小的限制,我們可以添加或刪除元素。ArrayList 繼承了 AbstractList ,并實(shí)現(xiàn)了 List 接口,順序表是將元素順序地存放在一塊連續(xù)的存儲(chǔ)區(qū)里,元素間的順序關(guān)系由它們的存儲(chǔ)順序自然表示
    2022-06-06
  • SpringBoot中郵件任務(wù)的使用

    SpringBoot中郵件任務(wù)的使用

    這篇文章主要介紹了SpringBoot中郵件任務(wù)的使用,SpringBoot?郵件任務(wù)是指使用SpringBoot框架來(lái)實(shí)現(xiàn)郵件發(fā)送和接收的功能,通過(guò)SpringBoot的自動(dòng)配置和簡(jiǎn)化的開(kāi)發(fā)流程,我們可以輕松地集成郵件功能到我們的應(yīng)用程序中,需要的朋友可以參考下
    2023-10-10
  • 深入淺出講解Java比較器及數(shù)學(xué)常用類

    深入淺出講解Java比較器及數(shù)學(xué)常用類

    這篇文章主要介紹了深入淺出講解Java比較器及數(shù)學(xué)常用類,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Java 發(fā)送http請(qǐng)求上傳文件功能實(shí)例

    Java 發(fā)送http請(qǐng)求上傳文件功能實(shí)例

    本文通過(guò)實(shí)例代碼給大家介紹了Java 發(fā)送http請(qǐng)求上傳文件功能,需要的朋友參考下吧
    2017-06-06
  • Java中關(guān)于Null的9個(gè)解釋(Java Null詳解)

    Java中關(guān)于Null的9個(gè)解釋(Java Null詳解)

    這篇文章主要介紹了Java中關(guān)于Null的9個(gè)解釋(Java Null詳解),本文詳細(xì)講解了Java中Null的9個(gè)相關(guān)知識(shí),需要的朋友可以參考下
    2015-01-01

最新評(píng)論

武乡县| 容城县| 沙坪坝区| 馆陶县| 金堂县| 封丘县| 海伦市| 麻江县| 曲沃县| 磐安县| 邵阳市| 霸州市| 芜湖县| 永平县| 榆中县| 抚远县| 三明市| 青神县| 浪卡子县| 三都| 屏东县| 濮阳县| 通许县| 太白县| 潮州市| 南昌县| 敦化市| 中西区| 桂林市| 木兰县| 车险| 万山特区| 寿阳县| 嘉义市| 兴文县| 丽水市| 布尔津县| 卓资县| 双柏县| 孟州市| 新乐市|