Skip to content

ZH OpenGemini

Alan Zhang edited this page Oct 7, 2026 · 4 revisions

Home · GitHub

English | 简体中文

当前源码版本为 2.1.2;本地发行验证通过,GitHub CI 与发布待完成,Maven Central 仍为 2.1.0。 使用这些修改须先从源码安装 2.1.2,见 2.1.2 发布说明。

2.1.2 的 OpenGemini 修改

统一 HTTP 路径及适配后的原生 ping()/version() 健康请求禁止自动重定向;统一写路径同时继承 64 MiB 应用批次合计预生成字节预算(tsdb.opengemini.max-batch-bytes,正数字节)。超预算批次在 I/O 前返回 ARGUMENT_ERROR/NOT_COMMITTED。结构化聚合输出名按保留大小写的规则保持唯一,query 与 count 均在 I/O 前拒绝冲突。既有整数精度预检、精确的 measurement 缺失归一、原生客户端所有权、不支持严格游标及 series 异步可见性保持。

2.1.2 不新增引擎、服务端版本、部署拓扑或替代 SDK。本轮四部署回归实证见 2.1.2 验证证据;不得将下方历史通过数视为重跑结果。首次源码构建的两个版本集群共出现 3 项错误,包含提交不明写入;原始证据保留在 history/pre-readiness/。首版门禁另有 1.4.1 日志字段假设缺陷,主动中断后清理通过,证据保留在 history/readiness-v1/。最终源码 2ba077a 仅修正版本专用测试观察,全新完整矩阵四种部署各通过 46 项(共 184 项),失败/错误/跳过均为零,源码/Git 身份一致,自有容器和网络全部清理。

InfluxDB 1.x 与 OpenGemini 的聚合响应还包含隐式物理 time 列,因此精确命名为 time 的聚合 alias 或分组 tag 在 I/O 前被拒绝;大小写不同的 Time 仍可使用。此协议专属保留名不扩大到 IoTDB 或 InfluxDB 3。

OpenGemini 接入

TsGate 2.1.0 新增独立的 OpenGemini adapter 与 starter,并在 2.1.0 BOM 中管理。Central 2.0.0 不包含这两个模块。直接从 Maven Central 引入时统一使用 2.1.0;使用本轮 2.1.2 修复前须先将 v2.1.2 源码安装到本地,再将全部 TsGate 依赖/BOM 统一为 2.1.2。依赖升级流程见升级指南。发布状态与兼容性验证分别记录。

目标版本为 openGemini 1.5.2 和 1.4.1,使用默认存储引擎的 InfluxQL 接口。适配器实现既有 TSDBAdapter,业务仍使用相同的 TGTemplate、TGQueryBuilder、TG* 注解及异常、结果类型。切换后端只涉及依赖、配置和原生查询方言;共享 SPI、业务 POJO 映射和查询模型不变。

直接 Java 接入使用 tsgate-opengemini,Spring Boot 接入使用 tsgate-opengemini-spring-boot-starter。适配器通过组合复用已有 InfluxDB 1.x 的受限 HTTP/InfluxQL 实现,具有独立的后端名称和配置前缀。兼容原生客户端类型为 org.influxdb.InfluxDB,不使用另一个 openGemini 异步 SDK。

依赖与启用

Spring Boot 使用 starter;自行管理 adapter 的 Java 应用可直接依赖 tsgate-opengemini。2.1.0 BOM 管理这两个模块:

<dependency>
    <groupId>io.github.alandevise</groupId>
    <artifactId>tsgate-opengemini-spring-boot-starter</artifactId>
    <version>2.1.0</version>
</dependency>
tsdb:
  query-log-enabled: true
  opengemini:
    enable: true
    fail-fast: true
    url: http://127.0.0.1:8086
    database: business_metrics
    username: ""
    password: ""
    retention-policy: ""
    max-batch-records: 10000
    max-batch-bytes: 67108864
    max-query-rows: 10000
    max-query-response-bytes: 16777216
    http-client:
      max-idle-connections: 8
      keep-alive-duration-ms: 300000
      connect-timeout-ms: 3000
      read-timeout-ms: 60000
      write-timeout-ms: 60000
      call-timeout-ms: 0
      retry-on-connection-failure: false

默认 URL 为 http://localhost:8086,默认数据库为 tsdb。使用前创建选定的数据库及具名保留策略;空保留策略使用服务器默认值。空凭据适用于未开启认证的服务,配置凭据后使用 HTTP Basic 认证。实际密码通过业务部署配置提供。

只有显式 tsdb.opengemini.enable=true 才启用 starter。其他后端保持关闭,除非也显式启用。即使 OpenGemini 实现依赖 InfluxDB1 模块,同时启用两个后端仍报错。多个 starter 依赖可以共存,一个 Spring 上下文最多启用一个后端。后端专用组件可使用 @Conditional(TSDBAdapterEnabledCondition.OpenGemini.class)。

业务仍注入 TGTemplate。以下使用应用已有的注解 Reading POJO:

tgTemplate.write(reading);
tgTemplate.batchWrite(readings);
BatchWriteResult written = tgTemplate.batchWriteDetailed(readings);
List<Reading> rows = tgTemplate.query(Reading.class)
    .whereTag("device", "sensor-a")
    .timeRange(startMillis, endMillis)
    .orderByTimeAsc()
    .limit(100)
    .list();
PageResult<Reading> page = tgTemplate.query(Reading.class)
    .orderByTimeAsc().page(1, 100);

直接接入使用 OpenGeminiProperties、可选的 OpenGeminiHttpClientProperties 和 OpenGeminiAdapter。手动构造后调用 init(),由拥有者在关闭时释放资源。构造时复制配置,后续修改原配置不会重定向适配器或原生客户端。初始化幂等,资源初始化失败可重试,关闭为终态。fail-fast=false 沿用现有原生客户端可选获取策略,并不探测服务器或数据库可用性。

单节点与三节点集群

两种部署使用相同的业务 API 与 YAML 结构。集群的 url 指向可达的 ts-sql 入口或部署提供的负载均衡入口。适配器不发现 meta/store 节点,也不会将失败写入自动重放到其他 SQL 入口;入口路由和故障切换由部署配置负责。本后端的 HTTP 连接失败重试默认关闭,避免传输层悄悄重试提交情况不明的写入。

本地集群夹具使用三个独立 Docker 容器,每个运行一个 ts-meta、一个 ts-store 和一个 ts-sql。就绪条件包含三个注册的 meta 节点及三个 store 节点,然后验证跨入口写入与读取。三个独立的单节点数据库不算集群。夹具记录实际版本、镜像与源码来源、成员及读回结果。

2.1.2 的测试数据库就绪条件

集群成员及元数据健康不等于新建数据库的数据 Raft 已就绪。自有三副本夹具在每次测试 CREATE DATABASE 后、首次写入前,只读观察初始 transfer,版本专用门禁最多等待 45 秒:

  • 1.5.2: 要求三个 store 中精确目标 database/partition 的完成记录,唯一覆盖 {0,1,2}。
  • 1.4.1: 绑定官方二进制准确提交 42678b4a23e0c7921548f6ceacb812659591d0bf,每个 store 须提供完整、未轮转、单次启动的日志。finish 日志没有 database/partition,因此不能把匿名 finish 直接归给某数据库;改为全日志中所有 init transfer 与显式 RPC start 的 repeated 合计,须等于匿名 finish 的 repeated 合计。精确目标数据库的显式 init 记录在三个节点唯一覆盖 {0,1,2},平衡账本须连续两次观察一致;证据缺失、含糊、格式损坏或版本不符即失败。

这是受控、独占、串行夹具的初始就绪观察。日志缓冲与随后后台 RPC 意味着它不能提供原子健康快照或持续可用保证;单节点无需该门禁。专用矩阵运行器自动传入夹具绝对 script/state 路径,仅外部 SQL URL 无法提供这些集群测试所要求的自有日志证据。

此准备不写预热数据、不改服务端设置、不强制转移 leader、不重放写入。生产适配器仍可连接外部三副本集群,无需 Docker/日志权限;下方新 series 索引可见性属于另一项读取条件。

写入可见性、测量名与原生健康检查

默认引擎异步刷新新 series 的索引。新测量或新的 tag 组合可能已经收到写入成功响应,但短时间内查询仍为空;已有可见 series 追加时间点可能立即可读。公共写入结果表示已确认的请求边界,不承诺强读己之写一致性。业务需要确认某个点已可查询时,可在读侧设置截止时间并轮询具体预期结果。适配器每次查询发送一次请求,不重放写入,也不延迟空查询。Docker 测试先通过独立 HTTP oracle 确认完整点可见,再验证被测查询。

测量名遵循服务端可打印名称规则:拒绝逗号、分号、斜杠、反斜杠,以及完整名称 . / ..。整个批次在发送前检查,非法名称返回 NOT_COMMITTED。合法名称保持原样,支持等号、普通空格及中文;field/tag 中的反斜杠继续按 line protocol 与 InfluxQL 规则转义。

仅将精确的服务端 measurement not found 查询错误,在公共结构化查询中规范为空成功结果,在 count 中规范为零。executeQuery 与借用的原生 query DTO 保留服务端错误,包括测量不存在:原生语句可能涉及多个测量或子查询,不能把失败整体转换为空结果而掩盖无效查询。其他服务端错误仍保留。

getNativeClient() 返回稳定的 InfluxDB 兼容代理。ping() 校验真实 HTTP 成功响应并读取 X-Geminidb-Version,version() 仅缓存已确认的版本。健康请求使用构造时的 URL、凭据和超时快照,并释放临时 HTTP 资源。其他方法、原生异常和 close 调用委托原客户端,链式设置保持代理身份。适配器关闭会等待本地校验、结果归一等完整操作;借用的原生调用仍由调用者协调关闭。

HTTP 写入路径的整数精度

实测 1.4.1/1.5.2 的 Influx 兼容 HTTP 写入路径会先把整数字段转换为 float64,再存储为整数。整数协议后缀也不能避免这一转换:9007199254740993i 读回为 9007199254740992。因此 OpenGemini 适配器在 I/O 前检查整个批次,只接受 signed-int64 范围内且可由 IEEE 754 float64 精确表示的整数字段。-2^53 至 2^53 之间的整数全部精确;2^53+2、Long.MIN_VALUE 等部分更大绝对值的整数也精确。2^53+1、Long.MAX_VALUE 和 Long.MIN_VALUE+1 在写前返回 ARGUMENT_ERROR、NOT_COMMITTED、零物理请求,不强制转换,也不编码成字符串。公共结构化 query/count 同样预检整数过滤字面量,包括 IN/BETWEEN 的每个值,避免服务端数值比较舍入后错误匹配。 极大整数型 BigDecimal 过滤值先与 signed-int64 边界比较再转换为整数,避免超大指数绕过检查或触发无界展开。Float/Double 及非整数查询字面量仍遵循普通浮点语义;已有 BigDecimal 字段校验继续生效。Epoch 毫秒时间戳走独立的时间路径。原生 SQL 与借用原生客户端写入绕过这些检查,保留服务端精度边界;该校验也不保证聚合累加无溢出或浮点运算精确。此限制针对本次 HTTP 适配,不代表 openGemini 的所有引擎或其他写入协议。

支持能力与边界

操作 默认引擎适配契约
POJO/记录单条与批量写入 沿用注解映射、写前校验与详细提交状态
时间范围、tag/field 条件与字段选择 沿用链式 API 与受限结果映射
时间升降序与 offset 分页 通过统一查询 API 支持
时间游标分页 支持;仅时间游标可能遗漏边界时间戳相同的记录
聚合、tag 分组与 UTC/固定偏移时间窗口 沿用聚合 API;时间窗口要求显式起止边界
count 分页前的结果行语义;稀疏字段不定义行身份;保留响应字节上限
只读原生查询 单条 SELECT、SHOW 或受支持的 EXPLAIN [ANALYZE] SELECT;管理操作使用借用的原生客户端
严格复合游标、FIELD 排序、仅 tag 投影 沿用兼容实现的明确 UNSUPPORTED_OPERATION
区域日历日窗口/DST 明确返回 UNSUPPORTED_OPERATION;可使用受支持的 UTC 或固定偏移窗口
COLUMNSTORE/Arrow/PromQL/集群管理 不在首版适配的已验证契约内,不声明覆盖 openGemini 的全部特性

普通和原生查询遵守配置的行数及解压后响应字节上限,分页探测可额外读一行。count 忽略分页与游标,同时保留时间边界校验和响应字节限制。不支持的操作明确报错,不返回成功的空结果。

写入保留已确认的请求提交边界。写前拒绝为 NOT_COMMITTED;可能已持久化数据的失败保持 UNKNOWN,保留此前批次的已确认记录数。不要自动重放提交不明的批次。原生调用绕过公共校验和限制,并须与适配器关闭协调;业务不能关闭借用的客户端。

2.1.1 契约与 CI 范围

OpenGemini 保留相同 API、兼容原生 client、HTTP 整数检查和异步可见性。共享模板的精确数值时间转换及有效续页检查同样适用;时间游标限制不变。严格复合游标和 FIELD 排序仍明确报 UNSUPPORTED_OPERATION。

可复用契约记录支持/不支持边界,不增加生产能力 SPI。自身模块、共享 core/构建输入或复用的 InfluxDB 1.x 实现变化时,自动 CI 均覆盖 OpenGemini。常规检查运行 1.4.1、1.5.2 单节点;发行/完整手动检查保留四种部署矩阵。run-matrix.py --mode single/--mode cluster 显式选择子集,省略选择器则运行完整矩阵。命令见运行器说明。

下方结果属于已记录的 2.1.0/源码快照。本次发行真实结果见 2.1.1 验证证据,不能由历史通过结果推断。

验证与复现

2026-10-03 的源码回归快照覆盖四种部署,每种均通过 44 项 adapter/starter 测试,失败、错误、跳过均为零,并保留源码摘要与清理记录。这是已记录的发行前源码快照;最终 2.1.0 发行验证另见兼容性与验证。较早证据保留原快照。

2026-10-03 在本地 ARM64 Docker、Temurin 17、Spring Boot 2.7.18 下完成以下矩阵。每种环境均运行真实适配层和自动发现 starter 的集成测试;兼容声明限定为这些默认引擎的精确版本与配置。

服务端 部署 副本数 Java 集成测试
1.4.1 单节点 1 44 通过;失败、错误、跳过均为 0
1.4.1 三节点集群 3 44 通过;失败、错误、跳过均为 0
1.5.2 单节点 1 44 通过;失败、错误、跳过均为 0
1.5.2 三节点集群 3 44 通过;失败、错误、跳过均为 0

集群由三个独立容器构成,每个容器运行 meta/store/SQL,实际组成三个 Raft Voter 的仲裁组并注册三个 store。数据库及保留策略元数据确认副本数为 3。测试使用 TGTemplate 和借用的兼容客户端从各 SQL 入口写入,再从每个入口读取完整数据集。所有测试容器和网络均已清理。

在仓库根目录复现,确保 Java 和 Maven 使用同一个 JDK:

python3 tsgate-opengemini/src/test/scripts/run-matrix.py \
  --output .local-test/opengemini-matrix

fixture 校验官方归档摘要并记录二进制/源码来源,即便镜像已缓存也可能下载归档。运行器将本次 Failsafe XML 报告和源码摘要保存在输出目录。1.4.1 官方二进制的 build commit 为 42678b4a23e0c7921548f6ceacb812659591d0bf,正式 tag 指向 5ff486d020cf52df11d8de73aa4664fd843a4e53;分别记录,避免误认为附件就是 tag commit 的构建。

已记录的源码回归快照在 17/2.7.18、21/3.5.14、25/4.1.0 三组 JDK/Boot 下各通过 888 项单元测试,另通过既有后端 114 项 Docker 测试、四种 OpenGemini 环境合计 176 项 Docker 测试、九个 JAR 模块的 27 份无签名 binary/source/Javadoc 归档检查,以及 34 项 Python 运行器测试。这些是历史源码回归结果,不代表最终 2.1.0 发布证据。本地拓扑矩阵未覆盖 TLS、启用认证的部署、入口故障切换或节点故障恢复。

1.4.1 使用官方全量二进制发行包。1.5.2 Release 没有二进制附件,夹具严格构建官方 tag commit 19ba0e2d9b428579004eb53d37d0c9b23034e2a9,不用 main 或候选版替代。

既有三数据库代表性 runner 保留 IoTDB/InfluxDB 回归。OpenGemini 集成测试需要显式提供入口或使用专用夹具;未提供入口时从该 runner 排除这些用例不构成兼容性证据。四种部署的独立矩阵见本地验证报告。

Clone this wiki locally