摘要:本文记录了一个真实的时序数据库迁移项目,从 InfluxDB 迁移到 TDengine 的全过程,包括性能对比、迁移方案、遇到的问题和解决方案。

一、迁移背景

某物联网平台公司,原有系统基于 InfluxDB 构建,随着业务增长,面临以下挑战:

  • 写入性能瓶颈:峰值 5 万条/秒,InfluxDB 经常出现写入延迟
  • 查询性能下降:历史数据查询经常超时,用户体验差
  • 存储成本高:数据量 10TB+,存储成本每月数万元
  • 集群限制:InfluxDB 集群版不开源,扩展受限
  • 国产化需求:客户要求使用国产数据库

经过技术调研,最终选择 TDengine 作为替代方案。

二、性能对比测试

2.1 测试环境

组件

配置

CPU

Intel Xeon E5-2680 v4 × 2

内存

128GB DDR4

存储

SSD 1TB × 4

网络

万兆以太网

操作系统

CentOS 7.9

2.2 写入性能对比

测试场景:1000 个设备,每个设备 10 个指标,写入 24 小时数据

指标

InfluxDB

TDengine

提升

峰值写入

8 万条/秒

120 万条/秒

15x

平均写入

5 万条/秒

80 万条/秒

16x

CPU 占用

80%

30%

降低 62%

内存占用

64GB

16GB

降低 75%

2.3 查询性能对比

测试场景:查询某设备最近 7 天的数据,聚合到 1 小时粒度

指标

InfluxDB

TDengine

提升

首次查询

15 秒

200ms

75x

缓存后查询

2 秒

50ms

40x

并发查询

10 QPS

500 QPS

50x

2.4 存储空间对比

数据量

InfluxDB

TDengine

压缩比

原始数据

100GB

100GB

1:1

存储空间

35GB

8GB

4.4:1

索引空间

15GB

2GB

7.5:1

总空间

50GB

10GB

5:1

三、迁移方案设计

3.1 迁移策略

采用"双写 + 切换"的迁移策略:

阶段 1:双写期(2 周)  应用 → InfluxDB(主)       → TDengine(备)  阶段 2:验证期(1 周)  对比两个系统的数据一致性 验证 TDengine 的查询结果  阶段 3:切换期(1 天)  应用 → TDengine(主)       → InfluxDB(备,短期保留)  阶段 4:下线期(1 月后)  下线 InfluxDB

3.2 数据模型转换

InfluxDB 数据模型

-- InfluxDB Line Protocoldevice_data,device_id=DEV001,device_type=CNC temperature=25.5,pressure=1.2 1609459200000000000

TDengine 数据模型

-- 创建超级表CREATE STABLE IF NOT EXISTS device_data (    ts TIMESTAMP,    temperature FLOAT,   pressure FLOAT) TAGS (    device_id BINARY(32),    device_type BINARY(16));-- 插入数据INSERT INTO device_001 USING device_data TAGS ('DEV001', 'CNC') VALUES ('2021-01-01 00:00:00', 25.5, 1.2);

3.3 迁移脚本

import influxdb_clientimport taosfrom datetime import datetimeclass DataMigrator:    def __init__(self):        # InfluxDB 连接        self.influx_client = influxdb_client.InfluxDBClient(           url="http://localhost:8086",            token="your-token",            org="your-org"       )                # TDengine 连接        self.td_conn = taos.connect(           host="localhost",            user="root",            password="taosdata",           database="iot_platform"        )                self.query_api = self.influx_client.query_api()        self.td_cursor = self.td_conn.cursor()        def migrate_measurement(self, measurement, start_time, end_time):        """迁移单个 measurement"""       # 查询 InfluxDB        query = f'''        from(bucket: "iot_bucket")            |> range(start: {start_time}, stop: {end_time})            |> filter(fn: (r) => r._measurement == "{measurement}")        '''                result = self.query_api.query(query)                # 批量写入 TDengine        batch_size = 10000        batch = []                for table in result:           for record in table.records:                # 转换数据格式                ts = record.get_time()               field = record.get_field()                value = record.get_value()               tags = record.values                                # 构建插入语句                sql = f"""                   INSERT INTO {measurement}                    USING device_data TAGS ('{tags['device_id']}', '{tags['device_type']}')                    VALUES ('{ts}', {value})               """                batch.append(sql)                                if len(batch) >= batch_size:                    self.execute_batch(batch)                    batch = []               if batch:            self.execute_batch(batch)        def execute_batch(self, batch):       """批量执行 SQL"""        for sql in batch:            try:               self.td_cursor.execute(sql)            except Exception as e:               print(f"Error: {e}, SQL: {sql}")if __name__ == '__main__':    migrator = DataMigrator()    migrator.migrate_measurement(        "device_data",        "2024-01-01T00:00:00Z",        "2024-01-02T00:00:00Z"    )

四、迁移过程中的问题与解决

4.1 时间精度问题

问题:InfluxDB 默认使用纳秒精度,TDengine 默认使用毫秒精度。

解决:统一使用毫秒精度,在迁移脚本中转换:

def convert_timestamp(ns_timestamp):    """纳秒转毫秒"""    return ns_timestamp // 1000000

4.2 TAG 值长度限制

问题:InfluxDB 的 TAG 值长度无限制,TDengine 的 BINARY 类型有长度限制。

解决:评估 TAG 值长度,适当调整 BINARY 长度:

-- 原设计TAGS (device_id BINARY(32))-- 调整为TAGS (device_id BINARY(64))

4.3 连续查询迁移

问题:InfluxDB 的连续查询(CQ)需要迁移到 TDengine 的流式计算。

解决:使用 TDengine 的数据订阅替代:

-- InfluxDB CQCREATE CONTINUOUS QUERY cq_1h ON iot_bucketBEGIN    SELECT mean(temperature) INTO avg_temp FROM device_data GROUP BY time(1h)END;-- TDengine 替代方案CREATE TOPIC hourly_avg AS SELECT _irowts as hour, AVG(temperature) as avg_temp FROM device_data INTERVAL(1h);

五、迁移效果

指标

InfluxDB

TDengine

提升

写入性能

5 万条/秒

80 万条/秒

16x

查询延迟

15 秒

200ms

75x

存储成本

5 万元/月

1 万元/月

降低 80%

系统可用性

99.5%

99.9%

+0.4%

运维复杂度

-

六、经验总结

  1. 充分测试是关键:迁移前在测试环境验证 2 周,确保数据准确性。
  2. 双写期不能省:双写期可以及时发现和解决问题,降低切换风险。
  3. SQL 兼容性降低迁移成本:TDengine 支持标准 SQL,改造量很小。
  4. 监控不能少:迁移过程中要监控数据完整性和一致性。
  5. 国产替代是趋势:在信创背景下,选择国产数据库是明智之选。

关键词:时序数据库、TDengine、InfluxDB、数据迁移、性能对比、国产替代

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐