流是一个有方向感的汉字,并且给人轻便迅捷的感觉。TDengine(Time Series Database,TSDB)产品最后的灵感之一,便是和“流”字相干:一台物联网设施便是一条数据流,十万台设施便是十万条数据流。它们像溪河汇聚一样,每秒每分源源不断地流向了数据处理平台。
面对这样规模的大数据挑战,TDengine 抉择充沛地利用时序数据自身的特点(可参考:https://mp.weixin.qq.com/s?__biz=MzIzNzg5MTcxNA==&mid=2247483…),来针对性地设计存储引擎。最终的指标其实就是:高效继续地吞吐、消化这些数据流,让数据可能无提早地产生价值。
能够说,咱们谋求的便是“流”个别的产品能力。而对于文章题目的答案,本文将从 TDengine 的存储引擎的变动史说起:
因为认为工夫序列领有人造递增属性,所以在最晚期的 1.6 版本中,TDengine 是不反对对乱序数据的解决的,过后乱序数据写入表中后,零碎会做报错解决。但通过用户理论场景的磨难后, 咱们不得不把注意力聚焦在这个“害群之马”的身上 。在生产环境中,因为设施损坏,网络提早等起因,数据乱序达到是不免的。更要害的是,不论数据乱序与否,用户都有权力自行决定是否解决它,这是一个产品应该具备的灵便度。
它让现实中的数据流“乱”了,但咱们却又不能放弃它。
于是,咱们立即在 2.0 版本中减少了数据在内存中的排序和硬盘中的数据子块来反对乱序数据的解决,以此维持了数据的完整性和有序性。
然而这对于 2.0 版本的流式计算和订阅来说,依然有相似的麻烦。
过后的订阅 / 流计算(间断查问)是基于查问引擎的产物,它依附连续不断地执行 SQL 查问后果作出实时反馈。以订阅为例,每条符合要求被生产掉的数据的工夫戳,都会被记录下来,从而作为下次 SQL 查问中工夫范畴的起始点。这时,即使是新数据的工夫戳只比这个记录早一秒,也不会被 SQL 轮询到。因而能够说,2.0 的流计算(间断查问)/ 订阅同 1.6 一样,它只解决了有序局部的数据。实质上来说,因为 SQL 取到的只能是曾经入库的数据,所以这个阶段的查问行为是滞后的。
因而,咱们决定在 3.0 再次进行优化重构:
尽管数据的工夫戳有乱序,然而他们达到数据库的工夫永远分有先后,这组序列相当于“数据入库工夫”。不过这个“数据入库工夫”不是工夫戳,而是一个从 0 开始的整型数字,咱们称之为“版本号”,代表的是数据库概念是“第 x 次的数据变更”。相熟 WAL 概念的搭档们都晓得,TDengine 利用 WAL 技术来提供根本的数据可靠性:每一条 WAL 信息代表的是一次数据库的变更(增删改),所以每一条 WAL 信息都会有惟一的版本号。通过“版本号”,咱们能够明确地通知流计算 / 订阅该数据是否为新增数据,再通过对 WAL 的这组“版本号”创立索引,咱们就能够疾速定位要生产的数据了。
以订阅为例:3.0 的订阅引擎为工夫驱动,它会解析每一条新写入的 WAL 的音讯内容,而后判断是否匹配 topic 的 sql 条件,如果匹配则间接把 WAL 的音讯转化成数据返回给用户。
除了用于订阅,这组版本号还有很多非常重要的作用:
- 它自身外围的职责是 raft 日志的编号,用于多正本的数据同步;
- 把版本号下发给每行数据,以追加写入的模式实现数据的更新与删除。
比方:某条 wal 音讯的内容是写入一行数据:
insert into d1 values ("2022-03-10 08:00:00.000",100);
那么这行数据就也领有了这条 wal 音讯的版本号(假如为 1),并且永久性地存储在数据文件中。
解下来的一条 wal 音讯的内容是以雷同工夫戳更新这行数据:
insert into d1 values ("2022-03-10 08:00:00.000",200);
音讯的版本号便是“2”,这条数据会以写入的模式追加存储。查问的时候,在工夫戳雷同的状况下,通过比对版本号大小来抉择最新的数据,因而咱们失去的数据便是:”2022-03-10 08:00:00.000″,200。
删除同理,被删除的数据是取版本号较大的空数据,这样便可在不毁坏原有数据文件构造的状况下实现高效的删除。以上局部具体实现细节可参考:https://mp.weixin.qq.com/s/imECB9dIFxZKeoaF3uoOgg
3. 另外,当 follower 正本的数据落后,但 leader 上的 WAL 日志曾经隐没的状况下,版本号还能够做数据文件的快照。只把增量的数据传 输过去,大大节约 data recovery 的工夫。
通过这些大刀阔斧的重构,TDengine 完满地把下面几大模块缝合了起来:
- 解决了流计算、订阅对于乱序数据处理的不反对;
- 让删除操作为逻辑删除,解决了删除操作的性能问题;
- 基于版本号引入了快照机制,大幅优化了特定场景下的数据恢复的速度。
回到题目上,为何 TDengine 用户应尽快切至 3.0 版本?答案曾经都写在下面了。通过下沉到海量用户理论场景中重复迭代优化,从 1.6 到 2.0 再到 3.0,TDengine 从底层构造上解决了最后设计的瑕疵,各个模块之间构造变得更加清晰,连接也更加天然,这样扎实的底层设计对产品将来的稳固和性能晋升所带来的帮忙都是微小的。