4. 数据库选型与配置优化(PostgreSQL):连接池配置、索引优化、查询计划分析、自动清理与维护策略
在 ThingsBoard 高并发场景下,PostgreSQL 作为核心元数据与关系型数据存储,其配置直接决定平台吞吐量与响应延迟。本章聚焦连接池、索引、查询计划及自动清理四大维度,提供可落地的优化方案。
4.1 连接池配置:从默认到高并发
ThingsBoard 默认使用 HikariCP 连接池,但默认参数(如 maximumPoolSize=10)在千级设备接入时极易成为瓶颈。连接池配置需平衡线程并发数与数据库资源。
| 参数 | 默认值 | 高并发推荐值 | 说明 |
|---|---|---|---|
spring.datasource.hikari.maximumPoolSize | 10 | 50~100 | 根据 CPU 核心数 ×2~4 调整,避免过多连接导致上下文切换 |
spring.datasource.hikari.minimumIdle | 10 | 10~20 | 保持常驻连接,减少频繁创建开销 |
spring.datasource.hikari.idleTimeout | 600000 | 300000 | 空闲连接超时,配合 minimumIdle 释放资源 |
spring.datasource.hikari.maxLifetime | 1800000 | 1200000 | 连接最大存活时间,避免长时间连接被网络设备断开 |
spring.datasource.hikari.connectionTimeout | 30000 | 10000 | 等待连接超时,快速失败避免请求堆积 |
实践建议:在 ThingsBoard 的
thingsboard.yml 中调整连接池参数后,务必监控数据库端最大连接数(max_connections),确保连接池上限不超过数据库配置的 80%。
4.2 索引优化:覆盖高频查询路径
ThingsBoard 核心表(如 ts_kv、device、alarm)在高并发写入与查询时,索引设计直接影响性能。以下为关键索引策略:
- 时序数据表(ts_kv): 复合索引
(entity_id, key, ts DESC)覆盖最新值查询;避免单列索引导致回表。 - 设备表(device): 索引
(tenant_id, type)加速租户级设备列表查询。 - 告警表(alarm): 索引
(tenant_id, status, created_ts DESC)支持活跃告警排序。 - 关系表(relation): 索引
(from_id, relation_type_group)与(to_id, relation_type_group)覆盖双向查询。
-- 示例:为 ts_kv 表创建覆盖最新值查询的复合索引
CREATE INDEX idx_ts_kv_entity_key_ts
ON ts_kv (entity_id, key, ts DESC);
-- 示例:为告警表创建活跃告警查询索引
CREATE INDEX idx_alarm_tenant_status_ts
ON alarm (tenant_id, status, created_ts DESC)
WHERE status = 'ACTIVE';
避坑提示:避免在
ts_kv 表上建立过多索引,写入时索引维护开销会显著增加。建议每张表索引数量控制在 5 个以内,并定期使用 pg_stat_user_indexes 检查未使用索引。
4.3 查询计划分析:定位慢查询根因
使用 EXPLAIN ANALYZE 分析 ThingsBoard 高频查询的执行计划,重点关注顺序扫描(Seq Scan)与嵌套循环(Nested Loop)。
-- 分析设备最新遥测查询
EXPLAIN ANALYZE
SELECT key, long_v, double_v, str_v, ts
FROM ts_kv
WHERE entity_id = 'abc-123'
AND key = 'temperature'
ORDER BY ts DESC
LIMIT 1;
优化目标:
- 避免 Seq Scan: 若出现顺序扫描,检查是否缺少索引或查询条件未使用索引列。
- 减少 Nested Loop: 多表关联时,确保关联列有索引,或调整
enable_nestloop参数。 - 关注 Bitmap Heap Scan: 当返回行数较多时,Bitmap 扫描通常优于 Index Scan。
关键指标:执行计划中
rows= 与 actual rows= 偏差超过 10 倍时,需更新统计信息(ANALYZE)或调整 default_statistics_target。
4.4 自动清理与维护策略
PostgreSQL 的 MVCC 机制导致死元组累积,若不及时清理,会引发表膨胀、索引效率下降。ThingsBoard 高写入场景下,需定制 autovacuum 参数。
| 参数 | 默认值 | 高并发推荐值 | 说明 |
|---|---|---|---|
autovacuum_vacuum_scale_factor | 0.2 | 0.01 | 触发清理的脏数据比例,降低以更频繁清理 |
autovacuum_vacuum_threshold | 50 | 1000 | 触发清理的最小死元组数,避免小表频繁触发 |
autovacuum_analyze_scale_factor | 0.1 | 0.005 | 触发统计信息更新的比例 |
autovacuum_naptime | 60 | 30 | 清理守护进程休眠时间(秒) |
autovacuum_max_workers | 3 | 4~6 | 并行清理工作进程数 |
维护策略:针对
ts_kv 等高频写入表,可单独设置表级 autovacuum 参数:ALTER TABLE ts_kv SET (autovacuum_vacuum_scale_factor = 0.005, autovacuum_vacuum_threshold = 500);
定期维护任务建议:
- 每周: 对核心表执行
VACUUM ANALYZE,更新统计信息并回收空间。 - 每月: 在低峰期对
ts_kv等大表执行REINDEX,重建索引消除碎片。 - 持续监控: 使用
pg_stat_user_tables观察n_dead_tup与last_autovacuum,确保清理及时。
4.5 综合配置清单
以下为 ThingsBoard 高并发场景下 PostgreSQL 配置的快速参考清单:
- 连接池: maximumPoolSize=80,connectionTimeout=10000,maxLifetime=1200000。
- 索引: 为 ts_kv 创建复合索引 (entity_id, key, ts DESC),为 alarm 创建条件索引。
- 查询计划: 每周使用 EXPLAIN ANALYZE 检查 TOP 5 慢查询,针对性优化。
- 自动清理: 全局 scale_factor=0.01,ts_kv 表级 scale_factor=0.005。
- 维护窗口: 每周 VACUUM ANALYZE,每月 REINDEX,避开业务高峰。
验证方法:优化后使用
pg_stat_activity 观察活跃连接数,使用 pg_stat_user_tables.n_dead_tup 确认死元组比例稳定在 5% 以下。