在 OPPO 的穿戴产品的手环/手表类业务中,产生的数据类型为时序数据,具有写入量巨大且存在离线/历史数据补录(更新)的处理需求。此前使用的 MongoDB/MySQL 集群方案,后端存储压力较大,需要经常扩盘,针对此痛点,OPPO 云计算中心智慧物联云团队尝试调研对比了几款时序数据库(Time-Series Database)产品,试图寻找一个降本增效的解决方案。

除了存储压力外,我们进行数据库替换还有一个比较重要的原因,就是 MySQL 和 MongoDB 的各个集群都比较独立,维护和需求开发成本相对较高。

以上是三款 Database 的初步调研结果,TSHouse 是 OPPO 云监控时序数据库,其底层为 Prometheus 的 TSDB 存储引擎,目前不支持历史数据和乱序写入;InfluxDB 对历史数据写入会进行二次压缩,影响性能,这两款数据库都不满足当下的数据处理需求。初步研究 TDengine 后,我们发现其作为国产时序数据库开源产品,不仅可以满足历史数据高效写入,还拥有较高的压缩能力。随后,我们选择对 TDengine 进行了比较详细的产品调研和性能测试。

TDengine 产品与能力调研

产品调研

某个数据表的结构如下:

我们写入 60 万行数据,到 MySQL(目前部分业务部署在 MySQL 集群)和 TDengine 的 4C 12G 容器上,对 CPU/内存/磁盘进行观察。测试发现 CPU 和内存消耗基本持平的情况下,TDengine 的落盘数据是 MySQL 环境的1/4左右。

同时,我们在不同规格容器及物理机场景下进行 TDengine 写入测试,部分记录如下:

需要说明的是,对于不同业务场景需要进行实际测试,才能确定适合该业务的部署参数。在整个测试过程中,TDengine 工程师们也为我们进行了及时答疑和帮助。

能力调研

随后我们根据 TDengine 丰富的产品手册,对一些关键能力进行了验证,包括数据管理、数据写入、聚合计算、集群扩容、故障可靠性保证等场景。

在数据管理上,TDengine 的元数据与业务数据是分离开来的。如下图所示,Mnode 负责管理元数据信息;单个 Vnode 可以存放多个表数据,相当于相当于水平分片,单个表的数据,又可以继续按照日期分片。

在数据写入逻辑上,整体和 LSM 类似:WAL,内存块,磁盘 FILE。

在 TDengine 中,数据在文件中是按块连续存储的。每个数据块只包含一张表的数据,且数据是按照时间主键递增排列的。数据在数据块中按列存储,这样使得同类型的数据能够存放在一起,大大提高了压缩比,节省了存储空间。

TDengine 是 10 天一组 data file,data file 里的 .data 文件只进行追加,且后续不会进行压缩。这种好处是:对历史数据和乱序极其友好,非常适用于 IoT 场景;没有压缩也就减少了写入之后的资源消耗,保证了较好的读写性能。

TDengine落地实践

在经历了比较充分调研后,我们根据业务写入模型,对生产环境中某一套 MySQL 集群环境,进行 TDengine 集群部署,搭建了如下所示的集群:

集群为 3 台 AWS-EC2 容器(8C 32GB 3.5TB NVME 盘)组成,配置为 3 节点、2 副本,写入端使用 RESTful 请求到 VIP 节点,转发到数据库服务。图中的 V0-V2 为副本数为 2 的 3 组数据分片,M0-M2 为副本数为 3 的 1 组管理节点。

配置的 Grafana 面板展示如下:

后台表结构展示如下:

目前数据已经开始接入 TDengine 的数据库,历史数据也在同步导入中。

实际效果展示

1.使用 last_row() 函数一次性输出 38 万个设备查询最新状态,结果如下所示。

2.使用 interval() 查询某个设备每 1 小时的总步数,结果如下所示。

在存储方面,由于目前数据还没有完全导入,针对生产环境的一个 6.6TB 集群,我们粗略估计了一下前后的压缩比,大概在 6.6/0.4。

在我们原来的集群中是没有副本的,单纯就部署了 MySQL 的 5 个分库,使用了 4C 8GB 2TB 的 5 台机器,在应用 TDengine 之后,现在是 8C 32GB 2TB 的 3 台机器。通过 TDengine 我们构建了多副本和统一的能力,以及后续上混合云的能力,这是整个平台级的一个优化与提升。

写在最后

在前期调研和集群搭建过程中,TDengine Database 的工程师伙伴们给我们提供了充分且及时的协助,为我们构建时序数据后端能力提供了很大帮助。目前接入TDengine的数据是海外某集群,后续我们会根据业务进展陆续进行其他集群数据的接入。

推荐内容