
聊时序数据库之前先说个真事。去年有个轨交项目调度中心的监控大屏突然卡了晚上12点。值班工程师查日志写入队列堆了两百多万条没落盘的数据查询从200毫秒窜到40秒。但你说硬件有问题吧CPU才到30%内存还剩一大截。最后定位到是某个时间分片数据量膨胀写入路由表挂了所有新数据挤在一个物理分区里抢锁。我这些年经手时序库选型的活儿不算少晚上12点被电话叫醒的故事每个项目都能讲出不同版本。轨交也好工厂也好电力也好时序数据库真正的麻烦从来不是能不能写进去——刚上线那会儿啥都好好的。麻烦在跑了几个月、数据量上来之后各种你当初根本没想到的配置坑全蹦出来了。金仓时序数据库搞了个叫超表Hypertable的东西思路跟传统方案不太一样。这篇文章就写写我理解的这套架构它怎么把分片管理这个运维老大难问题从根上拆掉。传统分片到底怎么把人逼疯的我自己踩过最深的坑是分片预估。大多数时序库的分片策略说白了就是手动配静态规则。部署阶段你得提前定好分片键、分几个片、每个片多大触发分裂。拿设备ID做Hash分片来说你得猜最终会接多少台设备——猜少了后面数据倾斜有的片撑爆有的片空着猜多了每片数据量太小查询时跨片合并的开销比单片扫描还高。时间维度的坑更深。时序数据天然有冷热之分最近一小时的数据被反复查三个月前的数据也就月报才翻一次。传统分片不做冷热分离的话所有数据挤一层存储热点分片的I/O被读写两头抢。做分离吧归档策略、迁移任务、索引重建脚本全得手写运维每周加班写Shell。有个能源监控的项目我印象特别深。跑了八个月之后运维团队每个月手动做一次分片重平衡。怎么操作呢数据导出来删旧分片按新规则重新灌进去。四到六小时期间系统降级跑。运维那哥们跟我原话是这么说的“我面试进来是做DBA的不是来做ETL搬运工的。”还有个更阴的坑——元数据膨胀。每个分片自己有索引、统计信息、路由表。分片从几十涨到几百之后查询规划器光遍历元数据就得几十毫秒。亚秒级监控场景下这个开销谁受得了。超表干的第一件事把物理分片藏起来超表这名字听着唬人其实道理不复杂。你应用层看到的就是一张普普通通的逻辑表INSERT、SELECT、GROUP BY该咋写咋写。底下数据怎么切、存哪台机器上你不用知道也不用管。我经常拿公司前台打比方。传统分片就像你去找人得先翻一张员工-楼层-工位映射表查到在几楼几座自己跑过去。映射表过期了或者写错了你就跑空。超表呢你只管报名字前台自己帮你定位映射表怎么维护是前台的事你感觉不到。具体到技术实现上有几层设计我挑重点说。写入路由是自动的。每条数据进来系统根据时间戳加上可选的空间标签设备ID、区域编号之类算出它该落在哪个Chunk里。你写INSERT的时候不指定目标分片甚至不需要知道有分片这东西存在-- 就这么写不用管数据落到哪个物理分片INSERTINTOdevice_metrics(ts,device_id,temperature,pressure,vibration)VALUES(2026-08-15 14:30:00,dev_00125,78.5,1.2,0.03);查询的时候有分区裁剪。你带时间范围条件查系统自己判断哪些Chunk跟这次查有关系无关的直接跳过。查最近一小时的数据只扫当前小时的Chunk三个月前的分片碰都不碰。这个过程对你完全透明SQL跟查普通表没区别-- 查最近1小时平均温度系统自动跳过无关分区SELECTdevice_id,AVG(temperature)ASavg_tempFROMdevice_metricsWHEREtsNOW()-INTERVAL1 hourGROUPBYdevice_idORDERBYavg_tempDESC;分片的生命周期也是系统管。创建新分片、归档旧分片、删过期分片全按策略自动跑。你配个保留180天到点自己删不用写定时脚本也不用晚上爬起来敲DROP PARTITION。有个事可以佐证这套设计到底省了多少事。我经手过一个五人团队从某传统时序库迁到金仓超表的项目迁完之后跟分片相关的代码和配置文件删了七成以上。之前那些手动路由逻辑、分片选择算法、跨片查询结果合并的代码——全砍了不需要了。二维分区不是按时间切一刀就完事的金仓的底层分片策略有个自研的二维分区算法时间轴和空间轴两个维度同时做路由。这个设计我觉得是他们整个超表架构里最有技术含量的部分。时间轴是主分区。数据按时间窗口每小时、每天看你配置自动切成独立物理块。好处直接两条新数据追加到最新分片不跟历史数据抢锁查询走分区裁剪只扫相关时间段的数据块I/O量掉一大截。空间轴是次分区。拿设备ID或者区域编号做哈希把高并发写入压力均匀打散到各节点。这个设计解决的是一个特别实际的问题——你3000台设备同时上报如果只按时间分区某一秒所有设备的数据全涌向同一个时间分片写入吞吐被单分片的处理能力卡死了。加上空间哈希分区之后同一时刻不同设备的数据被路由到不同物理节点并行写整体吞吐跟节点数挂勾线性扩展。-- 时间维度按天分区空间维度按device_id哈希CREATETABLEdevice_metrics(tsTIMESTAMPNOTNULL,device_idVARCHAR(50)NOTNULL,temperatureDOUBLEPRECISION,pressureDOUBLEPRECISION,vibrationDOUBLEPRECISION,regionVARCHAR(20),PRIMARYKEY(device_id,ts))PARTITIONBYRANGE(ts);-- 时间分片内部再做哈希子分区CREATETABLEdevice_metrics_20260815PARTITIONOFdevice_metricsFORVALUESFROM(2026-08-15 00:00:00)TO(2026-08-16 00:00:00)PARTITIONBYHASH(device_id);CREATETABLEdevice_metrics_20260815_h0PARTITIONOFdevice_metrics_20260815FORVALUESWITH(MODULUS4,REMAINDER0);CREATETABLEdevice_metrics_20260815_h1PARTITIONOFdevice_metrics_20260815FORVALUESWITH(MODULUS4,REMAINDER1);CREATETABLEdevice_metrics_20260815_h2PARTITIONOFdevice_metrics_20260815FORVALUESWITH(MODULUS4,REMAINDER2);CREATETABLEdevice_metrics_20260815_h3PARTITIONOFdevice_metrics_20260815FORVALUESWITH(MODULUS4,REMAINDER3);这套二维分区在高基数场景下优势特别明显。所谓高基数就是设备多、标签多。一个城市级物联网项目动辄上万台设备每台几十个指标一秒一报。光做时间分区的话一个时间窗口里攒的数据量太大单分片扛不住写入峰值。加了空间哈希之后同一时间段的数据被均匀打散到N个物理分片上每个分片只扛总写入量的1/N。北京轨交TCC项目是个很硬的数据 $性能提升超十倍金仓时序数据库首入北京轨交TCC。接入金仓时序数据库后写入性能相比旧系统提升超过10倍每秒处理数十万条数据点的洪峰写入存储空间占用降了70%到80%。这背后时间维度控制了每个数据块的规模空间维度把写入压力分摊到了多个节点上缺了哪个维度都撑不到这个数。标准SQL干时序的活不用学新语法这件事很重要有些专用时序库为了追性能把SQL给砍了搞了套自己的查询语言。你说这有多大影响在技术评审会上可能听着无所谓真到项目落地的时候开发团队要重新培训、重写数据访问层、调试工具全换一套DBA也得重新学运维体系。这种隐性成本选型阶段九成的人估不出来。金仓的时序能力是长在KingbaseES内核里的不是外挂服务。标准SQL写时序数据写入、查询、聚合、关联全都跟写普通表一样。-- 时序表和关系表直接JOIN查温度异常设备并关联档案信息SELECTd.device_name,d.location,d.maintainer,m.ts,m.temperature,m.pressureFROMdevice_metrics mJOINdevice_archive dONm.device_idd.device_idWHEREm.ts2026-08-15 00:00:00ANDm.ts2026-08-15 01:00:00ANDm.temperatured.alert_thresholdORDERBYm.temperatureDESC;这条SQL同时碰了时序表和关系表。放纯时序库里你干不了这个得先查时序库拿异常设备列表再查关系库拿设备档案中间加应用代码拼接。金仓这边一条SQL搞定。工业场景里降采样查询太常用了每秒一条的原始数据聚合成每分钟的平均值-- 按分钟降采样SELECTtime_bucket(1 minute,ts)ASminute_bucket,device_id,AVG(temperature)ASavg_temp,MAX(pressure)ASmax_pressure,STDDEV(vibration)ASvib_stdFROMdevice_metricsWHEREts2026-08-15 00:00:00ANDts2026-08-16 00:00:00GROUPBYminute_bucket,device_idORDERBYminute_bucket,device_id;time_bucket是金仓内置的时间桶聚合函数。底下执行的时候排序和聚合算子被推到各数据节点本地算先局部聚合再汇总尽量少搬数据 。原来分钟级的跨节点分析能压到亚秒。排查查询性能的时候EXPLAIN直接看分区裁剪有没有生效EXPLAIN(ANALYZE,BUFFERS)SELECTdevice_id,AVG(temperature)FROMdevice_metricsWHEREts2026-08-15 00:00:00ANDts2026-08-15 01:00:00GROUPBYdevice_id;执行计划里只出现20260815相关的子分区说明裁剪生效了。要是看到所有分片都在扫查两件事查询条件有没有带分区键时间列统计信息是不是过期了跑一下ANALYZE。几个真实项目里的数据架构到底行不行不看你PPT做得多漂亮看落地。北京轨交TCC这个项目我追了大半年。应急指挥调度系统每天接入的数据量很吓人列车实时位置、速度、牵引能耗、信号设备状态、车站客流密度、环境温湿度每秒数十万条时序数据点往里灌。旧系统用传统关系型数据库硬扛了几年到后来每早晚高峰写入队列就堆监控大屏延迟从亚秒劣化到十几秒运营分析报表跑一次等好几个小时。换了金仓之后TCC技术团队上了一主多从的读写分离集群。主节点专门写从节点扛监控大屏和后台分析查询。写入和查询在物理上隔离开了——写的不被查的拖累查的不被写的干扰。写入性能比旧系统高超10倍存储省了70%到80%。过去花几分钟才能跑出来的某线路过去一个月早高峰平均旅行速度分析现在秒级出结果。数据生命周期管理也做了分层热数据放高速存储服务实时告警温数据放普通磁盘服务历史分析冷数据自动归档。目前系统稳定存着TB级轨交全网时序历史数据百TB级可扩展存储体系已经搭好了。泰兴交通走了另一条路做的是时空一体化。金仓用时序引擎加地理空间引擎双擎驱动把交通数据的时间维度和空间维度放到底层一起处理。城市交通是个时刻变的网络一个路口堵了周边几条路跟着慢。传统方案你得先查时序库拿流量变化再查GIS库拿路口空间关系然后在应用层自己拼。金仓这边时序数据和空间数据在一个内核里直接关联省了数据同步和跨系统拼接。据报道通行效率提了20%以上。还有个机场的项目。金仓时序数据库帮机场从被动抢修转到预判模式靠对设备运行数据的时序分析和趋势预测在故障真发生之前就触发预警。这种预测性维护的底子就是超表对海量历史设备数据的快速检索和聚合能力。运维侧能自动的就别让人来开发者看到的是一张逻辑表运维要管的是底下分片怎么跑。金仓在运维侧的思路我总结一下就是一句话能自动的绝不让人手动来。分片创建这件事传统方案要DBA提前把未来几个月的分区手动建好或者写个定时脚本批量生成。脚本出了bug或者漏了某段时间的分区数据写入直接报错。超表这边系统根据你配的时间分区策略自己建新分片。当前分片快满了下一个自动跟上不需要人插手。数据归档和清理也一样。保留多久、什么时候归档、归到哪层存储、什么时候彻底删传统方案全靠运维脚本和手动操作。金仓超表支持配自动化规则-- 保留180天更早的自动清理SELECTadd_retention_policy(device_metrics,INTERVAL180 days);-- 30天以上的数据自动迁到低成本表空间SELECTadd_storage_policy(device_metrics,INTERVAL30 days,tablespacets_cold_storage);配完了系统到点自己执行迁移和清理。需要手动干预的时候比如临时保留某段数据做故障分析暂停一下特定分片的自动清理事后再恢复就行。写入性能监控也集成了。运维可以通过系统视图看各分片的写入量、数据量、压缩率-- 看各时间分片的存储大小SELECTrelnameASchunk_name,sys_size_pretty(sys_relation_size(oid))ASsizeFROMsys_classWHERErelnameLIKEdevice_metrics_2026%ORDERBYsys_relation_size(oid)DESCLIMIT10;要是发现某个哈希子分片的数据量是其他的好几倍说明空间维度有倾斜可能得调哈希分区数量或者换个哈希键。不过实际上设备ID的哈希分布一般比较均匀这种倾斜不常见。底层存储列式压缩和批量写入超表解决的是分片管理问题。但写入快不快、存储省不省钱还得看底层存储引擎。列式存储这块时序数据本质是同一指标在不同时间点的连续数值列式把同一列的数据放一块用RLE、字典编码、Delta-of-Delta这些压缩算法压缩比比传统行存储高不少 $时序数据处理组件金仓数据库如何高效管理时间序列。写入路径的设计是数据先进内存时序缓冲区攒够了阈值再批量刷盘。随机I/O变成顺序写写入效率拉满。应用层配合批量写入效果更好每秒的传感器数据打包成批次走JDBC批量插入// Java批量写入StringsqlINSERT INTO device_metrics (ts, device_id, temperature, pressure, vibration) VALUES (?, ?, ?, ?, ?);try(PreparedStatementpsconn.prepareStatement(sql)){conn.setAutoCommit(false);for(SensorReadingreading:batch){ps.setTimestamp(1,Timestamp.from(reading.getTs()));ps.setString(2,reading.getDeviceId());ps.setDouble(3,reading.getTemperature());ps.setDouble(4,reading.getPressure());ps.setDouble(5,reading.getVibration());ps.addBatch();}ps.executeBatch();conn.commit();}批量大小有个讲究。太小了看不出效果太大了吃内存而且失败了回滚代价高。我自己的习惯是从1000条起步压测逐步加大到写入延迟开始往上走的拐点取拐点前面一档当生产配置。时序数据不该是座孤岛最后说个容易被忽略的点。金仓的时序能力是构建在融合数据库架构里的原生能力不是独立外挂的模块。这事说起来抽象放到具体场景里就好理解了。你做设备预测性维护要喂给模型的数据包括设备历史运行参数时序、设备型号和投运日期关系、设备安装位置和周边环境空间、领域专家总结的故障特征向量。这些数据如果散在不同系统里数据工程师光做对齐和搭管道就得花掉项目六成以上的时间。金仓的融合架构让这些数据在一个内核里直接可用一条SQL就能跨时序、关系、空间、向量做关联查询AI团队能把精力挪到模型迭代上 $AI落地卡壳数据散成渣金仓时序数据库多模融合能力一键打通。回到晚上12点开头老张那个故事如果当时系统跑的是超表架构某个时间分片数据量膨胀导致写入路由失效这个问题压根不会出现。超表的分片创建是自动的数据量涨了系统自己切新分片不存在一个分片被撑爆的情景。运维不用手动维护路由表不用每月做重平衡不用写归档脚本。部署阶段配好分区策略和保留周期剩下的交给系统自己跑。超表架构真正有价值的地方不是哪个单点技术多花哨而是它把分片管理这件事从运维的负担变成了系统内置的能力。开发者对着一张逻辑表写标准SQL运维对着自动化策略做配置底层物理分片的创建、路由、裁剪、归档全由内核处理。关系型数据库的易用性保住了分布式数据库的水平扩展能力也拿到了。做时序数据库选型的同行别光盯着每秒能写多少行这个数。更该问的是跑了几个月之后还能不能稳定写历史数据越堆越多查询还快不快设备不断接入架构能不能平滑扩金仓超表在北京轨交TCC、泰兴交通、机场预测性维护这些项目里已经跑出了答案 。剩下的看你自己的场景对不对得上。