Files
iot-dc3/docs/tsdb-stores.md
pnoker eae86b58fc refactor(storage)!: unify platform persistence on reactive postgresql
- migrate auth, manager, data, and agentic persistence to R2DBC
- hard cut pagination, facade, gateway, web, and CLI contracts
- remove legacy database and TSDB adapters and document validation gates

BREAKING CHANGE: platform persistence now requires PostgreSQL 18 with TimescaleDB and the new reactive API contracts.
2026-09-01 22:03:16 +08:00

3.8 KiB
Raw Permalink Blame History

时序存储现状

结论

DC3 当前只保留一条时序存储实现:dc3-common-data 的原生 R2dbcTsdbStore。它直接实现 dc3-tsdb-core 的响应式 TsdbStore Port,使用 DatabaseClient 和 TransactionalOperator 访问 PostgreSQL/TimescaleDB。平台不再提供 JDBC、同步 HTTP、同步 Session 或“Mono.fromCallable 包装”的外部 TSDB 适配器,也不再提供运行时 dc3.tsdb.type 选择。

模块边界

模块 职责
dc3-tsdb-core 定义 TsdbStore、TsdbModel、游标分页和能力声明;不依赖具体数据库
dc3-common-data 实现 R2dbcTsdbStore,承载写入、历史读取、聚合和租户隔离
dc3-center-data 配置 R2DBC ConnectionFactory,通过 facade 暴露数据能力

dc3-tsdb/dc3-tsdb-timescale、dc3-tsdb-tdengine、dc3-tsdb-influxdb、dc3-tsdb-iotdb 和 dc3-tsdb-tck 已从源码构建中移除;target/ 下的历史 jar 不属于可发布模块。

数据模型

历史表是 dc3_history.dc3_point_value,逻辑主键为 (tenant_id, device_id, point_id, create_time)。 写入列同时保存原始值、计算值、数值投影、质量码、消息幂等字段、驱动节点、序号、fencing token 和 接收时间。所有时间使用 UTC Instant,精度为微秒;数值不可解析时 num_value 为 NULL,不把字符串 强行转换为零。

dc3_point_value_latest 等最新值投影属于关系数据面,由 Data 域事务维护;TSDB Port 只负责历史样本, 避免跨存储双写和读写竞态。

Port 操作

TsdbStore 的写入和读取全部返回 Mono/Flux:

  • append:非空、有界批量写入;同一批次原子失败或成功,数据库冲突按最后写入胜;
  • last:按 SeriesFilter 返回每个序列最新样本;
  • history:半开时间窗内按 deviceTime/messageId/series 的降序游标分页;
  • aggregate、bucketedAggregate:窗口聚合和升序分桶聚合;百分位参数严格校验;
  • count、seriesCounts、seriesLastSeen、latencyHistogram、correlation:分析查询,均带租户范围。

所有查询都要求正数 tenantId、正数序列 ID 和有限 deadline。limit/pageSize 超出上限或非法时直接 返回 IllegalArgumentException,不静默截断;超时由 Reactor timeout 终止并释放连接。

分页与排序

历史样本使用不透明 cursor,不暴露页码;cursor 包含设备时间、序列和 messageId,服务端验证租户和窗口。 管理类关系查询统一使用 offset/limit/sort,返回 items、total、hasNext。排序字段由白名单 映射到 SQL 列,禁止把客户端字符串直接拼进 SQL。COUNT 与 items 在同一事务快照下计算,避免总数与 列表跨快照漂移。

租户与一致性不变量

  1. 每条 SQL 都显式带 tenant_id;跨租户序列、join 和 correlation 请求直接拒绝。
  2. 软删除数据必须带 deleted = 0;更新和删除同时检查租户及版本,乐观锁冲突不重试覆盖。
  3. 批量写入有 maxAppendBatch 上限;不存在无界 concatMap 或无限缓存。
  4. 连接、事务和取消信号由 R2DBC/Reactor 管理,不允许阻塞桥接。
  5. 数据库方言由已配置的 R2DBC dialect 提供,启动时必须且只能存在一个有效连接配置。

验证

mvn -s .mvn/settings.xml -q -DskipTests compile
mvn -s .mvn/settings.xml -q test -pl dc3-tsdb/dc3-tsdb-core,dc3-common/dc3-common-data -am

需要真实 PostgreSQL 时运行 make up-db 后执行 Data 域 R2DBC integration tests。新增存储实现必须先 提供真正的异步客户端、租户隔离测试、取消/超时测试和分页一致性测试;仅用同步客户端包裹 Reactor 不满足本项目架构要求。