基于 TSBS 标准数据集时序数据库 TimescaleDB、InfluxDB 与 TDengine 的性能对比测试

基于 TSBS 标准数据集时序数据库 TimescaleDB、InfluxDB 与 TDengine 的性能对比测试

基于 TSBS 标准数据集,TDengine Database 团队对时序数据库Time Series DatabaseTSDB) InfluxDB, TimescaleDB 和 TDengine 针对 TSBS 指定的 DevOps 中 cpu-only 五个场景进行了对比测试。

在 TSBS 全部的 cpu-only 五个场景中,TDengine 写入性能均优于 TimescaleDB 和 InfluxDB。相对于 TimescaleDB, TDengine 写入速度最领先的场景是其 6.7 倍(场景二),最少也是 1.5 倍(场景五),而且对于场景四,如果将每个采集点的记录条数由 18 条增加到 576 条,TDengine 写入速度是 TimescaleDB的 13.2 倍。相对于 InfluxDB,TDengine 写入速度最领先的场景是其 10.6 倍(场景五),最少也是 3.0 倍(场景一)。此外,TDengine 在写入过程中消耗了最少 CPU 资源和磁盘 IO 开销。

磁盘空间占用方面,TimescaleDB  在所有五个场景下的数据规模均显著大于 InfluxDB 和 TDengine,并且这种差距随着数据规模增加快速变大。TimescaleDB 在场景四和场景五中占用磁盘空间是 TDengine 的 25.6 倍和 26.9 倍。在前面三个场景中,InfluxDB 落盘后数据文件规模与 TDengine 非常接近,但是在大数据规模的场景四和场景五中,InfluxDB 落盘后文件占用的磁盘空间是 TDengine 的 4.2 倍和 4.5 倍。

查询方面,在场景一(只包含 4 天的数据)与场景二的 15 个不同类型的查询中,TDengine 的查询平均响应时间全面优于 InfluxDB 和 TimescaleDB,而且在复杂查询上优势更为明显,同时具有最小的计算资源开销。相对于 InfluxDB,场景一,TDengine查询性能是其 1.9 ~ 37.0 倍,平均 11.3 倍,场景二,TDengine 查询性能是其 1.8 ~ 34.2 倍,平均是 11.3 倍。相对于 TimeScaleDB,场景一,TDengine 查询性能是其 1.1 ~ 28.6 倍,平均 7.6 倍,场景二,TDengine查询性能是其 1.2 ~ 24.6 倍,平均 7.7 倍。 

本测试报告中的数据在准备好物理环境后,可以由脚本一键执行生成。

点击这里,下载完整对比测试报告。

一、背景介绍

1.1 性能基准对比框架

Time Series Benchmark Suite (TSBS) 是 Timescale [1]开源,集多种应用场景下时序数据生成、数据写入、查询处理、自动化结果汇总统计等功能于一体的时序数据(Time Series Data)性能基准测评平台。TSBS 提供 IoT、DevOps 两个典型应用场景,具有简单、易用、扩展性优异等特点。由于 TSBS 是一个开源的平台,因此得到了 InfluxDB、TimescaleDB、QuestDB、ClickHouse 等众多数据库系统的广泛支持,并被多家数据库厂商使用,作为基准性能测评平台。

早在 2018 年,VictoriaMetrics 的创始人 Aliaksandr Valialkin 就基于 TSBS 框架发布 VictoriaMetrics 与 Timescale 和 InfluxDB 的性能对比报告[2]。2018 年 11 月,文章《ClickHouse Crushing Time Series》[3]《ClickHouse Continues to Crush Time Series》[4]对比 TimescaleDB, InfluxDB, ClickHouse 在时序数据场景下进行了性能。2020年 3 月 Cloudera 的网站博客中发布了基于 TSBS 框架,在DevOps场景的性能测评对比报告,对比了Apache Kudu, InfluxDB,  VictoriaMetrics, ClickHouse 等数据库产品在该时序场景下的性能表现[5]。同一个月,Redis发布了基于 TSBS 的性能报告《RedisTimeSeries Version 1.2 Benchmarks》[6],同年8 月,Timescale 在其官方博客中给出了基于此框架平台的性能基准对比报告《TimescaleDB vs. InfluxDB: Purpose Built Differently for Time-Series Data》[7],在该报告中 Timescale 提供了其核心产品 TimescaleDB 和 InfluxDB 基于 TSBS 框架的性能测评报告。2021年 8 月,QuestDB 发布了QuestDB与 TimescaleDB 的性能对比报告——《QuestDB vs. TimescaleDB》[8]。从上述众多的对比报告,不论是时间跨度还是发布的厂商来看,TSBS 作为基准测试平台具有相当高的认可度。

为了客观、准确、可验证地评估 TDengine Ver3.0 的性能表现,我们也选用了 TSBS 框架作为性能基准对比平台,作为横向对比的产品,我们选择了 TimescaleDB 和  InfluxDB 进行对比。请参见 GitHub – timescale/tsbs [9]获得关于该框架的详细介绍和相关信息。

1.2 测试场景介绍

我们使用了 DevOps 场景中的 cpu-only 作为基础数据集。TSBS 框架中 cpu-only 场景模拟对服务器 CPU 监控生成的时序数据,针对每个设备( CPU)记录其 10 个测量值,1个(纳秒分辨率)时间戳,10 个标签值。具体的内容和示例数据见下表 1,生成的数据每 10 秒一条记录。数据模式(schema)见下图 1。其中每条记录包含了 10 个标签(tags)和 1 个时间戳 及 10 个测量值(metric)。

时序数据库-TDengine Database
图 1. 样例数据

在整个基准性能评估中,涉及以下五个场景,每个场景的具体数据规模和特点见下表 1:

表 1. 场景数据集说明
场景一
100 devices × 10 metrics
场景二
4,000 devices × 10 metrics
场景三
100,000 devices × 10 metrics
场景四
1,000,000 devices × 10 metrics
场景五
10,000,000 devices × 10 metrics
设备数目 100 4000 100,000 1,000,000 10,000,000
持续时间 31 天 4 天 3 小时 3 分钟 3 分钟
数据间隔 10 秒 10 秒 10 秒 10 秒 10 秒
单个设备记录数 267,840 34,560 1,080 18 18
数据集记录数 26,784,000 138,240,000 108,000,000 18,000,000 180,000,000

可以看到,五个场景的区别主要在于数据集所包含的设备记录数量,设备数的差异。数据时间间隔均维持在 10 sec。整体上看,五个场景的数据规模都不大,数据规模最大的是场景五,数据规模最小的场景四只有 18,000,000 条记录。在场景四和场景五中,由于设备数量相对较多,所以数据集仅覆盖了 3 分钟的时间跨度。

1.3 数据建模

在 TSBS 框架中, TimescaleDB 和 InfluxDB 会自动创建相应的数据模型并生成对应格式的数据。本文不再赘述其具体的数据建模方式,只介绍 TDengine 的数据建模的策略。

TDengine 一个重要的创新是其独特的数据模型——为每个设备创建独立的数据表(子表),并通过超级表(Super Table)在逻辑上和语义上对同一采集类型的设备进行统一管理。针对 DevOps 场景的数据内容,我们为每个设备 (这里是 CPU)创建了一个表,用以存储该表的时序数据。在 1.2 章节数据记录中,我们看到 hostname 可以作为每个设备的标识 Id , 因此我们在 TDengine 中使用 hostname 作为子表的名称。我们使用如下的语句创建名为 CPU 的超级表,包含 10 个测量值和 10 个标签。

create stable cpu (ts timestamp,usage_user bigint,usage_system bigint,usage_idle bigint,usage_nice bigint,usage_iowait bigint,usage_irq bigint,usage_softirq bigint,usage_steal bigint,usage_guest bigint,usage_guest_nice bigint)
tags (hostname varchar(30), region varchar(30),datacenter varchar(30),rack varchar(30),os varchar(30),arch varchar(30),team varchar(30),service varchar(30),service_version varchar(30),service_environment varchar(30))

然后 ,我们使用如下语句创建名为 host_0 的子表:

create table host_0 using cpu (hostname,region,datacenter,rack,os,arch,team,service,service_version,service_environment)
tags ('host_0','eu-central-1','eu-central-1a','6','Ubuntu15.10','x86','SF','19','1','test')

上述语句创建了一个子表。由此可知,对于 100 个设备(CPU)的场景 一,我们将会建立 100 个子表。对于 4000  个设备的场景二,系统中将会建立 4000 个子表用以存储各自对应的数据 。

1.4 软件版本和配置

本报告仅比较 TDengine、InfluxDB 与 TimeScaleDB,下面对使用的版本和配置做出说明。

1.4.1 TDengine

我们直接采用 TDengine Ver3.0,从 GitHub 克隆 TDengine 代码编译版本作为性能对比的版本。

gitinfo: c90e2aa791ceb62542f6ecffe7bd715165f181e8

在服务器上编译安装运行。

cmake .. -DDISABLE_ASSERT=true -DSIMD_SUPPORT=true -DCMAKE_BUILD_TYPE=Release  -DBUILD_TOOLS=false
make -j  && make install

在TDengine的配置文件中设置了四个涉及查询的配置参数。

numOfVnodeFetchThreads           4

queryRspPolicy                   1

compressMsgSize             128000

SIMD-builtins                    1

第一个参数 numOfVnodeFetchThreads 设置 Vnode 的Fetch 线程数量为 4 个, 第二个参数 queryRspPolicy 打开  query response 快速返回机制, 第三个参数 compressMsgSize 让TDengine 在传输层上大于 128,000 bytes的消息自动进行压缩,第四个参数是如果 CPU 支持,启用内置的 FMA/AVX/AVX2 硬件加速。

如上所述,TDengine 建库默认创建 6 个 vnodes,即创建的表会按照表名随机分配到 6 个 虚拟节点(virtual node, VNode) 中。打开 LRU 缓存,设置为 last_row 缓存模式。对于场景一和场景二,stt_trigger 设置为 1,此时 TDengine 会准备一个 Sorted Time-series Table (STT) 文件,用于容纳单表写入量小于 minimum rows 的时候,数据直接保存在 STT 文件中,当 STT 文件中无法容纳新数据的时候,会将 STT 中的数据整理,再写入到数据文件中。对于其他的场景(场景三、四、五),stt_trigger 设置为 8,即允许最多生成 8 个 STT 文件。针对表较多的场景,需要适度增加 STT 的值,以此来获得更好的写入性能。

1.4.2 TimescaleDB 

为确保结果具有可比性,我们选用 TimescaleDB 版本 version 2.6.0。为获得较好的性能,TimescaleDB 需要针对不同的场景设置不同的 Chunk 参数,不同场景下参数的设置如下表所示。

表 2. 不同场景下 TimescaleDB 的 chunk 配置
场景一 场景二 场景三 场景四 场景五
设备数目 100 4000 100,000 1,000,000 10,000,000
Chunk 数目 12 12 12 12 12
Chunk 持续时间 2.58 天 8 小时 15 分 15 秒 15 秒
Chunk 内记录数 2,232,000 11,520,000 9,000,000 1,500,000 15,000,000

上述参数的设置,充分参考了对比报告[7]中推荐的配置参数设置,以确保能够最大化写入性能指标。

1.4.3 InfluxDB

我们选择 InfluxDB version 1.8.10。这里没有使用 InfluxDB 最新的 2.x 版本是因为 TSBS 没有对其进行适配,所以选用了能够运行 TSBS 框架的 InfluxDB 最新版本。

我们采用对比报告[7]中推荐的方式配置 InfluxDB,将缓冲区配置为 80G,以便 1000w 设备写入时能够顺利进行,同时开启 Time Series Index(TSI)。

配置系统在系统插入数据完成 30s 后开始数据压缩。

cache-max-memory-size = "80g"
max-values-per-tag = 0
index-version = "tsi1"
compact-full-write-cold-duration = "30s"

二、测试步骤

2.1 硬件准备

为与对比报告[7]的环境高度接近,我们使用亚马逊 AWS 的 EC2 提供的 r4.8xlarge 类型实例作为基础运行平台,包括 1 台服务器、1 台客户端共两个节点构成的环境。客户端与服务器硬件配置完全相同,客户端与服务器使用 10 Gbps 网络连接。配置简表如下:

表 3. 物理节点配置
CPU Memory Disk
服务器 Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz 32vCPU 244GiB 800G SSD,3000 IOPS. 吞吐量上限是 125 MiB/Sec
客户端 Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz 32vCPU 244GiB 800G SSD,3000 IOPS. 吞吐量上限是 125 MiB/Sec

2.2 服务器环境准备

为运行测试脚本,服务器OS需要是ubuntu20以上的系统。AWS EC2的服务器系统信息如下:

  1. OS: Linux tv5931 5.15.0-1028-aws #32~20.04.1-Ubuntu SMP Mon Jan 9 18:02:08 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
  2. Gcc:gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04)
  3. 基础环境,版本信息为:Go1.16.9 , python3.8 , pip20.0.2 (无需手动安装,测试脚本将自动安装) 
  4. 编译依赖:gcc , cmake, build-essential, git, libssl-dev (无需手动安装,测试脚本将自动安装)

但请做两个配置:

  1. client和 server配置ssh 访问免密,以便脚本可不暴露密码,可参考文档:免密配置
  2. 保证client 和 server 之间所有端口开放。

2.3 获取测试脚本

为便于重复测试,隐藏繁琐的下载、安装、配置、启动、汇总结果等细节,整个 TSBS 的测试过程被封装成一个测试脚本。重复本测试报告,需要先下载该测试脚本,脚本暂支持 ubuntu20 以上的系统。以下操作要求具有 root 权限。

1. 在客户端机器,进入测试目录拉取代码,默认进入 /usr/local/src/ 目录,

cd /usr/local/src/ && apt install git && git clone https://github.com/taosdata/tsbs.git && cd tsbs/scripts/tsdbComp 

2. 修改配置文件 test.ini 中服务端和客户端的 IP 地址(这里配置 AWS 的私网地址即可)和 hostname,如果服务器未配置免密,还需要配置服务器端的 root 密码。

clientIP="192.168.0.203"   #client ip
clientHost="trd03"         #client hostname
serverIP="192.168.0.204"   #server ip
serverHost="trd04"         #server hostname
serverPass="taosdata123"   #server root password

2.4 一键执行对比测试

执行以下命令:

nohup bash tsdbComparison.sh > test.log &

测试脚本将自动安装 TDengine, InfluxDB, TimeScaleDB 等软件,并自动运行各种对比测试项。在目前的硬件配置下,整个测试跑完需要大约一天半的时间。测试结束后,将自动生成 CSV 格式的对比测试报告,并存放在客户端的 /data2 目录。

三、写入性能对比

3.1 不同场景下写入性能对比

TDengine Database
图 2. 不同场景下写入性能的对比(metrics/sec. 数值越大越好)

可以看到在全部五个场景中,TDengine 的写入性能全面超越 TimescaleDB 和 InfluxDB。在场景二中 TDengine 写入性能是 TimescaleDB 的最大达到 6.74 倍,在差距最小场景五中,是 TimescaleDB 写入性能的 1.52 倍。相对于 InfluxDB,TDengine 在场景五中写入性能是 InfluxDB 的 10.63 倍,在差距最小的场景一中也有 3.01 倍,具体的倍率关系请参见表 4。

我们还注意到,随着设备数规模的增加,所有系统写入基本上呈现下降趋势。TimescaleDB 在小规模数据情况下写入性能不及 InfluxDB,但是随着设备数量的增加,其写入性能超过了 InfluxDB,这点上与对比报告[7]中的结论一致。

表 4. TDengine 相对于 InfluxDB 与 TimescaleDB  写入性能
TDengine/InfluxDB TDengine/TimescaleDB
100 devices × 10 metrics 301.41% 585.63%
4,000 devices × 10 metrics 489.69% 674.12%
100,000 devices × 10 metrics 451.25% 554.07%
1,000,000 devices × 10 metrics 735.38% 286.46%
10,000,000 devices × 10 metrics 1063.46% 152.16%

3.2 写入过程资源消耗对比

数据写入速度并不能够全面的反映三个系统在不同场景下数据写入的整体表现。为此我们以 1,000,000 devices × 10  metrics (场景 四)为例,检查数据写入过程中的服务器和客户端(包括客户端与服务器)的整体负载状况,并以此来对比三个系统在写入过程中服务器/客户端节点的资源占用情况,这里的资源占用主要包括服务器端的 CPU 开销/磁盘 IO 开销和客户端 CPU 开销。

3.2.1 服务端 CPU 开销

图 3 展示了在场景四写入过程之中服务器端 CPU 负载状况。可以看到,三个系统在返回给客户端写入完成消息以后,都还继续使用服务器的资源 进行相应的处理工作,这点上,TimescaleDB 尤为明显,TimescaleDB 在 7X 秒的时候即反馈客户端写入完成,但是其服务器端仍然调用 CPU 资源进行了数据压缩和整理工作,当然整个工作带来的 CPU 负载相对而言并不高,只有其峰值 CPU 开销的一半左右,但是其持续时间相当长,接近其净写入时间的 4 倍。InfluxDB 则使用相当多的 CPU 资源,瞬时峰值使用了全部的 CPU 资源,其写入负载较高,并且其持续时间比 TimescaleDB 更长,当然远长于 TDengine。三个系统对比,TDengine 对服务器的 CPU 需求最小,峰值也仅使用了 17% 左右的服务器 CPU 资源。由此可见,TDengine 独特的数据模型对于时序数据写入不仅在性能上,在整体的资源开销上也具有非常大的优势。

TDengine Database
图 3. 写入过程中服务器 CPU 开销

3.2.2 磁盘 I/O 对比

图 4 展示了 1,000,000 devices × 10  metrics (场景四)数据写入过程中服务器端磁盘写入状态。可以看到,结合着服务器端 CPU 开销表现,其 IO 动作与 CPU 呈现同步的活跃状态。

写入相同规模的数据集,TDengine 在写入过程中对于磁盘写入能力的占用远小于 TimescaleDB 和 InfluxDB,写入过程只占用了部分磁盘写入能力(125MiB/Sec.  3000IOPS)。从图上能看到,数据写入过程中磁盘的 IO 瓶颈是确实存在的。InfluxDB 长时间消耗完全部的磁盘写入能力,TimescaleDB 写入过程对于写入的消耗相对 InfluxDB 来说要更具优势,但是仍然远超过了 TDengine 对磁盘写入能力的需求。

TDengine Database
图 4. 写入过程中服务器IO开销

3.2.3 客户端 CPU 开销

TDengine Database
图 5. 写入过程中客户端 CPU 开销

从图 5 可以看到,客户端上 TDengine 对 CPU 的需求大于 TimescaleDB 和 InfluxDB, 而 InfluxDB 在整个写入过程中,客户端负载整体上来说,三个系统中计算资源占用最低,对客户端压力最小,其写入的压力基本上完全集中在服务端。这种模式很容易导致服务端成为瓶颈,TimescaleDB 相对于 InfluxDB 而言,对于客户端压力更大,CPU 峰值达到 17% 左右。TDengine 在客户端的开销最大,峰值瞬间达到了 56%,然后快速回落。TDengine 在客户端的开销相比于 TimescaleDB 多了1倍。综合服务器与客户端的资源开销来看,TDengine 写入持续时间更短,在系统整体 CPU 开销上 TDengine 仍然具有相当大的优势。

3.3 写入性能对比总结

在全部的场景中,写入性能超过TimescaleDB 和 InfluxDB。在整个写入过程中,TDengine 在提供了更高的写入能力的前提下,不论是服务器的CPU 还是 IO,TDengine 均远优于 TimescaleDB 和 InfluxDB。对于服务器的磁盘IO开销远小于 TimescaleDB 和  InfluxDB。即使加上客户端的开销统计,TDengine 在写入开销上远优于 TimescaleDB 和 InfluxDB。

3.4 磁盘空间占用

三个系统数据完全落盘以后,比较了三个系统在不同场景下的磁盘空间占用比较。

TDengine Database
图 6. 磁盘空间占用(数值越小越优)

可以看到,TimescaleDB 在所有的场景下数据规模均显著地大于 InfluxDB 和 TDengine,并且这种差距随着数据规模增加快速变大。TimescaleDB 在场景四和场景五中占用磁盘空间是 TDengine 的 25 倍。在前面三个场景中,InfluxDB 落盘后数据文件规模与 TDengine 非常接近(在场景二中,TDengine 的数据落盘规模比 InfluxDB 大了 1%)。但是在场景四/五两个场景中,InfluxDB 落盘后文件占用的磁盘空间是 TDengine 的 4 倍以上。

3.5 性能基准评估扩展部分

为了更全面地评估 TDengine 在默认参数下写入性能,我们在下面的性能评估中调整可能会影响写入性能的多个参数,进行全面的评估。

3.5.1 虚拟节点(vnodes)数量

我们调整数据库中虚拟节点数量(默认是 6)为6, 8, 12, 24,并衡量不同 vnode 数量情况下 TDengine 写入性能。

表 5. 不同虚拟节点数据量情况写入性能变化
scale=100
场景一
scale=4,000
场景二
scale=100,000
场景三
scale=1,000,000
场景四
scale=10,000,000
场景五
vnodes=6 12,505,486.02 100.0% 12,406,329.61 100.0% 7,385,493.05 100.0% 4,187,062.00 100.0% 1,920,218.77 100.0%
vnodes=12 13,700,149.95 109.6% 12,465,158.96 100.5% 7,659,621.20 103.7% 4,259,048.47 101.7% 3,212,637.82 167.3%
vnodes=18 12,513,161.38 100.1% 12,692,162.63 102.3% 7,596,867.61 102.9% 4,307,592.41 102.8% 3,471,004.33 180.7%
vnodes=24 13,700,149.95 109.6% 12,465,158.96 100.5% 7,659,621.20 103.7% 4,391,547.13 104.8% 3,936,532.14 205.0%

我们看到,在设备数最小的场景一 ,随着虚拟节点数的增加,写入变化趋势不明显。在较多的设备的场景(场景五)中,增加 vnodes 的数量 ,写入性能获得了显著的提升。可见在不同规模的场景中,可以通过调整虚拟节点的数量来获得更好的写入性能。在大规模的场景中,增加 vnodes 的数量可以获得显著的性能提升。

3.5.2 fsync 对写入性能的影响

数据库的 fsync 参数控制写入到预写日志(write ahead log, WAL)文件中的数据调用 fsync 的频率, 以确保数据可靠落盘。调用 fsync 会消耗较多的 IO 资源,并会对写入过程带来一定的影响。从下表看到,fsync 的配置对 TDengine 写入性能影响很小。

在前面的四个场景中我们看到在 fsync 配置为实时同步刷入磁盘(fsync 为 0)的时候,写入性能并没有出现显著的降低,是由于写入过程采用了大批量的写入模式,降低了每次刷入磁盘的次数需求,所以对性能影响并不明显,如果降低每批次写入的数据量,应该能看到写入性能降低,因此 ,增加每批次写入数据量,可以有效缓解 fsync 配置写入的影响。

表 6. 不同 fsync 配置下写入性能趋势
TDengine写入速度(metrics/sec.) scale=100 scale=4,000 scale=100,000 scale=1,000,000 scale=10,000,000
fysnc=0ms 12,530,045 12,176,290 7,566,922 4,199,325 2,041,612
fsync=200ms 12,842,668 12,477,106 7,681,030 4,264,758 1,974,915
fsync=3,000ms 12,505,486 12,406,330 7,385,493 4,123,547 1,968,498

3.5.3 设备记录数量

TDengine 为一个设备一张表的数据模型,需要在数据写入时创建表,建表操作对每个设备只执行一次,但这使得 TDengine 在数据写入的准备阶段时间耗时较多。当单个表中数据量增加以后 ,数据准备(建表)的开销被分摊到更多的数据写入的整体开销中,所以应该有更好的数据写入性能。以场景四(1,000,000 devices × 10  metrics)为例,单个设备的数据量仅有 18 条。当我们调整参数,将单个设备记录数据增加到 36 、72 、144 条时,整体写入时间更长,因此表现出来就是建表开销被分摊到更多的数据写入过程中,建表的开销相对于数据写入的耗时占比越来越小,相应的整体写入速度也越来越快。因此可以看到,TDengine 表现出了更加明显的写入优势。

TDengine Database
图 7. 设备记录数增加时候数据写入性能对比(数值越大越好)

我们调整 vnodes 数量配置,同时测试两个不同 vnodes 数量情况下的写入性能指标。如图 7 所示,随着表中记录数的增加,单表记录增加到72 的时候,TDengine 设置为 6 vnodes 的写入性能出现了下降,但是在 24 vnodes 的情况下,写入性能呈现出持续增加的趋势,并且全部场景下写入性能均优于 6 vnodes 的写入性能。当设备记录数达到 576 行(此时数据集规模1,000,000 × 576 = 5.76 亿行数据记录)的时候,写入性能达到 6,605,515 metrics/sec. 。不论是默认的 6 vnodes,还是 24 vnodes,在单设备记录达到 576 行的时候,默认 6 vnodes 配置下 TDengine 写入性能是 TimescaleDB 和 InfluxDB 的 7 倍多,当设置为 24 vnodes 的时候,性能更是达到其 均大幅领先 TimescaleDB 与 InfluxDB,最高达到了 TimescaleDB 和 InfluxDB 的 13 倍多。

TimescaleDB 写入性能在单表记录数量大于 72 行的时候就出现了下降趋势,在单表记录数 144 行以后出现了快速衰减。InfluxDB 在单设备记录增加过程中,写入性能有衰减,但衰减趋势非常缓慢。

3.5.4 总结

通过调整不同的参数,以及设置不同的数据规模(增加每个设备包含记录数)、调整 fsync 参数等方式,我们在更多的方面评估了 TDengine 在 TSBS 基准数据集上的写入性能。通过这一系列深入的对比可以看到,针对更大规模(设备数量和每个设备记录数量)数据集,TDengine 可以通过简单调整虚拟节点数量的方式,获得更高的写入性能,并且 TDengine 在针对大数据集写入场景下展现出更好的性能优势,同时具有远低于 TimescaleDB 和 InfluxDB 对服务端资源(服务器 CPU 和 磁盘 IO、内存等)的开销。

四、查询性能对比

在查询性能评估部分,我们使用场景一(只包含 4 天数据,这个修改与[7]中要求一致)和场景二作为基准数据集,具体基础数据集的特点,请参加本文前面 1.2 章节。在查询性能评估之前,对于 TimescaleDB, 我们采用[7]中推荐配置,设置为 8 个 Chunk ,以确保其充分发挥查询性能。对于 InfluxDB,我们开启 InfluxDB  的 TSI (time series index)。在整个查询对比中,TDengine 数据库的虚拟节点数量(vnodes)保持为默认的 6 个,其他的数据库参数配置为默认值。

4.1 4,000 devices × 10 metrics查询性能对比

由于部分类型(分类标准参见[7] )单次查询响应时间非常短,为了更加准确地测量每个查询场景的较为稳定的响应时间,我们将单个查询运行次数提升到 5,000 次,然后使用  TSBS 自动统计并输出结果,最后结果是 5,000 次查询的算数平均值,使用并发客户端 Workers 数量为 8。首先我们提供场景二 (4,000 设备)的查询性能对比结果。

表 7. 4,000 devices × 10 metrics(场景二)查询性能对比表(单位: ms)
查询分类  TDengine InfluxDB InfluxDB/TDengine TimescaleDB TimescaleDB/TDengine
Simple Rollups single-groupby-1-1-1 0.94 1.71 181.91% 3.27 347.87%
single-groupby-1-1-12 1.92 9.40 489.58% 5.07 264.06%
single-groupby-1-8-1 2.09 4.10 196.17% 4.56 218.18%
single-groupby-5-1-1 1.08 4.40 407.41% 3.34 309.26%
single-groupby-5-1-12 3.00 36.43 1214.33% 7.02 234.00%
single-groupby-5-8-1 2.60 13.58 522.31% 9.6 369.23%
Aggregates cpu-max-all-1 1.30 5.86 450.77% 5.54 426.15%
cpu-max-all-8 3.36 20.64 614.29% 23.72 705.95%
Double-Rollups double-groupby-1 266.69 2,785.23 1044.37% 5467.91 2050.29%
double-groupby-5 446.23 11,702.49 2622.52% 10984.63 2461.65%
double-groupby-all 686.42 23,509.02 3424.87% 16660.7 2427.19%
Thresholds high-cpu-1 2.23 17.15 769.06% 4.05 181.61%
high-cpu-all 3,508.00 52,884.94 1507.55% 4328.64 123.39%
Complex Queries groupby-orderby-limit 1,527.02 23,169.15 1517.28% 12784.92 837.25%
lastpoint 133.13 2,808.00 2109.22% 755.37 567.39%

下面我们对每个查询结果做一定的分析说明:

TDengine Database
图 8(a) .  4000  devices ×  10 metrics  Simple Rollups 查询响应时间 (数值越小越好)

由于 Simple Rollups 的整体查询响应时间非常短,制约查询响应时间主体因素并不是查询涉及的数据规模,即这种类型查询的瓶颈并不是数据规模。但是 TDengine 仍然在所有类型的查询响应时间上优于 InfluxDB 和 TimescaleDB,具体的数值比较请参见表 7 中的详细数据表格。

TDengine Database
图 8(b) .  4000  devices ×  10 metrics Aggregates 查询响应时间 (数值越小越好)

在  Aggregates 类型的查询中,我们看到 TDengine 查询性能相比于 TimescaleDB 和 InfluxDB 有比较大的优势,TDengine 在 cpu-max-all-8 查询性能是 InfluxDB 的 7 倍,是 TimescaleDB 的 6 倍。

TDengine Database
图 8(c) .  4000  devices ×  10 metrics Double rollups 查询响应时间 (数值越小越好)

在 Double-rollups 类型查询中, TDengine 展现出巨大的性能优势,其查询响应时间来度量,double-groupby-5 和 double-groupby-all 的查询性能是 TimescaleDB 的 24 倍,在 double-groupby-5 查询上是 InfluxDB 的 26 倍 和 double-groupby-all 是其 34 倍。

TDengine Database
图 8(d-1) .  4000  devices ×  10 metrics Thresholds 查询 high-cpu-1 响应时间 (数值越小越好)
TDengine Database
图 8(d-2) .  4000  devices ×  10 metrics Thresholds 查询 high-cpu-all 响应时间 (数值越小越好)

如图 8(d) 所示 threshold 类型的查询,TDengine 的查询响应时间均显著低于 TimescaleDB 和 InfluxDB。在 high-cpu-all 类型的查询上,TDengine 的性能是 InfluxDB 的 15 倍,是 TimescaleDB 的 1.23 倍。

对于 Complex-queries 类型的查询,TDengine 两个查询均大幅领先 TimescaleDB 和 InfluxDB。在lastpoint 查询中,查询性能是 TimescaleDB 的 5 倍, InfluxDB 的 21倍。在 groupby-orderby-limit 场景中查询性能是TimescaleDB的 8 倍,是 InfluxDB 的 15 倍。在时间窗口聚合的查询过程中,TimescaleDB 针对规模较大的数据集其查询性能不佳(double rollups类型查询),对于 groupby-orderby-limit 的查询,其性能上表现同样不是太好。

TDengine Database
图 8(e) .  4000  devices ×  10 metrics Complex queries 查询响应时间 (数值越小越好)

4.2 资源开销对比

由于部分查询持续时间特别短,并不能完整地看到查询过程中服务器的 IO/CPU/网络情况。我们针对场景二以 Double rollups 类别中的 double-groupby-5 查询为例,执行 1,000 次查询,记录整个过程中三个软件系统在查询执行的整个过程中服务器 CPU、内存、网络的开销进行对比。

TDengine Database
图 9.  查询过程中服务器  CPU  开销

如图 9 可以看到,三个系统在整个查询过程中 CPU 的使用均较为平稳。TDengine 在查询过程中整体 CPU 占用约 80%, 在三个系统中使用的 CPU 资源最高,TimescaleDB 在查询过程中瞬时 CPU 占用次之,约 38%。InfluxDB 的稳定的 CPU 占用的最小,约 27 %(但是有较多的瞬时冲高)。整体 CPU 开销上来看,虽然 InfluxDB 瞬时 CPU 开销大部分是最低的,但是其完成查询持续时间最长,所以整体 CPU 资源消耗最多。由于 TDengine 完成全部查询的时间仅 TimescaleDB 或 InfluxDB 的  1/20,虽然 CPU 稳定值是 TimescaleDB 与 InfluxDB 的 2 倍多,整体的 CPU 计算时间消耗只有其 1/10 。

服务器内存状况

TDengine Database
图 10. 查询过程中服务器内存情况

如图 10 所示,在整个查询过程中,TDengine 内存维持了一个相对平稳的状态。TimescaleDB 在整个查询过程中内存呈现增加的状态,查询完成后即恢复到初始状态,InfluxDB 内存占用呈现相对稳定的状态。

服务器网络带宽

TDengine Database
图 11. 查询过程中网络占用情况

图 11 展示了查询过程中服务器端上行和下行的网络带宽情况,负载状况基本上和 CPU 状况相似。TDengine 网络带宽开销最高,因为在最短的时间内就完成了全部查询,需要将查询结果返回给客户端。InfluxDB 网络带宽开销最低,TimescaleDB 介于两者之间。

4.3 100 devices × 10 metrics 查询性能对比

对于场景一(100 devices x 10 metrics),TSBS 的 15 个查询对比结果如下:

表 8. InfluxDB 与 Timescale 相对于 TDengine 查询响应时间比率 (单位:ms)
查询分类  TDengine InfluxDB InfluxDB/TDengine TimescaleDB TimescaleDB/TDengine
Simple Rollups single-groupby-1-1-1 0.91 2.01 220.88% 2.93 321.98%
single-groupby-1-1-12 1.83 9.40 513.66% 4.87 266.12%
single-groupby-1-8-1 2.09 3.98 190.43% 4.30 205.74%
single-groupby-5-1-1 1.03 4.40 427.18% 3.19 309.71%
single-groupby-5-1-12 2.94 36.77 1250.68% 6.38 217.01%
single-groupby-5-8-1 2.63 13.71 521.29% 5.91 224.71%
Aggregates cpu-max-all-1 1.27 5.92 466.14% 5.55 437.01%
cpu-max-all-8 3.46 21.88 632.37% 22.83 659.83%
Double-Rollups double-groupby-1 7.79 78.61 1009.11% 116.66 1497.56%
double-groupby-5 12.10 340.53 2814.30% 346.48 2863.47%
double-groupby-all 17.31 642.16 3709.76% 489.04 2825.19%
Thresholds high-cpu-1 2.05 13.51 659.02% 3.92 191.22%
high-cpu-all 96.75 1,129.62 1167.57% 104.68 108.20%
Complex Queries groupby-orderby-limit 47.48 533.50 1123.63% 367.40 773.80%
lastpoint 3.95 74.55 1887.34% 17.64 446.58%

如表 8 所示,在更小规模的数据集(100设备)上的查询对比可以看到,整体上 TDengine 同样展现出极好的性能,在全部的查询语句中全面优于 TimescaleDB  和 InfluxDB,部分查询性能超过 TimescaleDB 28 倍,超过 InfluxDB 37 倍。

五、总结

基于 TSBS 性能基准测评框架的结果可以看到,得益于 TDengine 契合时序数据特点的架构设计,TDengine 在数据写入和查询性能上相对于 TimescaleDB 和 InfluxDB,不论是数据写入的性能,写入过程中对于资源的消耗,查询的响应延迟还是查询过程中资源的开销,均全面优于 TimescaleDB 和 InfluxDB。本次对比测评只将 TDengine 横向对比了两个较为流行的时序数据库软件,后续我们进行更加深入全面的对比测评,涉及更多的数据库产品,更广泛的数据集,并会陆续发布相关的结果。

《基于 TSBS 标准数据集时序数据库 TimescaleDB、InfluxDB 与 TDengine 在 IoT 场景性能对比测试报告》已发布,点击这里获取。

六、参考文献

[1] Timescale. https://www.timescale.com/

[2] High-cardinality TSDB benchmarks: VictoriaMetrics vs TimescaleDB vs InfluxDB. https://valyala.medium.com/high-cardinality-tsdb-benchmarks-victoriametrics-vs-timescaledb-vs-influxdb-13e6ee64dd6b

[3] ClickHouse Crushing Time Series. https://altinity.com/blog/clickhouse-for-time-series

[4] ClickHouse Continues to Crush Time Series. https://altinity.com/blog/clickhouse-continues-to-crush-time-series

[5] Benchmarking Time Series workloads on Apache Kudu using TSBS.https://blog.cloudera.com/benchmarking-time-series-workloads-on-apache-kudu-using-tsbs/

[6] RedisTimeSeries Version 1.2 Benchmarks. https://redis.com/blog/redistimeseries-version-1-2-benchmarks/

[7] TimescaleDB vs. InfluxDB: Purpose Built Differently for Time-Series Data. https://www.timescale.com/blog/timescaledb-vs-influxdb-for-time-series-data-timescale-influx-sql-nosql-36489299877/

[8] QuestDB vs. TimescaleDB. https://towardsdatascience.com/questdb-vs-timescaledb-38160a361c0e

[9] Time Series Benchmark Suite. https://github.com/timescale/tsbs