TDengine与Cassandra对比测试
为帮助用户了解TDengine Database的指标,特将TDengine与Cassandra从数据库的读、写、查询、压缩比等方面进行了对比测试。从测试结果上看,TDengine的性能远超Cassandra,写入性能约为20倍,读取性能约为17倍,聚合函数性能约为4000倍,按标签分组查询性能约为2500倍,按时间分组查询性能约为119倍。
测试环境
对比测试的测试程序和数据库服务在同一台4核8GB的Dell台式机上部署,台式机型号为OptiPlex-3050,详细配置如下
OS:Ubuntu16.04 x64
CPU:Intel(R)Core(TM) i3-7100 CPU @3.90GHz
Memory:8GB
Disk:1TB HDD
测试数据集及其生成方法
1.测试数据生成方法
本次测试调研了两类比较热门的测试数据集:
1. 纽约出租车运行数据,因该数据中抹去了单台车辆的信息,无法对其进行建模
2. faker生成工具,因其只能生成字符串,并不适合物联网场景下处理的数据。
所以,为了使得测试可轻易重复,自己写了一个生成模拟数据的程序来进行本次测试。
测试数据生成程序模拟若干温湿度计生成的数据,其中温度为整数、湿度为浮点数,同时每个温度计包含设备ID、设备分组、设备名称三个标签。为了尽可能真实地模拟温湿度计的生成数据,没有使用完全随机数,而是针对每个温度计确保生成的数据值呈正态分布。
测试数据的频率为1秒钟,数据集包含10000台设备,每台设备10000条记录。每条数据采集记录包含3个标签字段,2个数据字段,1个时间戳字段。
2.测试数据生成程序源码
采用java程序生成测试数据集,测试程序源代码行数较多,因此您可以到https://github.com/taosdata/tests/tree/master/comparisonTest/dataGenerator 下载,执行如下语句
cd tests/comparisonTest/dataGeneratorjavac com/taosdata/generator/DataGenerator.java
3.测试数据生成程序用法
相关参数如下
dataDir 生成的数据文件路径
numOfFiles 生成的数据文件数目
numOfDevices 测试数据集中的设备数目
rowsPerDevice 测试数据集中每台设备包含的记录条数
4.生成测试数据
执行如下命令,会在~/testdata目录下生成100个数据文件,每个文件包含100台设备的测试数据;合计10000台设备,每台设备10000条记录
mkdir ~/testdatajava com/taosdata/generator/DataGenerator -dataDir ~/testdata -numOfDevices 10000 -numOfFiles 100 -rowsPerDevice 10000
TDengine环境准备
TDengine是一个开源的专为物联网、车联网、工业互联网、IT运维等设计和优化的大数据平台。除核心的快10倍以上的时序数据库(Time-Series Database)功能外,还提供缓存、数据订阅、流式计算等功能,最大程度减少研发和运维的工作量
1.安装部署
下载tdengine-1.6.1.0.tar.gz,地址https://www.taosdata.com/
安装TDengine,解压后运行install.sh进行安装
启动TDengine,运行sudo systemctl start taosd
测试是否安装成功,运行TDengine的shell命令行程序taos,可以看到如下类似信息
Welcome to the TDengine shell, server version:1.6.1.0 client version:1.6.1.0Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
taos>
2.数据建模
TDengine Database为相同结构的设备创建一张超级表(STable),而每个具体的设备则单独创建一张数据表。因此,超级表的数据字段为采集时间、温度、湿度等与时间序列相关的采集数据;标签字段为设备编号、设备分组编号、设备名称等设备本身固定的描述信息。创建超级表的SQL语句为
create table devices(ts timestamp, temperature int, humidity float) tags(devid int, devname binary(16), devgroup int);
以设备ID作为表名(例如device id为1,则表名为dev1),使用自动建表语句,写入一条记录的语句为
insert into dev1 using devices tags(1,'d1',0) values(1545038786000,1,3.560000);
3.测试程序源码
本文采用TDengine的原生C语言接口,编写数据写入及查询程序,后续的其他文章会提供基于JDBCDriver的测试程序。
测试程序源代码行数较多,因此您可以到https://github.com/taosdata/tests/tree/master/comparisonTest/tdengine 下载,执行如下语句
cd tdengine
make
会在当前目录下生成可执行文件./tdengineTest
4.测试程序用法
TDengine的测试程序用法与Cassandra的用法相同,写入相关参数
writeClients 并发写入的客户端链接数目,默认为1
rowsPerRequest 一次请求中的记录条数,默认为100,范围1-1000
dataDir 读取的数据文件路径,来自于测试数据生成程序
numOfFiles 从数据文件路径中读取的文件个数
例如
./tdengineTest -dataDir ./data -numOfFiles 10 -writeClients 2 -rowsPerRequest 100
查询相关参数
sql 将要执行的SQL语句列表所在的文件路径,以逗号区分每个SQL语句
例如
./tdengineTest -sql ./sqlCmd.txt
Cassandra环境准备
Apache Cassandra是一个高度可扩展的高性能分布式数据库,用于处理大量商用服务器上的大量数据,提供高可用性,无单点故障。这是一种NoSQL类型的数据库。
1.安装部署
下载并安装Cassandra
echo "deb http://www.apache.org/dist/cassandra/debian 311x main" | sudo tee -a /etc/apt/sources.list.d/cassandra.sources.list
curl https://www.apache.org/dist/cassandra/KEYS | sudo apt-key add -
sudo apt-get update
sudo apt-get install cassandra
启动Cassandra服务
sudo service cassandra start
测试是否安装成功,运行Cassandra的shell命令行程序cqlsh,可以看到如下类似信息
Connected to Test Cluster at 127.0.0.1:9042.[cqlsh 5.0.1 | Cassandra 3.11.4 | CQL spec 3.4.4 | Native protocol v4]Use HELP for help.
cqlsh>
2.Cassandra数据建模
创建一个名为Cassandra.test的measurement,所有设备都属于该measurement。每条记录包含六个数据字段,分别为时间戳(毫秒),温度(整型),湿度(浮点),设备编号(整型)、设备分组编号(整型)、设备名称(字符型)。主键为(设备分组编号、设备编号、设备名称,时间戳)。因为Cassandra的where语句里只对主键进行搜索,所以在后面查询时需要进行筛选的列一定要放进主键里。同时,因为Cassandra里group by语句只能对主键且按照主键的顺序进行聚合,所以这里将后面聚合查询用到的设备分组编号放在主键的第一位。
3.Cassandra测试程序源码
本文采用Cassandra的原生Java语言接口,编写数据写入及查询程序,测试程序源代码行数较多,因此您可以到https://github.com/taosdata/tests/tree/master/comparisonTest/cassandra 下载。
安装Cassandra Java 客户端。本次测试使用DataStax提供的客户端,具体可见https://github.com/datastax/java-driver。 DataStax使用maven管理源码,在Cassandra/Cassandratest/pom.xml 里DataStax客户端已经被添加入maven的库里。
4.Cassandra测试程序用法
测试准备
由于Cassandra建表写入查询速度比较慢,在本次测试中很容易出现timeout错误,测试无法进行下去。因此测试前一定需要修改Cassandra服务端和客户端的timeout的默认值。
服务端修改, 将/etc/Cassandra/Cassandra.yaml 中所有含有“timeout”的设置选项里的默认值增加100-1000倍。
客户端修改, 在测试源代码Cassandra/目录下提供了“application.conf”文件,里面修改了客户端timeout默认值,执行源代码时需要提供这个文件的路径。
写入相关参数
writeClients 并发写入的客户端链接数目,默认为1
rowsPerRequest 一次请求中的记录条数,默认为100,范围1-1000
dataDir 读取的数据文件路径,来自于测试数据生成程序
numOfFiles 从数据文件路径中读取的文件个数
conf Cassandra客户端参数文件所在路径(修改timeout默认值)
例如
cd cassandra/cassandratest/target
java -jar cassandratest-1.0-SNAPSHOT-jar-with-dependencies.jar -datadir ./data -numofFiles 100 -rowsperrequest 2000 -writeclients 4 -conf cassandra/application.conf
查询相关参数
sql 将要执行的SQL语句列表所在的文件路径,以逗号区分每个SQL语句
例如
cd cassandra/cassandratest/target
java -jar cassandratest-1.0-SNAPSHOT-jar-with-dependencies.jar -sql cassandra/sqlCmd.txt -conf cassandra/application.conf
写入性能对比
数据库的一个写入请求可以包含一条或多条记录,一次请求里包含的记录条数越多,写入性能就会相应提升。在以下测试中,使用R/R表示Records/Request ,即一次请求中的记录条数。同时,一个数据库可以支持多个客户端链接,链接数增加,系统总的写入通吐量也会相应增加。因此测试中,对于每一个数据库,都会测试一个客户端和多个客户端连接的情况。
1.TDengine的写入性能
TDengine按照每次请求包含1,100,500,1000,2000条记录各进行测试,同时也测试了不同客户端连接数的情况。测试步骤如下所示,您可以修改示例中的参数,完成多次不同的测试。
1.清空上次测试数据
运行TDengine的shell命令行程序taos,执行删除测试数据库语句Welcome to the TDengine shell, server version:1.6.1.0 client version:1.6.1.0Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
taos>drop database db;
2.测试执行开启5个客户端读取~/testdata目录中的100个数据文件,每个请求写入1000条数据,可以参考如下命令./tdengineTest -dataDir ~/testdata -numOfFiles 100 -writeClients 5 -rowsPerRequest 1000
写入吞吐量如下,单位为记录数/秒
R/R1 client2 clients3 clients4 clients5 clients6 clients7 clients126824436995513762869645296864772277100415800734484895522976085108790211710741192199500479846882612108303211951001269196136425614170041000500751914494112191412391571367989141810414765602000512820105552011741641306904142663514584341477208表1 TDengine的写入吞吐量图1 TDengine的写入吞吐量2.Cassandra的写入性能
Cassandra按照每次请求包含1,10,50, 100,500,1000条记录各进行测试,同时也测试了不同客户端连接数的情况。测试步骤如下所示,您可以修改示例中的参数,完成多次不同的测试。
1.清空上次测试数据运行Cassandra的shell命令行程序cqlsh,可以看到如下类似信息Connected to Test Cluster at 127.0.0.1:9042.[cqlsh 5.0.1 | Cassandra 3.11.4 | CQL spec 3.4.4 | Native protocol v4]Use HELP for help.cqlsh> drop database Cassandra;
2.测试执行开启5个客户端读取~/testdata目录中的100个数据文件,每个请求写入1000条数据,可以参考如下命令java -jar cassandratest-1.0-SNAPSHOT-jar-with-dependencies.jar -dataDir ~/testdata -numOfFiles 100 -writeClients 5 -rowsPerRequest 1000 -conf cassandra/application.conf
写入吞吐量如下,单位为记录数/秒
R/R1 client2 clients3 clients4 clients5 clients6 clients7 clients13515492555295991633163806597103599835542351243413535077358863610250317434942351626557525728256815558311003832850387545195694057853593356170850030417362643807839066394593975839918100021555252932622426559267652651126693表2 Cassandra的写入吞吐量图2 Cassandra的写入吞吐量3.TDengin和Cassandra的最佳性能对比
基于以上的测试数据,将TDengine和Cassandra测试出的最佳写入速度进行对比,结果如下
R/R1 client2 clients3 clients4 clients5 clients6 clients7 clientsTDengine512820105552011741641306904142663514584341477208Cassandra38328503875451956940578355933561708表3 TDengine和Cassandra的最佳写入性能对比图3. TDengine和Cassandra的最佳写入性能对比
从图3可以看出,TDengine的写入速度约为百万条记录/秒的量级,而Cassandra的写入速度约为1~10万条记录/秒的量级。因此可以得出结论,在同等数据集和硬件环境下,TDengine的写入速度远高于Cassandra,约为20倍。
读取性能对比
本测试做了简单的遍历查询,就是将写入的数据全部读出。
1. TDengine的测试方法
测试SQL语句存储在tdengine/q1.txt中,测试SQL语句参考select * from db.devices where devgroup=0;
执行方法如下
./tdengineTest -sql ./q1.txt
2.Cassandra的测试方法
测试SQL语句存储在Cassandra/q1.txt中,测试SQL语句参考select * from devices where devgroup=0;
执行方法如下
java -jar cassandratest-1.0-SNAPSHOT-jar-with-dependencies.jar -conf cassandra/application.conf -sql cassandra/q1.txt
读取速度如下,单位为秒
LatencyG-0G-10G-20G-30G-40G-50G-60G-70G-80G-90TDengine0.2350.2120.2080.2180.2090.2100.2090.2090.2160.208Cassandra3.923.683.653.613.693.573.553.593.663.64表4 TDengine和Cassandra的读取性能对比图4 TDengine和Cassandra的读取性能对比
从图表中可以看出,TDengine的100万条的读取速度稳定在0.21秒,吞吐量约为500万条记录/秒,Cassandra的100万条的读取速度大约在3.6秒,吞吐量约为30万条记录/秒。所以从测试结果来看,TDengine的查询吞吐量高于Cassandra,约为Cassandra的17倍。
聚合函数性能对比
本单元的测试包含COUNT,AVERAGE,SUM,MAX,MIN这五个TDEngine和Cassandra共有的聚合函数。所有测试函数都会搭配筛选条件(WHERE)来选取设备的十分之一、十分之二、十分之三、直到全部设备。
1.TDengine的聚合函数性能
测试SQL语句存储在tdengine/q2.txt中,测试SQL语句参考select count(*) from db.devices where devgroup<10;
执行方法如下./tdengineTest -sql ./q2.txt
查询速度如下表,单位为秒
Latency10+%30%40%50%60%70%80%90%100%count0.0180.0260.0160.0180.0170.0240.0240.0270.0300.033avg0.0070.0140.0150.0200.0240.0380.0440.0500.0570.060sum0.0060.0100.0190.0180.0310.0360.0340.0370.0430.046max0.0070.0130.0150.0200.0250.0300.0350.0390.0450.049min0.0060.0100.0160.0240.0320.0390.0450.0410.0430.049spread0.0070.0100.0150.0190.0330.0380.0460.0520.0590.066表5 TDengine聚合函数性能图5 TDengine聚合函数性能2.Cassandra的聚合函数性能
测试SQL语句存储在Cassandra/q2.txt中。
select count(*) from devices where devgroup<10;
执行方法如下Java -jar cassandratest-1.0-SNAPSHOT-jar-with-dependencies.jar -sql cassandra/q2.txt -conf cassandra/application.conf
查询速度如下表,单位为秒
Latency10+%30%40%50%60%70%80%90%100%count33.7967.2387.64105.82131.52160.88188.70213.85240.39264.49mean28.8857.8387.16114.87145.30173.32204.11235.33261.29290.97sum29.3558.1986.24115.56145.73173.81203.94234.15260.41292.51max28.9457.8585.60115.02145.62175.08202.53232.61260.37288.46min29.5858.2687.27117.22144.01174.20201.88235.98263.69290.27表6 Cassandra聚合函数性能图6 Cassandra聚合函数性能3.聚合函数性能对比
基于以上的测试数据,将TDengine和Cassandra在1亿条记录数据集的测试结果进行对比
LatencycountaveragesummaxminTDengine0.0330.060.0460.0490.049Cassandra264.49290.97291.51288.46290.27表7 聚合函数性能对比图7 聚合函数性能对比
从图7可以看出,TDengine的聚合函数查询时间在100毫秒以内,而Cassandra的查询时间在200~300秒左右。因此可以得出结论,在同等数据集和硬件环境下,TDengine的聚合查询速度远远高于Cassandra,超过100倍。
按标签分组查询性能对比
本测试做了按标签分组函数的性能测试,测试函数会搭配筛选条件(WHERE)来选取设备的十分之一、十分之二、十分之三、直到全部设备。
1. TDengine的测试方法测试SQL语句存储在tdengine/q3.txt中,例如
select count(temperature), sum(temperature), avg(temperature) from db.devices where devgroup<10 group by devgroup;
执行方法如下
./tdengineTest -sql ./q3.txt
2. Cassandra的测试方法测试SQL语句存储在Cassandra/q3.txt中,例如
select count(temperature), sum(temperature), avg(temperature) from db.devices where devgroup<10 group by devgroup;
执行方法如下
java -jar cassandratest-1.0-SNAPSHOT-jar-with-dependencies.jar -sql cassandra/q3.txt -conf cassandra/application.conf
读取速度如下,单位为秒
Latency10+%30%40%50%60%70%80%90%100%TDengine0.0300.0280.0310.0410.0690.0660.0770.0910.1020.123Cassandra31.4062.2192.12122.01154.95185.03217.46249.59281.86308.89表8 TDengine和Cassandra的按标签分组查询性能对比图8 TDengine和Cassandra的按标签分组查询性能对比
从测试结果来看,TDengine的分组聚合查询速度远高于Cassandra,约为3000倍。
按时间分组性能对比
本测试做了按时间分组函数的性能测试,测试函数会搭配筛选条件(WHERE)来选取设备的十分之一、十分之二、十分之三、直到全部设备。
1. TDengine的测试方法测试SQL语句存储在tdengine/q4.txt中,例如
select count(temperature), sum(temperature), avg(temperature) from db.devices where devgroup<10 interval(1m);
执行方法如下
./tdengineTest -sql ./q4.txt
2. Cassandra的测试方法因为前面提到的Cassandra 在where和group by 语句里的限制,在测试之前,需要重新写入数据,在原表中加入“minute”这一列,同时将它放入主键的第一位。执行下面命令再写入一次数据
java -jar cassandratest-1.0-SNAPSHOT-jar-with-dependencies.jar -datadir ~/testdata -numofFiles 100 -rowsperrequest 2000 -writeclients 4 -conf cassandra/application.conf -timetest
测试SQL语句存储在Cassandra/q4.txt中,例如
select count(temperature), sum(temperature), mean(temperature) from devices where devgroup<10 group by minute;
执行方法如下
java -jar cassandratest-1.0-SNAPSHOT-jar-with-dependencies.jar -sql cassandra/q4.txt -conf cassandra/application.conf
读取速度如下,单位为秒
Latency10+%30%40%50%60%70%80%90%100%TDengine0.2370.4720.6530.9021.1341.4221.7531.7842.0852.549Cassandra131.35153.87169.40188.86203.47227.61250.41274.53294.87303.51表9 TDengine和Cassandra的按时间分组查询性能对比图9 TDengine和Cassandra的按时间分组查询性能对比
从测试结果来看,TDengine的按时间分组聚合查询速度远高于Cassandra,约为100倍。
压缩比对比
1.原始数据的磁盘占用
本次测试共生成100个测试数据文件,存储在~/testdata目录下,使用du命令查看~/testdata目录的文件大小
cd ~/testdata
du -h .
如下图所示
图10 原始数据的磁盘占用情况2.查看TDengine的磁盘占用
TDengine的磁盘文件默认位置在目录/var/lib/taos/data下,在查看磁盘文件大小时,首先将TDengine的服务停止
sudo systemctl stop taosd
然后,调用du命令,查看/var/lib/taos/data目录下文件的大小
cd /var/lib/taos/datadu -h .
如下图所示
图11 TDengine的磁盘占用情况3.查看Cassandra的磁盘占用
Cassandra的磁盘文件默认位置在目录/var/lib/Cassandra/data/keyspace_name下,在查看磁盘文件大小时,首先将Cassandra的服务停止
sudo service Cassandra stop
本测试中,数据存储在/var/lib/Cassandra/data/Cassandra目录下,调用du命令,查看该目录下文件的大小。
cd /var/lib/Cassandra/data/Cassandra
du -sh .
如下图所示
图12 Cassandra的磁盘占用情况4.磁盘占用情况对比
生成的测试数据文件占用的磁盘大小为3941MB,Cassandra磁盘占用12GB,TDengine磁盘占用459MB。在相对比较随机数据集的情况下,TDengine的压缩比约为Cassandra压缩比的26.7倍。
在物联网场景下,大多数采集数据的变化范围都比较小。由于TDengine采用列式存储,因此可以预期,TDengine在真实场景的压缩比表现会更好。
功能对比
TDengine与Cassandra都是用与处理时序数据的存储引擎,其功能比较接近,各有特色。
功能支持TDengineCassandraSQL语法支持支持不支持查询中的计算支持*支持不支持非主键分组支持不支持私有化部署支持支持支持水平扩展能力支持支持系统连接管理支持支持查询任务管理支持支持数据导入工具支持支持数据导出工具支持支持Web管理工具支持支持多介质分级存储支持支持Telegraf数据采集支持支持Grafana数据可视化支持支持RESTFul支持支持C/C++支持不支持JDBC/ODBC支持不支持GO支持支持Python支持支持数据库参数配置支持支持配置副本数支持支持数据时效支持支持数据分区支持支持流式计算支持不支持数据订阅支持不支持微秒级精度支持支持聚合函数支持支持支持数据降采样支持支持数据分页支持支持数据插值支持支持历史数据修改不支持支持时间线删除支持支持数据清空支持支持表10 TDengine与Cassandra的功能对比*note: Cassandra的select语句中不支持数学运算,如有需要,可以使用用户自定义函数。具体参见https://Cassandra.apache.org/doc/latest/cql/index.html
总结
此次测试,从数据库的读、写、查询、压缩比等方面对TDengine和Cassandra进行了对比测试。测试用数据集、测试程序源码、执行的SQL语句都可以从https://github.com/taosdata/tests/tree/master/comparisonTest/ 下载,测试具备可重复性。
从测试结果上看,TDengine Database的性能远超Cassandra,写入性能约为20倍,读取性能约为17倍,聚合函数性能约为4000倍,按标签分组查询性能约为2500倍,按时间分组查询性能约为119倍,具体见下表。
TDengineCassandra写入吞吐量1477208 记录数/秒记录数61708/秒100万条记录读取时间0.21秒3.64秒1亿条记录取平均值时间0.06秒264.49秒1亿条记录按标签分组取均值时间0.123308.39秒1亿条记录按时间分组取均值时间2.549秒303.51秒表11 TDengine与Cassandra的性能对比汇总
-
HummingBird基于Go开源超轻量级 IoT 物联网平台
蜂鸟(HummingBird) 是 Go 语言实现的超轻量级物联网开发平台,包含设备接入、产品管理、物模型、告警中心、规则引擎等丰富功能模块。系统采用GoLang编写,占用内存极低, 单物理机可实现百
-
使用Apache Flink连接TDengine
小 T 导读:想用 Flink 对接 TDengine?保姆级教程来了。0.前言TDengine 是由涛思数据开发并开源的一款高性能、分布式、支持 SQL 的时序数据库(Time-Series Dat
-
58同城DBA团队选择TDengine解决传感器数据处理难题
在 58 同城的驾考业务上,需要存储分析驾校教练车传感器产生的数据,这是典型的时序数据场景,开发人员对原有的 TiDB 性能并不是很满意,因此 DBA 团队开始调研更具针对性的时序数据库。基于自身的业
关注公众号:拾黑(shiheibook)了解更多
赞助链接:
关注数据与安全,洞悉企业级服务市场:https://www.ijiandao.com/
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
随时掌握互联网精彩