searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

在物联网场景跑TeleDB,一天写入十亿条数据

2026-08-18 17:14:14
0
0

物联网场景对数据库的考验和传统业务系统完全不在一个量级。传统业务系统一天写入几百万条数据已经算不少了,但物联网场景里,几万台设备每秒上报一次数据,一天下来轻松十亿条起步。这还不算最极端的——有些高频采样场景,单台设备每秒就能产生上百条数据。这种写入量对数据库的吞吐能力、存储效率和查询性能都是巨大的挑战。这篇文章记录了在天翼云环境下用TeleDB承载物联网数据写入的实践过程,包括架构设计、性能调优和踩过的坑。

场景描述与挑战

这次实践的物联网场景具有代表性:约五万台设备分布在不同区域,每台设备每隔1到5秒上报一组数据,包含设备ID、时间戳、温度、湿度、压力、位置信息等约20个字段。峰值写入速率约为每秒12万条,日均写入量约十亿条,年数据量约3.5TB(压缩前)。

这个场景对数据库提出了几个明确的要求。第一,高吞吐写入,每秒12万条的写入速率需要稳定支撑,不能出现写入阻塞导致数据积压。第二,海量存储,年数据量3.5TB不算特别大,但考虑到要保留多年历史数据,存储成本会持续增长。第三,时序查询,典型的查询模式是"查询某台设备最近一小时的数据"或"查询某个区域所有设备在某段时间内的平均值",这类查询需要高效的时间范围扫描和聚合能力。第四,数据生命周期管理,近期数据需要快速查询,历史数据可以降精度存储或归档。

架构设计

数据链路设计为:设备端通过MQTT协议上报数据到消息队列,消费服务从队列读取数据批量写入TeleDB,下游分析服务直接查询TeleDB。

为什么中间加一层消息队列?直接写数据库不行吗?理论上可以,但实际中不建议。原因有几个:一是设备端网络不稳定,直接写数据库容易因为网络抖动导致写入失败;二是数据库在维护窗口或故障时无法接受写入,消息队列可以起到缓冲作用;三是消息队列可以做数据清洗和格式校验,避免脏数据直接进库。

消费服务的设计要点是批量写入。逐条写入对数据库的压力太大,而且效率极低。消费服务每积累1000条数据或者等待100毫秒(取先到者)就触发一次批量写入。这样写入频率控制在每秒120次左右,每次1000条,对TeleDB的写入压力是可控的。

表结构设计上采用了分区表,按天分区。物联网数据有很强的时间局部性,查询基本都带时间范围条件,按天分区可以让查询只扫描相关的分区,大幅减少IO量。另外,分区也方便数据生命周期管理——过期的分区可以直接删除,比DELETE语句高效得多。

写入性能调优

初始配置下,TeleDB的写入速率大约在每秒8万条左右,离目标12万条还有差距。通过一系列调优最终达到了每秒15万条的写入能力,留出了足够的余量。

调优的第一步是批量大小。最初设置的批量大小是200条,写入频率约为每秒600次。把批量大小提高到1000条后,写入频率降到每秒120次,但每次写入的数据量更大。总体吞吐量提升了约40%,原因是减少了事务提交次数和网络往返开销。

第二步是连接池配置。消费服务实例有多个,每个实例维护自己的连接池。初始配置每个实例10个连接,发现连接数不够用,写入请求偶尔排队。调整到每个实例20个连接后,排队现象消失。但连接数也不是越多越好,测试发现超过30个连接后性能反而下降,因为连接间竞争增加。

第三步是存储引擎选择。物联网数据的查询模式以时间范围扫描和聚合为主,适合列存引擎。把存储格式从行存改为列存后,写入性能略有下降(约5%),但查询性能大幅提升,而且存储空间节省了约60%。这个取舍是值得的,因为写入能力仍然满足需求,而查询性能和存储成本的改善更为显著。

第四步是分区裁剪优化。确保所有查询都带分区键(时间戳)的条件,让优化器能做分区裁剪,只扫描需要的分区。对于不带时间条件的查询,强制在应用层加上时间范围限制,避免全表扫描。

查询性能

写入调优完成后,测试了典型查询的响应时间。查询"某台设备最近一小时的原始数据"(约3600条记录),响应时间在100毫秒以内。查询"某区域所有设备最近一天的平均温度"(涉及约100台设备、约800万条记录的聚合),响应时间在2到3秒。查询"某台设备最近一个月的每小时趋势"(约72万条记录的分组聚合),响应时间在1秒以内。

这些查询性能在可接受范围内。需要注意的是,当写入高峰期同时执行重查询时,查询响应时间会有所增加。通过资源组的隔离配置,把查询任务的资源限制在总资源的30%以内,可以保证写入不受影响,代价是查询变慢一些。在业务上这个取舍是合理的,因为写入的实时性比查询的分析性更重要。

数据生命周期管理

十亿条日写入意味着数据量会快速膨胀。如果所有数据都保留在TeleDB中,成本会越来越高,查询性能也会随着数据量增长而下降。因此设计了三层数据生命周期管理。

热数据保留7天,存储在TeleDB的列存表中,支持实时查询和告警。温数据保留3个月,在TeleDB中做降精度处理,每小时聚合一条记录,存储量减少到原来的1/3600。冷数据超过3个月的,导出到对象存储归档,需要时再拉回来查询。

这套生命周期管理方案把TeleDB中的数据量控制在了合理范围内,热数据约70GB,温数据约5GB,对TeleDB来说毫无压力。年存储成本相比全量保存降低了约90%,查询性能也保持在较好的水平。

0条评论
0 / 1000
思念如故
2048文章数
3粉丝数
思念如故
2048 文章 | 3 粉丝
原创

在物联网场景跑TeleDB,一天写入十亿条数据

2026-08-18 17:14:14
0
0

物联网场景对数据库的考验和传统业务系统完全不在一个量级。传统业务系统一天写入几百万条数据已经算不少了,但物联网场景里,几万台设备每秒上报一次数据,一天下来轻松十亿条起步。这还不算最极端的——有些高频采样场景,单台设备每秒就能产生上百条数据。这种写入量对数据库的吞吐能力、存储效率和查询性能都是巨大的挑战。这篇文章记录了在天翼云环境下用TeleDB承载物联网数据写入的实践过程,包括架构设计、性能调优和踩过的坑。

场景描述与挑战

这次实践的物联网场景具有代表性:约五万台设备分布在不同区域,每台设备每隔1到5秒上报一组数据,包含设备ID、时间戳、温度、湿度、压力、位置信息等约20个字段。峰值写入速率约为每秒12万条,日均写入量约十亿条,年数据量约3.5TB(压缩前)。

这个场景对数据库提出了几个明确的要求。第一,高吞吐写入,每秒12万条的写入速率需要稳定支撑,不能出现写入阻塞导致数据积压。第二,海量存储,年数据量3.5TB不算特别大,但考虑到要保留多年历史数据,存储成本会持续增长。第三,时序查询,典型的查询模式是"查询某台设备最近一小时的数据"或"查询某个区域所有设备在某段时间内的平均值",这类查询需要高效的时间范围扫描和聚合能力。第四,数据生命周期管理,近期数据需要快速查询,历史数据可以降精度存储或归档。

架构设计

数据链路设计为:设备端通过MQTT协议上报数据到消息队列,消费服务从队列读取数据批量写入TeleDB,下游分析服务直接查询TeleDB。

为什么中间加一层消息队列?直接写数据库不行吗?理论上可以,但实际中不建议。原因有几个:一是设备端网络不稳定,直接写数据库容易因为网络抖动导致写入失败;二是数据库在维护窗口或故障时无法接受写入,消息队列可以起到缓冲作用;三是消息队列可以做数据清洗和格式校验,避免脏数据直接进库。

消费服务的设计要点是批量写入。逐条写入对数据库的压力太大,而且效率极低。消费服务每积累1000条数据或者等待100毫秒(取先到者)就触发一次批量写入。这样写入频率控制在每秒120次左右,每次1000条,对TeleDB的写入压力是可控的。

表结构设计上采用了分区表,按天分区。物联网数据有很强的时间局部性,查询基本都带时间范围条件,按天分区可以让查询只扫描相关的分区,大幅减少IO量。另外,分区也方便数据生命周期管理——过期的分区可以直接删除,比DELETE语句高效得多。

写入性能调优

初始配置下,TeleDB的写入速率大约在每秒8万条左右,离目标12万条还有差距。通过一系列调优最终达到了每秒15万条的写入能力,留出了足够的余量。

调优的第一步是批量大小。最初设置的批量大小是200条,写入频率约为每秒600次。把批量大小提高到1000条后,写入频率降到每秒120次,但每次写入的数据量更大。总体吞吐量提升了约40%,原因是减少了事务提交次数和网络往返开销。

第二步是连接池配置。消费服务实例有多个,每个实例维护自己的连接池。初始配置每个实例10个连接,发现连接数不够用,写入请求偶尔排队。调整到每个实例20个连接后,排队现象消失。但连接数也不是越多越好,测试发现超过30个连接后性能反而下降,因为连接间竞争增加。

第三步是存储引擎选择。物联网数据的查询模式以时间范围扫描和聚合为主,适合列存引擎。把存储格式从行存改为列存后,写入性能略有下降(约5%),但查询性能大幅提升,而且存储空间节省了约60%。这个取舍是值得的,因为写入能力仍然满足需求,而查询性能和存储成本的改善更为显著。

第四步是分区裁剪优化。确保所有查询都带分区键(时间戳)的条件,让优化器能做分区裁剪,只扫描需要的分区。对于不带时间条件的查询,强制在应用层加上时间范围限制,避免全表扫描。

查询性能

写入调优完成后,测试了典型查询的响应时间。查询"某台设备最近一小时的原始数据"(约3600条记录),响应时间在100毫秒以内。查询"某区域所有设备最近一天的平均温度"(涉及约100台设备、约800万条记录的聚合),响应时间在2到3秒。查询"某台设备最近一个月的每小时趋势"(约72万条记录的分组聚合),响应时间在1秒以内。

这些查询性能在可接受范围内。需要注意的是,当写入高峰期同时执行重查询时,查询响应时间会有所增加。通过资源组的隔离配置,把查询任务的资源限制在总资源的30%以内,可以保证写入不受影响,代价是查询变慢一些。在业务上这个取舍是合理的,因为写入的实时性比查询的分析性更重要。

数据生命周期管理

十亿条日写入意味着数据量会快速膨胀。如果所有数据都保留在TeleDB中,成本会越来越高,查询性能也会随着数据量增长而下降。因此设计了三层数据生命周期管理。

热数据保留7天,存储在TeleDB的列存表中,支持实时查询和告警。温数据保留3个月,在TeleDB中做降精度处理,每小时聚合一条记录,存储量减少到原来的1/3600。冷数据超过3个月的,导出到对象存储归档,需要时再拉回来查询。

这套生命周期管理方案把TeleDB中的数据量控制在了合理范围内,热数据约70GB,温数据约5GB,对TeleDB来说毫无压力。年存储成本相比全量保存降低了约90%,查询性能也保持在较好的水平。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0