引言
在现代微服务架构中,多数据源场景越来越常见。无论是为了读写分离、提高性能,还是适应不同类型的数据存储需求,合理的多数据源架构设计都是架构师必须掌握的技能。
在物联网(IoT)和大数据场景中,MySQL 适合结构化数据存储,而 TDengine 作为时序数据库,在处理海量时序数据时具有高效的写入和查询性能。因此,我们可以结合 MySQL 和 TDengine,在保持数据一致性的前提下,优化存储架构,提高系统的吞吐能力。
本文将从架构设计的角度,详细讲解如何基于 Spring Boot + MyBatis-Plus 进行 MySQL + TDengine 的多数据源整合,并提供完整的代码示例。
业务场景与架构设计
1. 典型业务需求
在 IoT 场景中,我们通常会遇到如下需求:
- 设备的基本信息需要存储在 关系型数据库(MySQL) 中,以支持复杂的查询和业务逻辑。
- 设备的时序数据(如传感器上报的温湿度、信号强度等)需要存储在 时序数据库(TDengine) 中,以支持高吞吐写入和高效查询。
- 需要提供一个统一的数据访问层,便于开发人员使用,而不需要关注底层数据库的差异。
2. 架构设计
在本方案中,我们采用 Spring Boot + MyBatis-Plus 进行数据访问,并使用 Druid 连接池 和 dynamic-datasource-spring-boot-starter 进行多数据源管理。
架构整体设计如下:
- 主数据库(MySQL 主从) :存储设备的静态信息,如设备编号、注册信息、配置参数等。
- 时序数据库(TDengine) :存储设备的时序数据,如信号强度、上报数据、状态变更等。
- 多数据源动态管理:通过 dynamic-datasource-spring-boot-starter 进行数据源管理,并使用 @DS 注解在 DAO 层实现自动切换。
环境与依赖配置
1. 技术栈
- • Spring Boot:用于快速构建 RESTful 服务。
- • MyBatis-Plus:简化数据访问层的开发,提高代码可维护性。
- • MySQL(主从模式) :保证高可用,同时提高查询性能。
- • TDengine 3.3.5.2:高效的时序数据库,适合 IoT 场景。
- • Druid 连接池:提供稳定高效的数据库连接管理。
2. Maven 依赖
xml
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.24</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.9</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>3.5.1</version>
</dependency>
MyBatis-Plus 多数据源整合
1. 配置 MySQL 与 TDengine 数据源
在 application.yml 中配置多个数据源,包括 MySQL 主从库和 TDengine:
yaml
spring:
datasource:
dynamic:
primary:master
datasource:
master:
url:jdbc:mysql://127.0.0.1:3306/tdengine-demo-master
username:root
password:root
slave:
url:jdbc:mysql://127.0.0.1:3306/tdengine-demo-slave
username:root
password:123456
tdengine:
type:com.alibaba.druid.pool.DruidDataSource
driver-class-name:com.taosdata.jdbc.rs.RestfulDriver
url:jdbc:TAOS-RS://127.0.0.1:6041/tdengine_demo
username:root
password: root
2. 自定义 BaseTaosMapper
typescript
public interface BaseTaosMapper<T> extends BaseMapper<T> {
default String getStableName(Class<?> clazz) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
return tableInfo != null ? tableInfo.getTableName() : null;
}
}
3. 设备数据表 devices
sql
CREATE STABLE IF NOT EXISTS tdengine_demo.devices (
ts TIMESTAMP,
imsi VARCHAR(20),
dev_id VARCHAR(50)
) TAGS (
msg_type INT
);
4. 业务 TdEngineDemoMapper
less
@Mapper
@DS("tdengine")
public interface TdEngineDemoMapper extends BaseTaosMapper<TdEngineDemoDO> {
@Insert("insert into devices (tbname, ts,imsi,dev_id,msg_type) values(#{tbname},#{ts},#{imsi},#{devId},#{msgType})")
int insertOne(TdEngineDemoDO demo);
}
5. TdEngineDemoServiceImpl业务实现
less
@Service
@Slf4j
public class TdEngineDemoServiceImplimplementsTdEngineDemoService {
@Resource
private TdEngineDemoMapper tdEngineDemoMapper;
@Override
public intinsert(TdEngineDemoMessage message) {
TdEngineDemoDO tdEngineDemoDO= BeanUtils.toBean(message, TdEngineDemoDO.class);
tdEngineDemoDO.setTbname(tdEngineDemoMapper.getStableName(TdEngineDemoDO.class) + "_" + tdEngineDemoDO.getDevId());
tdEngineDemoDO.setTs(newTimestamp(System.currentTimeMillis()));
return tdEngineDemoMapper.insertOne(tdEngineDemoDO);
}
}
总结
从架构师的角度来看,本方案通过 MySQL 和 TDengine 的结合,实现了高效的多数据源存储。MySQL 负责结构化数据,而 TDengine 负责高吞吐时序数据,在 IoT 和大数据分析领域具有广泛的应用场景。
未来优化方向:
- 读写分离,提高查询性能。
- 使用 Redis 进行缓存优化,降低数据库压力。
- 结合 Kafka 进行流式数据处理,提高实时数据分析能力。
希望这篇文章对你有所帮助,欢迎交流!