尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

时序数据库那些年|我与金仓超表Hypertable的一场久别重逢

时序数据库那些年|我与金仓超表Hypertable的一场久别重逢 一、那些年我们一起爬过的月台做时序数据的人大概都有过类似的经历。你接手一个项目设备数据每秒几条一天下来几千万条要存好几年。你选了数据库建了表然后开始想这么多数据一张表肯定放不下得分片。分片这两个字说起来轻巧做起来才知道是个深坑。1.1 第一次写分表脚本的那个下午我还记得第一次做时序分表的那个下午。那是一个物联网项目几百台设备每台每秒采一次数据。我当时想按天分表吧每天一张表表名带日期清晰明了。于是我写了个脚本每天凌晨自动建第二天的表。-- 类似这样的逻辑每天跑一次CREATETABLEsys_metrics_20260812(LIKEsys_metrics_template INCLUDINGALL);写完那天我还挺得意觉得自己设计得挺合理。结果上线第一周就出问题了。脚本跑的时候服务器卡了一下第二天的表没建成功。早上八点设备数据开始灌进来全报错了。运维同事六点多给我打电话我迷迷糊糊爬起来手动建表手都是抖的。后来我给脚本加了重试、加了告警、加了前置检查生怕哪天又漏建了。但你知道吗这种事防不胜防。有一次服务器磁盘满了脚本建表失败等发现的时候已经丢了两个小时的数据。客户那边脸拉得老长我跟运维同事两个人对着日志查了一下午最后还是没找回来。那时候我就想不就是建个表吗怎么就这么难呢就像父亲爬月台本来买橘子是件简单的事可因为月台之间隔着铁道就变得不容易了。分片也是一样本来存数据是件简单的事可因为数据量太大要分片就变得处处是坑。1.2 跨天查询的那些深夜建表的事搞定了查询的麻烦又来了。用户要查最近三天的数据你得拼三张表查最近一周拼七张查一个月三十张表UNION ALL。我写过最长的一条查询SQL拼了九十多张表整整三百多行。你能想象吗一条SELECT语句FROM后面跟着九十多个表名用UNION ALL连起来。我写完之后自己都看晕了更别说维护了。有一次客户要改一个查询逻辑加个过滤条件。我得在九十个子查询里每个都加上那个条件一个都不能漏。加完之后测试发现有个子查询漏了结果对不上。我对着SQL一行一行找找了半个多小时才找到漏的那一个。那天晚上又是凌晨两点才回家路上的雪已经积了薄薄一层踩上去咯吱咯吱响。我那时候经常想要是有一张表就好了。不用拼不用管日期就SELECT * FROM 某张表 WHERE ts BETWEEN ...多简单。可那时候没有这样的东西。数据量摆在那儿一张表存不下也查不动。你只能一张表一张表地拼就像父亲只能一个台阶一个台阶地爬月台。没有捷径。1.3 扩容那天我们熬了个通宵如果说建表和查询是日常的麻烦那扩容就是一场灾难。项目跑了一年多数据量比预期大了一倍原来的存储不够了要加节点。传统分表的扩容你得把已有数据迁移到新节点上。怎么迁导出、传输、导入、验证、切换。每一步都不能出错出了错数据就乱了。我们选了个周末计划停八个小时业务。周五晚上十点开始先停应用再导出数据。导出就导了三个小时数据量太大了。然后传输又一个多小时。导入的时候出问题了有几张表的索引建失败得重来。等全部搞定已经是周六早上六点了。我和运维同事两个人在办公室坐了一整夜眼睛里全是血丝。客户的运维主管过来验收的时候看着我们俩的样子叹了口气说“辛苦了。”那时候我就在想扩容这件事能不能不用这么折腾加个机器而已为什么要把人熬成这样就像父亲买橘子本来是件小事可因为要穿过铁道、爬上爬下就变成了一件让人看着心疼的事。扩容也是本来加个节点就能解决的事可因为数据是手动分片的就变成了一场通宵达旦的战役。1.4 那些没人看见的运维脚本除了建表、查询、扩容还有一堆杂事。过期数据要清理吧你得写个脚本定期删旧表。删之前得确认吧万一删错了呢归档要做吧冷数据要挪到便宜的存储上吧分片大小要监控吧有的表数据特别多有的特别少不均衡怎么办热点分片要处理吧某台设备数据量特别大那张表就成了热点查询慢得要死。这些事每一件单独拿出来都不算大但凑在一起就是没完没了的运维负担。我那个项目光分片相关的运维脚本就写了十几个加起来一千多行代码。每天都要检查这些脚本有没有正常跑有没有报错。运维同事跟我说他每天早上到公司第一件事就是看这些脚本的执行日志。看得头都大了。有一次清理脚本出了个bug把当月的数据当成过期数据给删了。发现的时候已经删了一半。我们两个人从备份里恢复搞了整整一天。客户那边差点发火最后还是我去赔了不是才压下来。那些年做时序数据就是这样。表面上看系统在跑数据在存查询在返回。但背后是无数个深夜的调试、无数个周末的通宵、无数个提心吊胆的清晨。就像父亲的背影你只看到他把橘子放在你皮大衣上却没看到他爬月台时有多努力。你只看到系统在运行却没看到背后有多少人在为分片管理这件事疲于奔命。二、遇见超表像有人在月台上搭了一座桥转机出现在两年前。那时候我在做一个新的物联网项目又要面对时序数据存储的问题。客户提了个要求要用国产数据库。我那时候对国产数据库的印象还停留在能用就行的阶段。但客户要求了就得去了解。就是在那个时候我第一次接触到了电科金仓KingbaseES的超表Hypertable。2.1 第一次建超表的那个上午我记得很清楚那是一个周三的上午阳光很好。我在测试环境里装了金仓然后照着文档试着建一张超表。CREATETABLEsys_metrics(tsTIMESTAMPNOTNULL,device_idVARCHAR(64)NOTNULL,metric_nameVARCHAR(64)NOTNULL,metric_valueDOUBLEPRECISION,qualityINT);SELECTcreate_hypertable(sys_metrics,ts,chunk_time_intervalINTERVAL1 day);就这么两行。第一行建表跟普通表一模一样。第二行把它变成超表按天分区。建完之后我愣了好一会儿。就这不用写建表脚本不用每天凌晨自动建分区我试着插了一条数据INSERTINTOsys_metricsVALUES(2026-08-11 10:00:00,DEV001,temperature,25.6,1);成功了。我又查了一下SELECT*FROMsys_metrics;也查到了。我又插了一条明天的数据INSERTINTOsys_metricsVALUES(2026-08-12 10:00:00,DEV001,temperature,26.1,1);也成功了。我去查了一下底层发现系统自动建了两个Chunk一个存11号的数据一个存12号的。没有人让它建它自己就建了。那天上午我坐在电脑前反反复复地插数据、查数据像个得到新玩具的孩子。就像有人在月台上搭了一座桥。你不用再跳下铁道、再爬上去了。你走过去就行桥替你承担了所有的艰难。那些曾经让我熬到凌晨的自动建表脚本忽然之间就不需要了。2.2 第一次写跨月查询的那一刻建表的惊喜还没过去查询的惊喜又来了。我在测试环境里灌了三个月的数据然后写了一条查询SELECTdevice_id,AVG(metric_value)asavg_tempFROMsys_metricsWHEREtsBETWEEN2026-06-01AND2026-08-31ANDmetric_nametemperatureGROUPBYdevice_id;就这么简单。一张表名一个WHERE条件一个GROUP BY。不用拼九十张表不用写UNION ALL不用动态计算日期。执行了一下结果出来了而且很快。我看了一下执行计划发现系统自动做了分区裁剪只查了6月到8月这九十多天对应的Chunk其他的直接跳过了。它知道你要查哪段时间就只查那段时间的数据不相关的看都不看。那一刻我真的有点激动。你知道吗做了这么多年时序数据我写过无数条拼了几十张表的SQL。每一条都写得小心翼翼生怕漏了一张表、拼错一个日期。现在忽然不用了就写一张表名剩下的系统帮你搞定。那种感觉就像你走了十年的泥泞小路忽然有一天路修成了柏油马路。你还是要去那个地方但路上的颠簸全没了。三、超表的心思它把艰难都藏在了背后用了一段时间超表之后我开始好奇它到底是怎么做到的。为什么在我看来就是一张普通表底层却能自动分成那么多Chunk为什么我不用管分区它自己就建好了为什么扩容不用停业务它自己就把数据迁过去了我去研究了一下它的架构越研究越觉得这东西设计得真用心。它就像一个默默做事的人把所有的艰难都藏在背后给你看的永远是最简单的一面。3.1 逻辑表与物理Chunk两层之间的那座桥超表最核心的设计就是逻辑表和物理Chunk的两层映射。什么意思呢在你看来就是一张表叫sys_metrics你用标准SQL操作它就行。但在底层这张表被切成了很多个物理数据块每个块叫一个Chunk存一段时间的数据。比如你存了三个月的数据按天分区那底层就有九十多个Chunk。每个Chunk是一张独立的物理表有自己的数据文件、索引、统计信息。但这些你都看不到你看到的只有最上面那一张逻辑表。这中间有一个超表引擎层负责翻译。你写一条INSERT引擎看一下这条数据的时间算出来该放到哪个Chunk里。如果那个Chunk还不存在引擎就自动建一个。然后把数据放进去。你写一条SELECT引擎看一下你的时间条件算出来需要查哪些Chunk。然后只去查那些Chunk不相关的直接跳过。查完之后把结果合并起来返回给你。你写一条DELETE要删三个月前的数据引擎直接把对应的Chunk整个删掉。不用一行一行删直接删物理文件又快又干净。这整个过程你完全不用管。你就面对一张表写标准SQL剩下的引擎全帮你做了。这就像月台上的那座桥。你从桥上走过去很轻松。但桥的下面是桥墩、是钢架、是混凝土是无数人花了大力气建起来的。你看不到那些你只需要走过去就行。超表的引擎层就是那座桥。它把分片管理的所有复杂性都扛在了自己身上给你一个最简单的接口。3.2 Chunk的一生从出生到消亡全是自动的我研究Chunk管理的时候发现了一个很有意思的事情。Chunk从创建到删除整个生命周期全是系统自动管理的不需要人干预。出生你插入数据的时候如果对应的Chunk不存在系统自动创建。不用你写脚本不用你定时任务数据来了它就建。就像你走到桥边发现桥已经搭好了你直接走就行。成长Chunk里的数据越来越多系统会监控它的大小。如果某个Chunk太大了超过了阈值系统会自动把它分裂成两个更小的Chunk。比如某天的数据特别多一个Chunk装不下了系统就把它拆成上午一个、下午一个。这样每个Chunk的大小都在合理范围内查询性能不会因为数据太多而下降。合并如果有些Chunk太小了比如某天数据很少只有几万条系统也会自动把相邻的小Chunk合并成一个大的。不然碎片太多元数据管理起来也麻烦。该拆的拆该合的合系统自己会调整。消亡数据过期了不需要了系统自动把对应的Chunk删掉。你设一个保留期限比如90天超过90天的Chunk系统自动清理。不用你写删除脚本不用你怕删错系统帮你处理得干干净净。你看Chunk的一生从出生到消亡全是自动的。你唯一要做的就是在建表的时候说一声我要按天分区保留90天。然后就不用管了。这就像你请了一个管家你告诉他家里的事你看着办然后他就把所有事都办好了。你不用每天叮嘱他做这做那他自己知道什么时候该做什么。3.3 时空组合分区更聪明的分法只按时间分区有时候还不够。比如设备特别多一天的数据量特别大一个Chunk装太多了查询起来慢。这时候超表支持时间空间的组合分区。什么意思呢就是除了按时间分再按另一个维度比如设备ID分一次。比如按天分时间分区同时按设备ID做4个空间分区。那每一天的数据就不是一个Chunk了而是4个Chunk。不同设备的数据按哈希值分到不同的Chunk里。这样做有什么好处呢第一单个Chunk不会太大。一天一亿条数据分成4个Chunk每个两千五百万条查询起来更快。第二写入可以并行。不同设备的数据写到不同的Chunk互不干扰写入吞吐量更高。第三避免热点。如果某些设备数据特别多只按时间分的话都在一个Chunk里容易热点。组合分区把它们分散开了热点就缓解了。第四查询更精准。如果你查某台设备的数据系统直接定位到对应的那个空间分区只查一个Chunk不用查全部4个。这个设计我觉得特别聪明。它不是简单地把数据切开而是根据数据的特征用多个维度来组织让存储更合理、查询更高效、写入更均衡。而且这些你都不用管建表的时候说一声按设备ID分4个区剩下的系统自己搞定。就像一座桥不只是能走过去还分了人行道、车行道、快车道。不同的需求走不同的道大家都快。但你走的时候不用管这些你走你的就行桥会帮你安排。3.4 分布式扩展加节点就像加椅子超表还有一个厉害的地方就是支持分布式部署。Chunk可以分布在多个节点上数据量再大也不怕。加节点的时候系统自动把一些Chunk迁到新节点上不用停业务不用你手动迁数据。我第一次测试扩容的时候心里还有点紧张。毕竟之前那次通宵扩容的经历太深刻了。我加了一个节点然后看着监控。系统开始自动把一些Chunk迁到新节点上一个一个迁有条不紊。迁的过程中我还在不停地插数据、查数据一切正常没有报错没有明显的变慢。过了几个小时所有Chunk都迁完了数据均匀分布在两个节点上。整个过程我什么都没做就看着它自己完成了。那一刻我真的有点感动。你知道吗之前扩容是一场战役要提前规划、要选时间、要停业务、要通宵。现在扩容就像在餐厅里加一把椅子。你说加个位置服务员就搬把椅子过来摆好你继续吃饭什么都不耽误。这种从容是以前想都不敢想的。四、鱼和熊掌关系型的简单分布式的能耐用超表用得越久我越觉得它最了不起的地方不是自动分区也不是分布式扩展。而是它把两个看起来矛盾的东西结合到了一起——关系型数据库的简单易用和分布式数据库的水平扩展。4.1 标准SQL不用学新东西很多时序数据库为了追求性能和扩展性搞了一套自己的查询语言。你要用它就得重新学原来的SQL经验用不上。而且很多关系型数据库的功能它不支持比如多表JOIN、子查询、窗口函数、存储过程。你想用这些功能对不起没有自己想办法。超表不是这样。它就是金仓关系型数据库里的一张表标准SQL全支持。你会写SQL就会用超表零学习成本。JOIN、子查询、窗口函数、存储过程、触发器、视图……该有的都有想用就用。我之前那个项目数据分析师经常要做一些复杂的分析查询要关联设备表、工单表、指标表还要用窗口函数算趋势。如果用那种功能受限的时序数据库这些都做不了得把数据导出来在外面算。用超表就简单了直接在数据库里写SQL关联查询窗口函数想怎么算怎么算。数据分析师说用了超表之后他做分析方便多了不用倒来倒去了。这就是关系型数据库的好处。它经过了几十年的发展功能非常完善生态非常成熟。你需要的功能它基本都有。超表站在关系型数据库的肩膀上把时序的分布式能力叠加上去既保留了关系型的完整功能又有了分布式的扩展能力。这就像一座桥不只是能走过去桥上还有路灯、有护栏、有休息区什么都有。你走在上面跟走在平地上一样舒服但它能跨越原来过不去的铁道。4.2 水平扩展数据量再大也不怕关系型数据库的简单有了那扩展性呢传统关系型数据库数据量到一定程度单机就扛不住了。你只能换更好的服务器加CPU、加内存、加磁盘。但硬件是有上限的而且越往上越贵。这叫纵向扩展有天花板。超表是横向扩展。数据量不够了加节点就行。一个节点不够加两个两个不够加四个。理论上没有上限加节点就能提升存储容量和计算能力。而且加节点的过程前面说了不用停业务系统自动迁数据。这就像你家里请客人多了坐不下。纵向扩展是换一张更大的桌子但桌子再大也有个限度。横向扩展是多摆几张桌子来多少人摆多少桌没有上限。超表就是后者数据量再大加桌子就行。而且查询的时候多个节点并行算。一个复杂查询拆成好几份每个节点算一部分然后合起来。节点越多算得越快。这就像好几个人一起干活比一个人干快多了。4.3 两者兼得这才是真本事把关系型的简单和分布式的扩展结合在一起说起来容易做起来难。很多数据库要么简单但扩展不了要么能扩展但用起来复杂。两者兼得的很少。超表是怎么做到的关键就是那层透明映射。它在关系型表的上面加了一个超表引擎层。这个引擎层负责把逻辑表的操作翻译成对底层分布式Chunk的操作。向上给你一个标准的关系表接口向下管理分布式的存储和计算。你用的时候感觉就是在用一张普通的关系表。但实际上底层是分布式的数据分布在多个节点上查询是并行执行的。分布式的复杂性全部被这层映射藏起来了。你看不到也不用管。这就像自动挡的汽车。你踩油门就走踩刹车就停不用管离合器、不用换挡。但发动机、变速箱、传动系统该有的都有在你看不到的地方自动工作。你享受了简单的驾驶体验同时也拥有了汽车的全部性能。超表就是数据库里的自动挡。你用标准SQL操作不用管分片、不用管分布、不用管并行。但底层该有的分布式能力一样不少。我觉得这才是真本事。不是把复杂的东西丢给用户让用户去学、去适应。而是把复杂的东西自己扛下来给用户一个最简单的接口。好的技术应该是让人感受不到技术的存在。你用着很自然、很简单但背后是大量的技术积累和设计巧思。五、改造实录那个项目后来怎么样了讲了这么多原理和感受最后给大家讲讲那个项目的实际改造过程。就是我开头说的那个传统分表方案做了两年的工业物联网项目。后来我们把它迁到了金仓超表上。迁完之后的变化比我预想的还要大。5.1 迁移那两天迁移选了个周末。但跟之前扩容那种通宵不一样这次迁移很从容。我们用金仓的数据迁移工具把旧库的数据导出来再导入超表。数据量不小三年的数据五百多亿条。导入花了大概一天半。导入的过程中系统自动创建Chunk不用我们管。我们就在旁边看着喝喝茶聊聊天偶尔检查一下进度。迁完之后底层有四千多个Chunk三年×365天×4个空间分区。但应用层看到的就是一张sys_metrics表。然后是改应用代码。原来那些拼表名、写UNION的SQL全改成了单表查询。改了多少呢大概改了几十条SQL平均每条从两百多行改成了十几行。代码量减了一大半。改完测试跑了一遍全通过。整个迁移过程从数据导入到代码改完到测试通过两天搞定。比我预想的顺利太多了。5.2 迁完之后的那些变化迁完之后跑了一段时间变化是方方面面的。开发那边最直接的感受是写SQL变简单了。原来做一个跨时间范围的统计要先算日期、再拼表名、再写UNION半天才能写好一条SQL。现在直接写单表查询几分钟就搞定了。开发效率提升了多少呢他们自己说时序数据相关的功能开发速度快了一倍都不止。而且bug少了原来拼表名容易拼错现在不会了。查询性能也提升了不少。因为超表的分区裁剪更精准加上空间分区的并行查询典型查询比原来快了两三倍。尤其是大范围的聚合查询原来要扫几十张表现在系统并行扫Chunk快多了。客户那边说原来跑十几分钟的报表现在两三分钟就出来了。写入性能更稳定了。组合分区之后写入分散到多个Chunk高并发的时候不会卡在一个点上。原来月底数据量大的时候写入延迟会明显上升。现在很平稳不管数据量多大延迟都差不多。运维那边变化最大。那些分片管理的脚本全删了不用每天早上查日志了。自动建分区、自动清理过期数据全是系统自己搞定。运维同事说他现在每天看一眼监控就行基本上不用管数据库的事了。他甚至有时间去学别的东西了。扩容后来我们又加过一次节点。加完之后系统自动迁Chunk业务完全没停。运维同事甚至都没跟我说还是我看监控的时候发现节点数变了去问他他才说哦上周加的挺顺利的。你看扩容已经变成了一件不值得专门说的事了。这在以前是想都不敢想的。六、结语这些年做技术我越来越觉得技术的发展其实就是在修一座又一座的桥。原来要爬月台的现在有桥了原来要手写分片的现在有超表了原来要通宵扩容的现在加个节点就行。每一座桥的背后都有无数技术人的付出和积累。他们把艰难的事扛下来把简单的路留给后来的人。电科金仓作为国内自主研发的数据库能做出超表这样的产品我是真心敬佩的。这不是简单的功能堆砌是对时序场景的深刻理解加上扎实的内核功底才能做出来的东西。而且它不是为了炫技是真的解决了开发者的痛点。
返回列表