我们之前已经发布了 TDengine 和 InfluxDB 的写入性能测试报告,今天我们再来对比一下两款时序数据库(Time-Series Database)产品的查询性能。
1. 前言
本报告包含了基础测试部分内容,并根据具体的场景,增加了部分扩展测试场景,以便更加全面、准确地呈现两款数据库产品在不同应用场景下的查询性能表现。
1.1 硬件环境
为便于大家复现该测试,我们在 Microsoft Azure 云服务上搭建了测试环境。测试中用到了两台服务器,分别部署客户端和服务器,客户端与服务器通过云服务的内网连接。
两台服务器的具体配置如下。
客户端 | 8C,Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz | 16 GB | 64 GB SSD, 无写入情况下,4k 随机读取 IOPS 5000 |
服务端 | 16C, AMD EPYC 7452 32-Core Processor | 128 GB | 1 TB SSD, 无写入情况下,4k 随机读取 IOPS 25000 |
操作系统均为 Ubuntu 20.10 Linux。使用的 Go 版本为 1.16。
1.2 软件安装
TDengine 2.1.7.2 社区版,可以在涛思官网下载。也可以通过 clone GitHub 上的代码自行编译生成。该版本的 git 的信息如下:
community version: 2.1.7.2 compatible_version: 2.0.0.0
gitinfo: c6be1bb809536182f7d4f27c0d8267b3b25c9354
InfluxDB 1.8.4(由于该性能测试框架最高只能适配到 1.8 版本,所以这里选取了 InfluxDB 1.8 版本进行对比),可以在 InfluxData 官网下载。
1.3 运行脚本生成查询用数据
1.3.1 安装准备
部署完 TDengine、InfluxDB 与 Go 语言环境,确保两台服务器的数据库也连接正常使用正常(建库删库写入查询功能均需测试,建库之后立即删除,如有问题立刻排查)
此外,在测试中应该注意以下几点( TDengine 的默认配置文件为 /etc/taos/taos.cfg ):
1)fsync 的设置要保持同步,InfluxDB 默认是无延时的 fsync,需要修改 TDengine 的这两个参数:walLevel=2 ,fsync=0 才能达到相同的配置环境。后续的一切测试均是在这个设置条件下完成。
2)TDengine 的客户端要把 maxSQLLength 开到最大 1048576。
3)客户端服务器要安装 TDengine 的客户端。(注意:bulk_load_tdengine 编译需要依赖 TDengine 客户端)
1.3.2 从 GitHub 取下代码,在客户端服务器执行:
git clone https://github.com/taosdata/timeseriesdatabase-comparisons
1.3.3 准备编译环境,生成写入程序,timeseriesdatabase-comparisons 的根目录为工作目录:
cd timeseriesdatabase-comparisons/build/tsdbcompare/
./compilation.sh
1.3.4 切换到build/tsdbcompare目录下,产生测试数据集合并写入数据库。
在build/tsdbcompare下执行./writ_to_server.sh -a "test217"
# 本次测试的服务端 hostname 是"test217",./writ_to_server.sh -h 可以查看对应参数:
生成数据参数(总记录数=(t-e)*24*3600/ i * s)
i : 数据间隔,默认10s
s : 样本数量,默认100
t : 数据起始时间,默认'2018-01-01T00:00:00Z'
e : 数据终止时间,默认'2018-01-02T00:00:00Z'
g : 是否生成数据,默认1(1:生成数据,0:不生成数据)
T : TDengine的默认数据目录路径,默认为"/var/lib/taos"
I : InfluxDB默认数据目录路径,默认为"/var/lib/influxdb"
写入参数
b : batchsize(默认5000)
w : workers(默认16)
n : TDengine写入方式(false:cgo,true:rest,默认false)
a : TDengine 和 InfluxDB 的 hostname 或者ip地址,默认为127.0.0.1
如果希望自定义更多参数值,可以查看 write_to_server.sh 脚本代码
1.3.5 生成查询文件,并进行查询测试,在build/tsdbcompare下运行脚本:
./read_all.sh -a "test217"
脚本参数和 write_to_server.sh 一致。
2. 测试运行
运行该测试要求关闭 TDengine 系统日志,然后自动执行脚本即可。
在不同的场景之间切换时,会重启数据库后台服务(Influxd/taosd),并清除 Linux 系统的全部缓存。
3. 对比测试结果
本小节说明运行测试脚本获得的对比测试结果,并对结果进行了初步的分析。
对于测试结果,所有的响应是测试脚本自动记录的时间,即该时间并不是单次查询执行的响应时间,而是完成 1,000 次重复查询最后获得的时间。需要说明的是,由于整个测试持续时间较长,测试获得的数据并非同一个时刻。不同的时间,测试程序运行过程中会受到云服务器所能发挥的最大性能影响,获得的结果数据能看到有轻微的抖动,但是整体趋势是一致的。
100 台设备模拟生成的 1 天的数据集,在 TDengine 中生成了 900 个子表,每个设备间隔 10 s 生成一条数据,总记录数是 7,776,000。
1,000 台设备在 TDengine 中生成了 9,000 个子表,每个设备间隔 10 s 生成一条记录,总记录数是 77,760,000。
测试主要包括四个测试场景,分别是:
- 场景一:通过标签过滤随机筛选出 8 个时间线后,取其中的最大值。
- 场景二:随机选取 1 h 时间区间,通过标签随机筛选出 8 个时间线,取其中的最大值。
- 场景三:随机选取 12 h 的时间区间,通过标签随机筛选出 8 个时间线,使用 10 min 作为一个时间窗口,获取每个时间窗口的最大值。
- 场景四:随机选取 1 h 时间区间,通过标签过滤随机筛选出 8 个时间线,使用 1 min 为一个时间窗口,获取每个时间窗口的最大值。
通过测试结果可以看出:整体来看,TDengine 在多种场景下(单线程、多线程)的性能均优于 InfluxDB。在极少的几个情况下,TDengine 与 InfluxDB 的差异非常小。在更多的场景下,TDengine 拥有数倍的性能优势,部分场景的性能优势能达到 40 倍。
3.1 100 台设备数据集查询结果对比
本部分呈现的是,在 100 台设备上模拟 1 天的数据生成的结果集上,运行测试程序所获得的性能对比测试结果。
由图 1 可以看到,在所有的场景中,只有第三个测试场景单线程的时候 TDengine 查询响应时间超过 InfluxDB,其他的场景均优于 InfluxDB,并且部分场景(场景二)下其查询性能有着 40 倍的巨大优势。具体的测试响应数据见附录表 1。
在 1,000 个设备上测试结果显示出 TDengine 仍然展现出较大的性能优势,即使部分相对于 InfluxDB 较慢的场景(多线程场景下的场景四),其差距也非常小。而领先的部分,则仍然有巨大的性能优势,最高的性能差达到近 20 倍,具体的查询响应数据见附录表 2。
3.2 扩展测试
在上述的两个标准测试之外,我们基于现有的数据集合设计了一系列扩展测试,以期更全面准确地评估两个数据库产品在不同场景下的性能表现。在以下测试中,我们只使用 cgo 的运行测试结果。
3.2.1 标签筛选量对查询性能的影响
调整过滤 host 的数量,设定并行执行的 work 为 16,使用 1,000 个设备的数据集合执行全部查询,所获得的结果如下表所示。查询响应时间单位为秒,数值越小越好。
可以看到,随着筛选的时间线的增加,InfluxDB 的查询响应时间在四个测试场景均呈现快速增加的趋势,而 TDengine 对于数据筛选规模的变大则呈现出相对稳定的查询响应时间,并且随着时间线筛选规模的扩大呈现出更大的优势。 由此可以推断,随着查询规模的继续扩大,InfluxDB 的查询响应时间还会继续快速增加。各种场景下的查询响应具体时间见表 3。
3.2.2 查询时间窗口对查询性能的影响
为了评估不同长度的时间窗口对查询性能的影响,我们选取了第四个查询场景,设定并行执行的 work 数量 16, 时间区间是随机选取的 1 h / 2 h / 4 h / 8 h / 12 h 等连续时间段,单个聚合时间窗口维持在 1 min 不变。获得的查询响应时间如图 4 所示。
由上图可见,TDengine 相对于 InfluxDB 有更好的查询性能,并且,随着查询时间区间的增加,TDengine 的领先优势持续扩大,当查询时间区间是 1 小时的时候,TDengine 只比 InfluxDB 快约 8%。但是当查询区间增加到 12 小时的时候,TDengine 的查询优势已经扩大到近 2 倍。具体查询响应时间见表 4。
3.2.3 复杂查询性能表现
考虑到标准测试中只使用了较为简单的查询函数,我们使用多个查询函数组合的复杂查询,评估查询性能。我们选取了第四个运行场景,随机选取 1 h 的时间段,聚合时间窗口为 1 min,过滤筛选 8 个时间线进行查询处理。
三个场景分别是:
- max(value), count(value),first(value),last(value)
- top(value, 10)
- max(value),count(value),first(value),last(value),integral(value1)*spread(ts)/1000 在该场景中,TDengine 中没有 integral 函数,因此采用 TWA(value) * Spread(value) / 1000 的计算方式进行了等效替代。此外,integral 函数查询的是另一个列 value1,而不是 value。
由上图的结果可以看到,在三种复杂函数组合的查询条件下,TDengine 查询性能均优于 InfluxDB。特别是在第一种组合场景中,TDengine 的性能是 InfluxDB 的 2.5 倍。具体的查询响应时间见表 5。
3.2.4 数据读取测试
在这个场景测试中,我们测试了 TDengine 和 InfluxDB 的数据读取表现。针对全部数据集,不限定查询时间范围,调整标签的过滤条件,投影查询来获取全部的数据内容。其结果如图 6 所示。
可以看到,在提取不同比例的情况下,TDengine 的总的时间开销稳定在 InfluxDB 的 11% 左右,即该项测试的性能,TDengine 是 InfluxDB 的 8.78 倍,并且该优势随着时间线数量的增加而得到扩大,在 128 个时间线的时候,达到了 9.37 倍。即在更大数据规模的情况下,TDengine 展现出了更好的性能优势。在时间线为 256 的时候,InfluxDB 最终未能完成测试运行,服务端出现了连接拒绝的问题,而TDengine也仅用时 365.61 s 就跑完该项测试。
4. 总结
在基于该对比测试框架下运行的测试中,展示出了 TDengine Database 相对于 InfluxDB 较大的性能优势,特别是更加多样化的条件和变量控制情况下的扩展测试中,我们看到 TDengine 一致性地表现出相对于 InfluxDB 的较大性能优势。
附录
对比测试运行的具体数据汇总如下:
表1. 100台设备数据集上的查询结果对比
表2. 1000台设备数据集上的查询结果对比
表3. 调整筛选标签数量
表4. 不同长度的时间范围查询响应(秒)
表5. 复杂查询性能表现
表6. 不同规模数据读取性能表现(秒)