乐趣区

关于tdengine:TDengine-30-架构详解

在 8 月 13 日的 TDengine 开发者大会上,TDengine 分布式系统架构师关胜亮带来题为《反对 10 亿工夫线、100 个节点的 TDengine 分布式系统架构设计》的主题演讲,具体论述了 TDengine 3.0 新的架构设计思路。本文依据此演讲整顿而成。

在物联网大数据时代,随着企业业务的一直扩张,须要采集的设施数量急剧回升,通常要达到百万甚至千万的级别,采集频率也从以前的 15 分钟一个点逐步演变到当初的 1 分钟、30 秒、15 秒,甚至 1 秒的一个点,这么多数据还要源源不断地发往云端,如何进行更好地写入、存储及查问,成为企业亟待解决的难题。

在测点数暴涨、数据采集频次一直进步的大数据时代,传统实时数据库暴露出下列问题:

  • 没有程度扩大能力,如果数据量减少,只能依附硬件 scale up
  • 技术架构古老,应用磁盘阵列,大多运行在 Windows 环境下
  • 数据分析能力偏弱,不反对当初风行的各种大数据分析接口
  • 不反对云端部署,更无奈反对 PaaS

在此背景下,依附 Hadoop 架构造成的一系列通用数据存储解决方案,成为一众企业的首选,为了可能适配更多的业务场景,还要集成如 Kafka、Redis、Spark 等泛滥第三方开源软件,在一次次的实际中,也暴露出诸多问题,如开发效率低、运行效率差、运维简单以及利用推向市场慢等。

在此基础上,时序数据库(Time Series Database)应运而生了。尽管新兴的时序数据库之间竞争强烈,但因为业务场景的复杂性和数据的多样性,还没有哪一款产品真正成为物联网场景的领跑者,而大部分产品还都存在以下三点难以漠视的问题:

  • 性能繁多,须要集成其他软件,晋升零碎负重及运维难度
  • 不是规范 SQL,学习老本高
  • 没有实现真正的云原生化,程度扩大能力无限

在调研了数百个业务场景的根底上,TDengine 实现了 3.0 版本的迭代,集群反对 10 亿条以上的工夫线、100 台服务器节点,成为一款真正的云原生时序数据库,具备极强的弹性伸缩能力,且无需再集成 Kafka、Redis、Spark、Flink 等软件,能够大幅升高零碎架构的复杂度。

TDengine 分布式系统架构设计

如上图所示,在数据节点(Dnode)、虚构节点(Vnode)、治理节点(Mnode)之上,TDengine 3.0 集群新增了弹性计算节点(Qnode)和流计算节点(Snode)。 其中 Qnode 次要在运行查问计算工作中起作用,当一个查问执行时,依赖执行打算,调度器会安顿一个或多个 Qnode;Snode 次要负责运行流计算工作,能够同时执行多个。

针对数据库级别的元数据管理,3.0 版本通过两阶段提交来保障要害操作的一致性, 以上图为例,假如咱们要创立一张超级表,零碎首先会把 SQL 语句先解析成申请发给 Mnode,之后 Mnode 会把这个申请发给各个不同的 Vnode(Vnode1 和 Vnode2),最初咱们会等这些申请都完结之后再做一个长久化,而后把它返回给客户。

但在实际操作中,数据库级别的元数据,量是比拟少的,更多的还是数据表级别的元数据管理。在以前的版本中,元数据都是集中管理,而 TDengine 3.0 会把元数据都放到 Vnode 里,在放弃核心节点之后,程度扩大能力显著晋升。这样一来,当利用要将数据插入到一张表或对一张表做查问操作时,咱们就能够基于表名的特定 hash 值,将申请间接发送到对应的 Vnode 里,性能能够失去进一步晋升。

数据表中大量标签数据的解决也是一个重点,比如说一个设施的标签有 1K,那 100 万个设施合在一起的话可能就会产生 1GB 的元数据,如果把它们都放在内存里,启动速度天然就会变得比较慢。

为了解决这个问题, 新的版本采纳了 LRU 机制,只有应用比拟频繁的数据才会被放在内存中。 在全内存的状况下,对于千万级别规模的标签数据 TDengine 能做到毫秒级的返回,那在内存资源有余的状况下,咱们依然可能反对数千万张表疾速的查问。同时 TDengine 还提供了 TTL 机制,不便对一些只须要存储一个月或半年的数据,进行删除过期数据表的操作。

凭借着 LRU 机制,TDengine 的每一个 Vnode 都能反对十万乃至百万以上数据表的治理。 不同于 Prometheus,TDengine 的每个数据表能够有很多个字段,这样的话假如说一个表有十个字段,咱们就能够认为每个 Vnode 能够反对百万的工夫线。

此外,数据表路由的信息也是十分重要的。此前 TDengine 每一条数据表的路由信息都须要在 Mnode 做注销,再把注销的信息转给 Vnode,咱们想要做的事务频率会越来越多,那可能就会导致每一个零碎的 warmup 工夫越来越长。而且在刚开始部署一套零碎时,就须要先把这些表都创立好,压力十分大。

为了解决这个问题,TDengine 3.0 做了一个非凡的翻新,即数据表的路由采纳一致性 hash 算法, 具体来说就是把数据表的名称压缩到 2 的 32 次方长度的一个环形空间,在创立 Database 时就创立指定数目的 Vnode,零碎就会依照等分的办法,把它拆解到这一环形空间中,每一个 Vnode 就负责其中某一个 hash 范畴的数据表,并由 Mnode 来负责 hash 范畴的治理。

在零碎缩容、扩容时还能够通过动静调整 hash 范畴来实现,比方下面这个环形,咱们想把 Vnode 数量从 5 个变成 6 个,只须要调整其中某一个 Vnode 的 hash 范畴就能够做到了,这样一来,TDengine 就可能反对在 100 个数据节点上创立 Vnode 了。

大家可能会有一个疑难,如果用 hash 会不会产生比较严重的数据歪斜,如果你只有一百个设施或者一千个设施,这种歪斜可能是比较严重的,这时你能够创立数目较少的 vgroup,起码能够设置一个,一个 vgroup 蕴含 1-1000 个数据表时,性能差异不大。当你达到一万个设施时,这种歪斜咱们根本都看不出来了,数据是十分均匀分布的状态。

TDengine 反对特定查问场景的性能调优

所有的查问性能也好,写入性能也好,实质上都是为了升高对硬盘的读写次数,如果存储量降下来了,那读取速度天然就能够取得更大的晋升。一般来讲,一个硬盘的写入速度大略在 70MB/s 左右,读取速度可能在 100MB/s,数据库没有方法冲破这样一个物理上的瓶颈,那咱们想要做到亿级数据或者十亿级数据这样一个秒级的查问计算,就必须想尽各种各样的办法对数据进行降采样,升高它的存储量。

从这一思路登程,在 TDengine 3.0 中,咱们也做了很多查问性能上的优化,具体体现在如下的三个性能上:

1. Block-Wise SMA(写入过程中,保留数据块的预计算后果)

  • 内存数据积攒到肯定大小触发写磁盘
  • 由行存储转化为列存储
  • 在磁盘中以数据块 Block 模式组织
  • 把 Block 中各列数据的聚合后果,例如 max、min、sum、count 等存储到 sma 文件
  • 依据查问打算抉择应用哪些聚合后果

2. Rollup SMA(原始数据主动进行降采样存储)

  • 反对三个不同的数据保留层级,指定每层数据的聚合周期和保留时长
  • level 1 存储原始数据,能够在 level 1 中存储一条或者多条数据,level 2 和 3 存储聚合数据
  • Rollup 目前反对 avg, sum, min, max, last, first
  • 实用于 DevOps 等关注数据趋势的场景,实质是升高存储开销,减速查问,同时摈弃原始数据

3. Time-Range-Wise SMA(依照聚合后果降采样存储)

  • 实用于高频应用 interval 的查问场景
  • 采纳与一般流计算一样的逻辑,容许用户通过设定 watermark 应答延时数据,绝对应的理论的查问后果也会有肯定的提早

标签索引

咱们在 3.0 里也做了很多标签索引的优化,新实现了一个 TDB 模块,特色就是把标签数据进行了 LRU 的存储,这在后面也提到过。TDB 的查问实用于标签变动不频繁或者说是有结构化标签的设施,例如文本型和数值类型。

对于 JSON 类型的标签,特点是标签量很大然而数据内容很小,TDengine 采纳的就是 FST 的索引形式。索引的重建始终是 FST 外面比较复杂的局部,TDengine 采纳异步形式重建索引数据,因此不会让用户在创立表或者批改表时期待太长的工夫。

对于数据缓存,尽管 TDengine 2.0 也能够缓存最新的数据,但内存的消耗量会比拟大,而在 3.0 中用根底的 LRU 库就能够把最近的数据放在内存外面,让用户即使用很小的内存,也能够查到最近应用比拟频繁的数据。

计算资源弹性裁减

如上图所示,当客户端要进行明细数据查问时,须要先从磁盘里或者内存里源源不断地把原始数据读出来,这时咱们必定不心愿这个数据要在不同节点里进行大量的数据交换,减少网络或磁盘开销,从这一点登程,TDengine 将明细数据查问放在了 Vnode 中进行。

但在做一些聚合查问(数据的计算、合并、插值等)时,比如说在车联网场景下要察看所有车辆每一天动员多长时间,这一类查问都是在 Qnode 中进行,依据不同场景大家能够抉择配置不同数量的 Qnode。

在时序场景下升高对 Kafka、Flink、Spark 的依赖

在时序场景下,TDengine 升高了对 Kafka 的依赖,咱们的 Vnode 能够容许不同的消费者同时生产数据,所有的数据都是结构化的数据,用户能够只订阅本人关注的这部分数据,比如说我只想关注电流外面超限的数据,应用 TDengine 进行订阅时的数据传输总量十分小,但用 Kafka 进行数据订阅时很可能须要从服务器拉取全副的数据,而后在客户端中进行数据筛选,这时两者的性能就齐全不在一个量级上了。

此外,如果是罕用的一些计算,还能够把它们放到 Snode 里,Snode 会将流计算的后果放到独自 Vnode 外面去做存储,有了这样一个流计算的引擎,就大大降低了对 Flink 和 Spark 的依赖。

结语

TDengine 3.0 的架构改良,从要害个性上来看,除了程度扩展性之外,还加强了弹性和韧性,可作为一个极简的时序数据处理平台,可能让大家以更低的老本实现时序数据平台的搭建。接下来咱们还会陆续公布 TDCloud 云服务版本、TDLite 嵌入式版本,提供边云协同软件包、数据预测软件包,进一步晋升零碎高可用、高牢靠、计算能力。

大家能够马上下载体验 TDengine 3.0,也欢送大家多提宝贵意见。


想理解更多 TDengine Database 的具体细节,欢送大家在 GitHub 上查看相干源代码。

退出移动版