4. 数据库选型与配置优化(PostgreSQL):连接池配置、索引优化、查询计划分析、自动清理与维护策略

在 ThingsBoard 高并发场景下,PostgreSQL 作为核心元数据与关系型数据存储,其配置直接决定平台吞吐量与响应延迟。本章聚焦连接池、索引、查询计划及自动清理四大维度,提供可落地的优化方案。

4.1 连接池配置:从默认到高并发

ThingsBoard 默认使用 HikariCP 连接池,但默认参数(如 maximumPoolSize=10)在千级设备接入时极易成为瓶颈。连接池配置需平衡线程并发数与数据库资源。

参数默认值高并发推荐值说明
spring.datasource.hikari.maximumPoolSize1050~100根据 CPU 核心数 ×2~4 调整,避免过多连接导致上下文切换
spring.datasource.hikari.minimumIdle1010~20保持常驻连接,减少频繁创建开销
spring.datasource.hikari.idleTimeout600000300000空闲连接超时,配合 minimumIdle 释放资源
spring.datasource.hikari.maxLifetime18000001200000连接最大存活时间,避免长时间连接被网络设备断开
spring.datasource.hikari.connectionTimeout3000010000等待连接超时,快速失败避免请求堆积
实践建议:在 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。
查询计划分析流程 捕获慢查询 EXPLAIN ANALYZE Seq Scan 出现? → 检查索引缺失 Nested Loop 过多? → 优化关联索引 rows 偏差大? → 更新统计信息 应用索引 / 调整参数 验证延迟与吞吐

4.4 自动清理与维护策略

PostgreSQL 的 MVCC 机制导致死元组累积,若不及时清理,会引发表膨胀、索引效率下降。ThingsBoard 高写入场景下,需定制 autovacuum 参数。

参数默认值高并发推荐值说明
autovacuum_vacuum_scale_factor0.20.01触发清理的脏数据比例,降低以更频繁清理
autovacuum_vacuum_threshold501000触发清理的最小死元组数,避免小表频繁触发
autovacuum_analyze_scale_factor0.10.005触发统计信息更新的比例
autovacuum_naptime6030清理守护进程休眠时间(秒)
autovacuum_max_workers34~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,确保清理及时。
自动清理与维护时间线 每日 监控 n_dead_tup 检查 autovacuum 日志 每周 VACUUM ANALYZE 更新统计信息 每月 REINDEX 大表 清理索引碎片 核心原则 高频写入表(ts_kv)降低 scale_factor,低频表提高 threshold 避免在业务高峰期执行 VACUUM FULL 或 REINDEX

4.5 综合配置清单

以下为 ThingsBoard 高并发场景下 PostgreSQL 配置的快速参考清单:

  1. 连接池: maximumPoolSize=80,connectionTimeout=10000,maxLifetime=1200000。
  2. 索引: 为 ts_kv 创建复合索引 (entity_id, key, ts DESC),为 alarm 创建条件索引。
  3. 查询计划: 每周使用 EXPLAIN ANALYZE 检查 TOP 5 慢查询,针对性优化。
  4. 自动清理: 全局 scale_factor=0.01,ts_kv 表级 scale_factor=0.005。
  5. 维护窗口: 每周 VACUUM ANALYZE,每月 REINDEX,避开业务高峰。
验证方法:优化后使用 pg_stat_activity 观察活跃连接数,使用 pg_stat_user_tables.n_dead_tup 确认死元组比例稳定在 5% 以下。