乐趣区

关于数据库:TDengine-应用实录存储缩减超过-60HBase-等集群指数级下线

小 T 导读:狮桥团体的网货平台与金融 GPS 零碎,对于车辆轨迹收集与计算有着强需要。GPS 每日产生总量在 40 亿左右,须要为业务方提供实时末次地位查问,近 180 日行驶轨迹查问,相似车辆轨迹比照查问,以及一些危险逾期的智能剖析等等。利用 TDengine 后,他们的整体数据存储缩减超过 60% 以上,节俭了大量硬件资源。

一、缘起

2021 年 10 月,我偶尔读到 Jeff(涛思数据创始人陶建辉)所作的一篇讲述父亲的文章,言辞之恳切,也让我回想起了本人和父亲的种种过往,于是在 TGO(鲲鹏会)微信群中加了 Jeff 的微信。彼时恰逢咱们技术选型之时,在和他的寒暄之中,我理解到了时序数据库 TDengine,我和 Jeff 一拍即合。带着业务上的场景和问题,咱们约见了一次,他的激情及对 TDengine 的精妙设计深深吸引了我,对于我所提出的一些细节问题,他甚至拿进去最后写的代码为我解说,吃惊之余也让我十分打动。

和 Jeff 的这次会面让我更加理解了 TDengine,也让我看到了国产开源产品的心愿。通过审慎的思考,咱们抉择将 TDengine 接入到零碎之中,在所有尘埃落定后我整顿出了这篇文章,对 TDengine 的技术架构特点、咱们本身业务的实际思路及利用成果进行了相干论述,心愿能帮到有须要的敌人。

二、业务背景

狮桥团体的网货平台与金融 GPS 零碎,对于车辆轨迹收集与计算有着强需要。狮桥大数据团队自研星熠平台采纳国标 JT808 协定前置接收数据,通过 Flink 实时计算写入到多个存储模块,最终利用络绎大数据 GPS 平台进行业务出现,撑持团体多个业务零碎的风控、贷前、反欺诈等模块。GPS 每日产生总量在 40 亿左右,须要为业务方提供实时末次地位查问,近 180 日行驶轨迹查问,相似车辆轨迹比照查问,以及一些危险逾期的智能剖析等等。

三、从零碎架构的迭代看业务需要

纵观狮桥团体的产品历史,技术架构共进行过四个大版本的迭代。

阶段一

最后构建零碎时,因为工期、团队规模以及服务器资源的限度,实现上十分毛糙,仅可能实现最根本的性能。架构大略如下:

阶段一

在此模式下,咱们通过 MQ 接入厂商的数据,利用非分布式的实时计算能力传输到零碎当中,仅仅实现了实时的地位查问以及一些十分根底的性能。

阶段二

之后咱们进行了一次很大的改版,构建起了大数据集群,通过 Yarn 对立来进行资源调度,采纳分布式的形式进行实时处理,实现了弹性伸缩,同时也在做 Spark Streaming 到 Flink 的过渡。业务上,从这个版本开始咱们也接入了不同的 GPS 数据源,并且针对不同数据源的数据实现了实时切换查问,零碎的复杂度晋升较高。

与此同时,GPS 的轨迹数据在业务中开始应用,这就要求咱们必须有存储的计划,需要是实时写批量读,即能够高效插入数据的同时还可能疾速扫描大量数据。咱们最终采纳了 Kudu 进行存储,同时利用 Impala 在应用层进行 SQL 解析与减速,不便利用同学进行开发。此外,咱们还须要留存 GPS 的数据,会将其进行压缩并写入到 HDFS 中。

阶段三

随着性能的逐步减少,咱们对散落的技术点进行了一直的整合——对所有的实时计算进行了 Flink 的对立,对所有离线的计算进行了 Spark 的对立。在这个过程中,也始终在对 GPS 数据的存储进行尝试和摸索。

因为 Kudu+Impala 的模式是一个存储和解释引擎拆散的架构体系,优雅与否放在一边,更重要的是,Impala 毕竟是运行在 OLAP 平台上的解释引擎,不适宜在生产环境里做高并发的查问引擎,这违反 Impala 的设计初衷。随着不断深入的调研,咱们尝试应用 Hbase、Clickhouse 替换 Kudu。此时零碎架构演变为了计算引擎逐步固化、存储引擎一直迭代的状态。

从存储性能而言,咱们心愿可能读写兼顾、反对 SQL,同时还有正当的分区策略,这一点 Hbase 必定不能满足,因而咱们寄希望于 Clickhouse。在这个阶段中 Clickhouse 的体现的确也不错,但还是没有齐全满足需要。

阶段四

2021 年,咱们在 GPS 平台根底之上进行了协定层的开发,构建了 JT808 协定层平台,并且和原 GPS 零碎进行了买通。这样一来,咱们就能够在市场上依照协定来进行厂商的筛选,进步竞价和议价能力,晋升整个平台的效力。而在这个过程中,存储层的调研也带来了一个好消息,咱们发现了一款名为 TDengine 的时序数据库。

此前,咱们对 ClickHouse 进行了一系列的测试,尽管成果还算不错,但对于某些场景而言依然存在问题,以轨迹查问(个别是对单个车辆的轨迹进行查问)为例,尽管列式存储有着人造的劣势,但如果 HBase 的 rowkey 设计的更精美一些,那应用 Hbase 进行工夫周期的轨迹查问将会更加间接高效,然而 HBase 人造又对 SQL 十分不敌对。因而咱们始终在思考一个问题,是否有一个存储技术既能够合并读写性能,又能够符合到咱们的业务场景,且还是 SQL 原生的?

自身 GPS 的数据就相似于设施产生的数据,即时序数据,因而咱们开始基于时序数据库赛道进行了一轮筛选。因为同处 TGO“小家庭”中,Jeff 所创建的 TDengine 自然而然地走进了我的眼帘中,殊不知,这次遇见让咱们跳过了含辛茹苦,直接触碰到了时序数据库赛道的“天花板”。

四、为什么我会抉择 TDengine?

TDengine 有着十分精妙的架构设计,它是基于物联网典型业务场景和数据个性所设计和优化的优良时序数据库产品。上面我把一些感动我的优雅设计策略为大家进行下分享。

Device = Table

能够说,这个概念间接颠覆了咱们对于一般数据库的认知。无论是 ClickHouse 还是其余数据库,大都是从业务维度来构建库表,而在 TDengine 中是以采集点为单位来构建表,一个 device 就等于一个表。

对于狮桥来讲,如果咱们有 50 万辆车跑在路上,那么就须要构建出 50 万张表。乍一听,如同有点不堪设想,然而抛开固有思路,这样做的第一个长处就是解决了咱们在上述架构演变的第三阶段中心愿解决的问题,即咱们心愿一个设施在一个工夫范畴内的数据是间断存储且能够整块获取的,这样基本上剿灭了磁盘的随机拜访,相似于 Kafka 的程序读写机制,能够取得最高的效率,TDengine 在这一点上齐全解决了咱们的痛点。

同时,这个新型概念也让时序数据的写入速度有了十分大的晋升,你能够用 Kafka 的程序写入的思路去了解。

在表级别上做了“继承”

这个小标题可能不太贴切,然而它带来的成果有些相似。家喻户晓,TDengine 有个超级表的概念,通过定义超级表的标签能够归类不同的超级表,每一个超级表是一类一般表的形象汇合统称,在进行一般表的聚合操作时,通过其“继承”(或者叫做实现)的超级表进行预聚合(相似于索引查问),能够大幅晋升效率,缩小磁盘扫描。

迷信的逻辑单元划分

在 TDengine 中,所有的逻辑单元都叫做 node,在每个 node 之前加一个字母,不同的逻辑节点就诞生了:

物理节点 (Pnode),代表物理(机) 节点,艰深来说即裸金属节点
数据节点 (Dnode),代表运行实例,也是数据存储的组合单元
虚构节点 (Vnode),是真正负责数据存储与应用的最小工作单元,Vnode 组合而成 Dnode
这种划分的迷信之处就在于,数据进行分片时将 Dnode 中的 Vnode 进行扩散即可,而每一个 Vnode 中会有多个 device 的数据表,这个相似于 MongoDB 的 Sharding 的机制。依据 TDengine 的设计初衷,为了对 device 中的数据进行间断有序的存储,它会针对一个 device 进行单 Vnode 的强映射,而不会拆成多个 Vnode,这样就防止了因数据散落在不同地位(物理节点)还须要通过网络 merge 的问题,最大水平上晋升了效率。

在 TDengine 中,利用的是 Vgroup 的机制保证数据的正本高牢靠,这块能够进入 TDengine 官网参看文档,写的十分分明。总而言之,这些职能划分和逻辑设计使得 TDengine 既能够满足高牢靠,又可能对 device 级别吞吐提供读写数据需要。当然,具体有多强,大家能够参看压测比照,也能够本人尝试一下。

Mnode 的两个精妙之处

在下面的解释中,我特意避开了 Mnode 的阐明,上面我要独自解说。

从逻辑意义上了解 Mnode 很简略,就是 Meta Data 的管理者,在很多中间件中都有这个角色,比方 Hadoop 的 NameNode、Kafka 中通过 Zookeeper 保留的 Metadata 信息。然而 TDengine 的 Mnode 有两个性能十分奇妙。

Mnode 是幽灵般的存在,到底在哪一个 Dnode 上都是零碎主动实现的,用户无奈抉择。当用户须要拜访 TDengine 的集群时,必定要先晓得 Mnode 在哪里,继而能力通过 Mnode 来获取集群信息和数据,这个过程是通过 taosc(client 模块)进行拜访的。设计的精妙之处在于,这个过程中你间接拜访集群中的任何一个 Dnode 都能够获取到 Mnode 的信息,从而免去了从一个 metadata center 中去获取元数据。这种设计策略在 ES 和新版的 Kafka 中都在应用,用一句话形容就是模式下来中心化的元数据存储与获取机制,在这一点的架构设计上,TDengine 走在了时代的前列。

其次,Mnode 能够帮忙监控 Dnode 的负载状况,一旦遇到 Dnode 负载压力高、数据存储热点散布不平衡的场景,Mnode 能够帮忙转移 Dnode 的数据,从而打消歪斜。值得一提的是,在这个过程中,对外服务是不会进行的。

五、咱们在 TDengine 上的实际

轨迹数据存储与查问

鉴于 TDengine 的个性,用它来存储轨迹数据十分适合。咱们在 JT808 协定平台后挂上了 Kafka,通过 Flink 间接把数据写入到了 TDengine 中。在和 TDengine 的小伙伴进行探讨与优化的过程中,咱们惊奇地发现,TDengine 写入时的 driver 多采纳堆外内存的读写策略,对数据缓存和写入做了极大的优化,写入效率十分高。

接入 TDengine 后流程

在数据查问上,因为 TDengine 人造反对 SQL,利用开发同学的学习老本出现几何级的降落,极大地晋升了开发效率。对他们来说,数据不论是存在 MySQL 还是 Oracle 抑或是 TDengine 都是齐全通明的。

末次地位查问

此前,咱们须要应用 Flink 把数据打入到 Redis 集群中,进行末次地位的存储与查问。而 TDengine 中的“最新热数据缓存”的策略恰好符合到了咱们的需要,Redis 集群就能够间接省略了。当咱们钻研到这个性能时,几乎热泪盈眶——这不是针对某一个业务的帮忙,而是在对一整个行业进行了透彻的洞察之后所设计进去的灵魂级的性能。

大家都晓得 LRU,这种治理缓存策略的初衷是,咱们不晓得数据以何种形式进入到零碎中,只能用随机与无序来定义数据,通过 LRU 的机制能够筛选出将来可能会被应用的数据来进行缓存,用“猜测”的形式来提供查问减速。

而 TDengine 自身就是为 IoT 而生,它洞察到了时序数据的个性,从而采纳以工夫程序来设计的 FIFO 来定义缓存的策略,即陈腐的数据会落在缓存中,不便企业查问最新产生的热数据。依附着这个设计,咱们只须要一个简略的 SQL 即可从内存中以最快速度获取想要的数据,此时 TDengine 摇身一变,就成为了一个反对 SQL 的内存数据库。在部署了 TDengine 之后,咱们下线了一整套的末次地位 Redis 集群。

自动化的分区与数据保留策略

上文中咱们讲到过 TDengine 的分片机制,那分区又是如何做到的?在咱们应用时发现,TDengine 能够设置 days 的参数进行数据存储,以工夫范畴对数据进行分区。简略来说,咱们的场景是搜寻过来 180 天内的轨迹数据,然而更多的场景都是以月的纬度来搜寻,那咱们咱们能够把 days 设置成 30,这样数据就是以每个月分块,搜寻的时候也是整体捞出,效率十分高。

而超过 180 天的数据,咱们不会去进行展现搜寻,因为数据在 HDFS 上还有压缩的存储,所以咱们通过 TDengine 的 keep 参数来设置数据保留多久,即设置 keep=180,这样超过 180 天的数据会被主动革除,对存储极为敌对。

应用 TDengine 后的成果

从时序数据量大的特点登程,TDengine 有着一系列十分高效的压缩伎俩。大家可能都晓得 ES 中的 FOR 或者 RBM 等压缩算法,我猜测 TDengine 中应该也应用了相似的压缩形式,使得整体数据笨重且有序。

利用 TDengine 后,咱们整体数据存储缩减超过 60% 以上,集群更是指数级的下线——末次地位查问的 Redis、轨迹查问的 Hbase 集群个体下掉、Clickhouse 也不再用作轨迹存储,把裸金属用在了更须要蛮力干活的中央。目前 TDengine 在“降本”方面给予了咱们微小的帮忙,置信将来在其助力下,咱们也会在“增效”的路线上越走越远。

六、写在最初

从我的感触来讲,TDengine 是一家年老有生机的企业,工程师文化十分浓重。我很喜爱和 Jeff 探讨技术,每每看到他拿出笔记本关上 IDE 看每一行的源代码时,我就越发感觉咱们应该重新认识程序员这个职业,平凡的不仅仅是那些商业首领,更多的是用一行行代码来扭转世界、怀揣着幻想却又求实的人们。

心愿 TDengine 将来能多举办一些 Meetup 来进行更多的交换,也能够做一些 Best Practice 的解说。在一些语言与中间件上,间接出一些简略的 Showcase,便于大家上手实际,一起来见证这个时代最好的时序数据库的成长。

作者简介

杨路,前狮桥团体大数据团队负责人,深耕大数据平台架构与三高利用平台建设,规范技术控一枚。InfoQ 连载《大画 Spark》作者。


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

退出移动版