各位,我是老张。今天从一次实战出发,往下拆一层。时序数据这东西,前几年大家关注写入速度。百万点每秒、千万点每秒,数字越喊越大。但真到了生产环境,问题往往不在写入。在存储成本,在历史数据加载,在查询效率。今天把这三笔账拆开算。
一、先算一笔存储账
某省智能电表的项目里,500万个观测点。一年下来,1956亿行。这个量级,已经不能用"数据多一点"来形容。它直接决定存储要花多少钱。如果按传统方式存,每行按100字节算。一年接近20TB。保留三年、五年,成本更吓人。很多项目不是算力不够,是存储先扛不住。数据还在源源不断进来,历史数据又不能随便删。
这里有个矛盾。业务希望数据留得越久越好。存储预算又不可能无限涨。很多项目最后只能做冷热分层。热数据留最近几个月,冷数据归档。但归档也要占空间。压缩比上不去,分层也只是把成本往后挪。
时序数据有自己的规律。按固定周期采集。相邻时间点相关。重复信息多。这些规律,就是压缩的空间。压得好,同样的数据占更少空间。压得不好,查询还要额外解压,得不偿失。金仓时序数据库的存储层,就是围绕这些规律设计的。它不是给行存加一个压缩开关。时间戳、浮点值、标签列,各走各的编码。几种编码按列组合,压缩和查询的代价一起算。
金仓在这个电表项目里,用500万个观测点、一年1956亿行做了验证。实测压缩比45:1。金仓公开资料给出的对比,约为业界水平的3.6倍。这个45:1是在电表数据上跑出来的。采集周期稳,数值波动小,压缩比自然高。换成别的数据,结果要重新测。但压缩比不是越高越好。要看查询模式。点查多、随机读多,解压代价会被放大。范围查询多、顺序读多,高压缩比更划算。选型时,不能只盯着一个压缩数字。
二、时序数据为什么能压
压缩不是玄学。时序数据能压,是因为它有结构。时间戳按固定间隔走。数值在相邻点之间变化不大。设备编号、测点名称,重复率很高。这些结构,给了编码算法发挥空间。金仓时序数据库的压缩层,不是一套算法打天下。它按列选编码,再按数据特征组合。
时间戳用Delta-of-Delta。第一个差值,记下相邻时间点的间隔。第二个差值,记下间隔的变化。间隔稳定时,第二个差值大量为0。存储量就下来了。这比每个时间戳都存全量,省很多。浮点值则用Gorilla XOR。相邻两个值做异或。相同的高位和低位,可以压掉。只保留变化的部分。传感器数据平稳时,异或结果里大量是0。压缩效果就明显。
剩下的重复字符串,用字典编码。设备编号、测点名称、区域编码,反复出现。给每个值分配一个短ID。存ID,不存长字符串。查询时再映射回去。存储和IO都会省。数据本身则按列存。同一列的数据放在一起。时间戳一列,数值一列,标签一列。同列数据的相似度高。压缩算法更容易找到规律。列式存储也更适合范围扫描和聚合计算。金仓时序数据库的存储布局也是列式。编码和扫描,都围绕列来做。
| 编码方式 | 压什么 | 适合什么数据 | 代价 |
|---|---|---|---|
| Delta-of-Delta | 时间戳、等间隔数值 | 采集周期稳定 | 乱序写入时收益下降 |
| Gorilla XOR | 浮点数值 | 相邻值变化平缓 | 剧烈波动时压缩率下降 |
| 字典编码 | 重复字符串 | 设备、测点、区域标签 | 字典过大时维护成本上升 |
| 列式存储 | 同列数据 | 范围查询、聚合分析 | 点查多时未必最优 |
这几种编码不是万能。数据波动大、乱序写入多,压缩率会下降。标签基数太高,字典也会变大。压缩方案要跟着数据特征走。不是一套编码打天下。金仓的这套组合也不是固定模板。数据特征变了,编码和块大小都要跟着调。还有一个细节。压缩通常是在数据块内做的。块越大,压缩率通常越高。但块太大,点查要解压更多数据。块太小,压缩率又上不去。块大小要按查询模式调。这是压缩和查询之间的取舍。
三、写入路径决定加载效率
历史数据加载,是另一个容易被低估的场景。数据迁移、系统升级、数据平台建设。这些项目都要把多年积累的数据灌进新库。TB级、几十TB级,很常见。传统导入方式,逐行插入。每插一行,可能还要维护索引、写事务日志。数据量一大,速度就上不去。业务等不起,项目周期被拉长。很多迁移项目卡在数据准备阶段。不是数据库算不动。是加载路径不对。
历史数据写入这块,金仓时序数据库单独优化了写入路径。它不是把逐行INSERT调快,而是改成批量写。一次提交一批,按时间顺序组织写入。索引维护和事务日志的重复开销,也跟着降下来。这条路径解决的是加载窗口,不是在线写入。分布式部署环境下,1956亿行写入用了701分钟。平均465万行每秒。金仓公开资料给出的数据,约为业界水平的2.3倍以上。这个速度,决定了历史数据迁移能不能在窗口内完成。
批量加载也有参数要调。一次提交多少行。并发开多少。索引什么时候建。这些参数没有标准答案。数据特征不同,最优值也不同。上线前要拿真实数据试。别直接套别人的配置。金仓把批量路径做出来了,参数仍要按项目调。701分钟、465万行每秒,也要连环境看。分布式节点数、批量大小、硬件配置、数据特征,都会影响结果。脱离条件谈写入速度,没有意义。我拆性能数据,一向先看测试条件。
还要记住一点。写入快,不等于查询快。写入路径和查询路径,是两套设计。写入追求顺序、批量、少开销。查询追求裁剪、并行、少读无关数据。选型时,两个都要测。
四、数据组织决定查询效率
时序数据量大,还有三个特点。设备多,采样频率高,时间跨度长。同样一张表,按什么方式组织,查询效率差别很大。普通分区表,按时间分区。查询时可以先裁掉不相关的分区。这个思路没错。但分区一多,元数据和管理成本就上来了。分区粒度太细,管理麻烦。太粗,裁剪效果又不好。
金仓的时序超表,换了另一套组织方式。按时间组织数据。数据按列存。查询时先定位时间范围,再在范围内扫描。减少随机IO,也减少无关数据读取。它不是给普通表换个名字。底层的数据组织变了。
项目做过一组对比。数据规模和表结构相同。实时插入,超表用了404秒。普通分区表用了549秒。曲线查询,超表253毫秒。普通分区表4834毫秒。曲线查询这一项,快了19.1倍。这个差距,不是语法造成的。是数据组织方式造成的。时间范围裁剪减少无效扫描。列式读取减少无关列IO。这些机制叠在一起,查询越集中在时间维度,超表的优势越明显。
| 场景 | 时序超表 | 普通分区表 | 差距 |
|---|---|---|---|
| 实时插入 | 404秒 | 549秒 | 约1.36倍 |
| 曲线查询 | 253毫秒 | 4834毫秒 | 19.1倍 |
五、选型要算总账
时序库选型,不能只看一个指标。压缩比、写入速度、查询延迟、保留周期、运维成本。五项要一起看。只看写入速度,容易选到"灌得快、查得慢"的方案。只看压缩比,容易忽略解压代价。我一般先做容量估算。公式不复杂。日增行数,乘以单行字节数。再乘以保留天数。最后除以压缩比。算出来的,是大概的存储需求。保留周期也要算进去。三年和五年,存储预算差一大截。
举个例子。每天1亿行,每行100字节。原始数据每天10GB。保留三年,约10.95TB。按20:1压缩,约547GB。这个账算清楚,才知道存储要投多少。按这套算法,45:1才有意义。金仓时序数据库的压缩比,也要放进同一个容量模型里看。脱离数据特征和保留周期,单看一个倍数,容易高估收益。
容量估算只是第一步。还要看查询模式。点查多,还是范围查询多。聚合多,还是明细多。写入是持续平稳,还是批量突增。这些答案,决定压缩策略和表结构。总账还要算服务器和网络。压缩比高,存储省了,CPU可能更忙。解压要算力。写入快,磁盘IO压力也大。存储、计算、网络,三块要一起算。只算存储单价,容易得出错误结论。
总账还要算运维。备份、恢复、扩容、监控。分布式时序库,运维复杂度比单机高。团队能不能接住,要提前判断。别只看产品参数,不看自己的人力。
六、什么时候不该用时序库
时序库不是万能。数据量小、查询简单,普通关系库够用。上时序库,反而多一套系统要维护。数据保留周期短,压缩收益不明显。也不一定非要上专用时序库。强事务、复杂关联多的业务,时序库也不擅长。时序场景追求写入吞吐和范围查询。跨表事务、多表关联,不是它的强项。选型要看业务主干,不要拿边缘场景做决定。
团队没有分布式运维能力,先别急着上。分片、副本、扩容、故障切换,每一项都要人接。系统上了,没人维护,比不上更麻烦。反过来说,什么场景适合用时序库。数据持续增长,查询集中在时间维度。需要长期保留,又不想无限加存储。这类业务,时序库的优势才明显。选型不是赶时髦,是看场景匹配。
七、避坑清单
第一条,只看写入速度,不看查询延迟。灌得快,查得慢,业务还是用不了。第二条,只看压缩比,不看解压代价。点查多的场景,高压缩比未必划算。第三条,用普通分区表硬扛时序场景。数据量一大,管理和查询都会吃力。
第四条,不做容量估算。存储拍到哪算哪,最后不是扩容,就是删数据。第五条,历史数据迁移不分批。一次性灌库,窗口根本不够。第六条,不监控块级健康。等问题出来才查,代价更大。
最后一条,别把时序库当成关系库用。它的优势在时间维度。复杂事务和关联,交给更适合的系统。选型不是比谁功能多,是看谁更匹配场景。选型前,先拿一个月的数据试跑。写入、查询、压缩,三项都测一遍。别只看厂商给的测试报告。金仓时序数据库的45:1和701分钟,也要连环境看。换成你的数据,先重测。
八、写在最后
时序库的竞争力,不在"能存",在"存得起、写得快、查得动"。压缩解决成本。写入路径解决加载效率。数据组织解决查询效率。这三件事只要有一件做不好,数据越多越难管。金仓时序数据库把这三件事做进了同一条链路。压缩层解决存得起。批量写入路径解决灌得快。时序超表解决查得动。45:1、465万行每秒、19.1倍,都是这条链路上的项目实测。数字只是结果。编码、写入路径和超表组织,才是背后的原因。
这也是我看金仓时序数据库的方式。不看单点参数,看三件事能不能同时成立。选型还是要回到自己的业务。数据量多大,查询怎么走,数据保留多久。三个问题答清楚,再决定要不要上时序库。别因为别人上了,自己也跟着上。
各位,你们现在时序数据一年长多少?存储成本扛得住吗?评论区聊聊。
我是底层玩家老张。咱不聊概念,只聊源码和压测跑出来的东西。