在上一篇文章《 InfluxDB vs TimeScaleDB 功能/性能对比 (一)》
<https://blog.csdn.net/suzy1030/article/details/81478514>
中,主要对比了两种数据库在功能方面的差异,以及不进行任何优化的情况下,数据批量写入的性能、存储空间的占用情况。

本篇主要对两种数据库在实际应用场景中的读写性能、空间占用进行对比,针对实际应用场景,两种数据库在表结构上都做了一些优化。

目录

测试目的及最终结论
<https://blog.csdn.net/u013480467/article/details/81486234#%E6%B5%8B%E8%AF%95%E7%9B%AE%E7%9A%84%E5%8F%8A%E6%9C%80%E7%BB%88%E7%BB%93%E8%AE%BA>

写入性能
<https://blog.csdn.net/u013480467/article/details/81486234#%E5%86%99%E5%85%A5%E6%80%A7%E8%83%BD>

存储空间占用
<https://blog.csdn.net/u013480467/article/details/81486234#%E5%AD%98%E5%82%A8%E7%A9%BA%E9%97%B4%E5%8D%A0%E7%94%A8>

读取性能
<https://blog.csdn.net/u013480467/article/details/81486234#%E8%AF%BB%E5%8F%96%E6%80%A7%E8%83%BD>

全表扫描性能对比
<https://blog.csdn.net/u013480467/article/details/81486234#%E5%85%A8%E8%A1%A8%E6%89%AB%E6%8F%8F%E6%80%A7%E8%83%BD%E5%AF%B9%E6%AF%94>

条件查询性能对比
<https://blog.csdn.net/u013480467/article/details/81486234#%E6%9D%A1%E4%BB%B6%E6%9F%A5%E8%AF%A2%E6%80%A7%E8%83%BD%E5%AF%B9%E6%AF%94>

聚合查询性能对比
<https://blog.csdn.net/u013480467/article/details/81486234#%E8%81%9A%E5%90%88%E6%9F%A5%E8%AF%A2%E6%80%A7%E8%83%BD%E5%AF%B9%E6%AF%94>

测试环境
<https://blog.csdn.net/u013480467/article/details/81486234#%E6%B5%8B%E8%AF%95%E7%8E%AF%E5%A2%83>

TimeScaleDB配置
<https://blog.csdn.net/u013480467/article/details/81486234#TimeScaleDB%E9%85%8D%E7%BD%AE>

InfluxDB配置
<https://blog.csdn.net/u013480467/article/details/81486234#InfluxDB%E9%85%8D%E7%BD%AE>

测试数据
<https://blog.csdn.net/u013480467/article/details/81486234#%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE>

测试方式
<https://blog.csdn.net/u013480467/article/details/81486234#%E6%B5%8B%E8%AF%95%E6%96%B9%E5%BC%8F>

测试用例及结果
<https://blog.csdn.net/u013480467/article/details/81486234#%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%E5%8F%8A%E7%BB%93%E6%9E%9C>

写入性能
<https://blog.csdn.net/u013480467/article/details/81486234#%E5%86%99%E5%85%A5%E6%80%A7%E8%83%BD>

存储空间占用
<https://blog.csdn.net/u013480467/article/details/81486234#%E5%AD%98%E5%82%A8%E7%A9%BA%E9%97%B4%E5%8D%A0%E7%94%A8>

全表扫描性能
<https://blog.csdn.net/u013480467/article/details/81486234#%E5%85%A8%E8%A1%A8%E6%89%AB%E6%8F%8F%E6%80%A7%E8%83%BD>

条件查询性能
<https://blog.csdn.net/u013480467/article/details/81486234#%E6%9D%A1%E4%BB%B6%E6%9F%A5%E8%AF%A2%E6%80%A7%E8%83%BD>

数据源维度查询
<https://blog.csdn.net/u013480467/article/details/81486234#%E6%95%B0%E6%8D%AE%E6%BA%90%E7%BB%B4%E5%BA%A6%E6%9F%A5%E8%AF%A2>

时间维度查询
<https://blog.csdn.net/u013480467/article/details/81486234#%E6%97%B6%E9%97%B4%E7%BB%B4%E5%BA%A6%E6%9F%A5%E8%AF%A2>

时间+数据源维度查询
<https://blog.csdn.net/u013480467/article/details/81486234#%E6%97%B6%E9%97%B4%2B%E6%95%B0%E6%8D%AE%E6%BA%90%E7%BB%B4%E5%BA%A6%E6%9F%A5%E8%AF%A2>

采集指标维度小范围查询
<https://blog.csdn.net/u013480467/article/details/81486234#%E9%87%87%E9%9B%86%E6%8C%87%E6%A0%87%E7%BB%B4%E5%BA%A6%E5%B0%8F%E8%8C%83%E5%9B%B4%E6%9F%A5%E8%AF%A2>

聚合查询性能
<https://blog.csdn.net/u013480467/article/details/81486234#%E8%81%9A%E5%90%88%E6%9F%A5%E8%AF%A2%E6%80%A7%E8%83%BD>

全表
<https://blog.csdn.net/u013480467/article/details/81486234#%E5%85%A8%E8%A1%A8>

以数据源维度为聚合条件
<https://blog.csdn.net/u013480467/article/details/81486234#%E4%BB%A5%E6%95%B0%E6%8D%AE%E6%BA%90%E7%BB%B4%E5%BA%A6%E4%B8%BA%E8%81%9A%E5%90%88%E6%9D%A1%E4%BB%B6>

以时间维度聚合条件
<https://blog.csdn.net/u013480467/article/details/81486234#%E4%BB%A5%E6%97%B6%E9%97%B4%E7%BB%B4%E5%BA%A6%E8%81%9A%E5%90%88%E6%9D%A1%E4%BB%B6>

 

测试目的及最终结论

本次测试主要为了对比两种数据库写入性能以及不同场景下的查询性能。

由于InfluxDB的数据查询架构和数据存储方式特殊(数据存储可参见《InfluxDB存储引擎—— TSM文件与数据写入》
<https://blog.csdn.net/suzy1030/article/details/81479138>,数据查询流程可参见
《InfluxDB存储引擎—— TSI文件与数据读取》
<https://blog.csdn.net/suzy1030/article/details/81507806>
),因此fields的数量在一定程度会影响数据查询性能,所以整理了查询单列和查询所有列的测试结果。

总的来说,InfluxDB在写入性能和存储空间上有明显优势,读取时单列查询速度较快,多列查询性能比TimeScaleDB差。

所有结论都基于本次所采用的测试数据,不同的测试数据会有不同的测试结果。

写入性能

InfluxDB的写入性能约为TimeScaleDB的3倍



存储空间占用

InfluxDB的存储空间占用不到TimeScaleDB的30%



 

读取性能

全表扫描性能对比

查询所有列时,TimeScaleDB的性能是InfluxDB的7倍左右

查询单列时,InfluxDB的性能是TimeScaleDB的2倍左右

详细数据见下文

条件查询性能对比

查询所有列时,TimeScaleDB的性能是InfluxDB的7倍左右

查询单列时,InfluxDB的性能是TimeScaleDB的2倍左右

详细数据见下文

聚合查询性能对比


聚合查询单列时InfluxDB的性能约为TimeScaleDB的2倍,聚合查询多列时TimeScaleDB性能几乎没有变化,InfluxDB的性能随着聚合查询列数的增加而降低,性能与聚合查询列数成反比。

详细数据见下文

 

测试环境

centos虚拟机

cpu: AMD Ryzen 5 1600 Six-Core(4线程)

内存:8G

磁盘:机械硬盘

TimeScaleDB配置

版本:PostgreSQL 10.4+TimeScaleDB 0.10

shared_buffers = 2g (推荐设置为机器内存的1/4,默认值为1g)

wal_buffers = 64m (推荐设置为shared_buffers的1/32,默认值为16m)

wal_writer_delay = 800ms(默认值200ms)

除上述修改之外均使用默认配置

<>InfluxDB配置

版本:1.6.0

cache-max-memory-size = "2g" (默认值为1g)

cache-snapshot-memory-size = "100m"(默认值为25m)

[http] log-enabled = false

wal与data目录指定不同磁盘

除上述修改之外均使用默认配置

 

测试数据

场景:

以1秒为时间间隔,采集机器资源消耗情况,并记录机器的操作系统以及所在城市。假设共4个数据源,采集9个指标,示例如图:



设计表结构:
CREATE TABLE test_function ( "time" timestamp with time zone,--以1秒递增 type
text,--数据源属性,只有2个取值:windows/linux address
text,--数据源属性,只有2个取值:guangzhou/shenzhen usage_system double
precision,--以下其他字段全部为随机生成的double值 usage_idle double precision, usage_nice
double precision, usage_iowait double precision, usage_irq double precision,
usage_softirq double precision, usage_steal double precision, usage_guest
double precision, usage_guest_nice double precision ) tablespace with_index_ts;
总行数:1000万行

总数据量:900M

单行大小:88byte

TimeScaleDB:时间分区跨度为7天,time/type/address三个字段带btree索引。

InfluxDB:时间分区跨度为7天,type/address设置为tag

 

测试方式

使用JAVA代码编写InfluxDB和TimeScaleDB的写入程序,在本地运行测试程序读写服务器的数据库。

 

测试用例及结果

写入性能

InfluxDB写入性能明显优于TimeScaleDB。

  行数吞吐量(行/秒)
InfluxDB 37593
TimeScaleDB 12269
原因分析:

InfluxDB存储引擎是基于LSM进行改进的TSM,LSM是利用顺序读写磁盘比随机读写主存的性能高三个数量级这一特性来保证数据的写性能,具体可参考:
《Log Structured Merge Trees(LSM) 原理》
<http://www.open-open.com/lib/view/open1424916275249.html>

 

存储空间占用

InfluxDB对存储空间的占用明显小于TimeScaleDB。

  空间占用(M)
InfluxDB 625
TimeScaleDB 2272
原因分析:

* 得益于InfluxDB的存储模型,tags不会被当成数据存储,极大程度上减少了tags的冗余存储
* 得益于InfluxDB的数据存储格式,数据在block中采用列式存储
* 得益于InfluxDB的数据压缩算法。
* Timestamp :采用delta编码,delta相同的情况下会进一步进行游程编码,delta不同且纳秒纳秒分辨率的所有值都小于(1 <<
60)-1时进一步采用Simple8b编码
* Floats : 使用Facebook Gorilla paper
<http://www.vldb.org/pvldb/vol8/p1816-teller.pdf>
实现对浮点数的编码。当值靠近在一起时,编码将连续值XORs连在一起让结果集变得更小。然后使用控制位存储增量,以指示XOR值中有多少前导零和尾随零。我们的实现会删除paper中描述的时间戳编码,并且仅对浮点值进行编码。
* Integers : 整数编码使用两种不同的策略,具体取决于未压缩数据中的值的范围。编码值首先使用ZigZag编码
<https://developers.google.com/protocol-buffers/docs/encoding?hl=en#signed-integers>
进行编码。这样在正整数范围内交错正整数和负整数。如果所有ZigZag编码值都小于(1 <<
60)-1,则使用simple8b编码进行压缩。如果有值大于最大值,则所有值都将在未压缩的块中存储。如果所有值相同,则使用游程长度编码。
* Boolean : 布尔值使用简单的位打包策略进行编码,其中每个布尔值使用1位。使用可变字节编码在块的开始处存储编码的布尔值的数量。
* Strings : 字符串使用Snappy <http://google.github.io/snappy/>
压缩进行编码。每个字符串连续打包,然后被压缩为一个较大的块。
 

全表扫描性能

  sql 符合条件的数据行数 InfluxDB耗时(S) TimeScaleDB耗时(S)
查询单列 select count(usage_idle) from test_function; 1000万 0.88 1.52
查询所有列 select count(*) from test_function; 1000万 6.759 1.04
由上述测试结果可知:
单列查询时InfluxDB的性能比TimeScaleDB高一倍,但多列查询时InfluxDB的性能下降非常明显。而TimeScaleDB查询的列数几乎不影响结果。InfluxDB的查询性能和查询的列数成反比。

原因分析:

* TimeScaleDB采用行存储,读取多列和读取单列时需要扫描的数据范围没有区别。
* InfluxDB采用列式存储,读取多列和读取单列时需要扫描的数据范围不同,需要扫描的范围与查询的列数成正比
 

条件查询性能

数据源维度查询

      sql 符合条件的数据行数 InfluxDB耗时(s) TimeScaleDB耗时(s)
数据源维度 数据源单个属性为条件 查询单列 select count(usage_idle) from test_function where type =
"windows"; 500万 0.453 1.48
查询所有列 select count(*) from test_function where type = "windows"; 500万 3.43 1.43
数据源所有属性为条件 查询单列 select count(usage_idle)  from test_function where type =
"linux" and address = "shenzhen"; 250万 0.63 1.48
查询所有列 select count(*)  from test_function where type = "linux" and address =
"shenzhen"; 250万 5.86 1.48
由上述测试结果可以得出以下结论:

* 查询的列数和查询条件中维度列的个数对TimeScaleDB的性能几乎没有影响
* 单列查询时InfluxBD的性能约为TimeScaleDB的2-3倍,所有列查询时InfluxDB的性能约为TimeScaleDB 的30-40%
* InfluxDB的查询性能随着查询条件中维度列的个数增加而降低
*
数据源维度查询多列InfluxDB与TimeScaleDB的差异比全表扫描时的性能差异要小,说明InfluxDB在数据源维度查询优化力度比TimeScaleDB大
原因分析:

上述结论1、2原因分析:见上文

结论3原因分析:InfluxDB读取数据时会根据条件中各个tag及值分别查找符合条件的seriesKey,
进行合并后再获取数据,条件中的tag越多,查找SeriesKey耗时越久。详细可阅读《InfluxDB存储引擎—— TSI文件与数据读取》
<https://blog.csdn.net/suzy1030/article/details/81507806>

结论4原因分析:InfluxDB通过对tags创建倒排索引的方式来加快数据源维度的数据读取速度,详细可阅读《InfluxDB存储引擎——
TSI文件与数据读取》 <https://blog.csdn.net/suzy1030/article/details/81507806>

 

时间维度查询

    sql 符合条件的数据行数 InfluxDB耗时(s) TimeScaleDB耗时(s)
时间维度 查询单列 select count(usage_idle)   from test_function where time >=
'2000-04-28' and time < '2000-04-29' 345600行 0.09 0.11
查询所有列 select count(*)   from test_function where time >= '2000-04-28' and time
< '2000-04-29' 345600行 0.3 0.11
由上述测试结果可知:单列查询时两种数据库差异不大,多列查询时InfluxDB的性能依旧比TimeScaleDB差。

原因分析:两种数据库都基于时间对数据进行了分区,因此在时间维度的查询性能上差异不大。(InfluxDB多列查询性能问题分析见上文)

 

时间+数据源维度查询

      sql 符合条件的数据行数 InfluxDB耗时(s) TimeScaleDB耗时(s)
数据源+时间维度 时间+数据源单个属性为条件 查询单列 select count(*)  from test_function where type =
'linux' and time >= '2000-04-28' and time < '2000-04-29' 172800行 0.09 0.09
查询所有列 select count(*)  from test_function where type = 'linux' and time >=
'2000-04-28' and time < '2000-04-29' 172800行 0.21 0.089
时间+数据源所有属性为条件 查询单列 select count(*)  from test_function where time >=
'2000-04-28' and time < '2000-04-29' and address = 'guangzhou' and type =
'linux'  86400行 0.06 0.09
查询所有列 select count(*)  from test_function where time >= '2000-04-28' and time
< '2000-04-29' and address = 'guangzhou' and type = 'linux'  86400行 0.29 0.09
由上述测试结果可知:结论与上文 数据源维度查询 和 时间维度查询 相同

 

采集指标维度小范围查询

    sql 符合条件的数据行数 InfluxDB耗时(s) TimeScaleDB耗时(s)
小范围查询 查询单列 select count(usage_idle)  from test_function where usage_idle <
0.00001 109行 1.19 1.25
查询所有列 select count(*)  from test_function where usage_idle < 0.00001 109行 9.67
1.25
从上述测试结果可知:两种数据库在采集指标维度进行条件查询时性能差异不大,反而InfluxDB因为上文中提到的原因在多列查询时性能更差。

原因分析:对采集指标进行条件筛选相当于全表扫描,两种数据库对这一场景都没有任何优化。(InfluxDB多列查询性能问题分析见上文)

 

聚合查询性能

全表

sql 符合条件的数据行数 InfluxDB耗时(s) TimeScaleDB耗时(s)
select sum(usage_system) from test_function 1000万  0.9 1.5

由上述测试数据可知:聚合查询时InfluxDB的性能比TimeScaleDB高50%左右,(如果聚合多列,InfluxDB同样会存在性能降低的问题。原因分析见上文)

原因分析:InfluxDB采用列式存储,聚合单列时需要扫描的数据范围比TimeScaleDB小

 

以数据源维度为聚合条件

sql 符合条件的数据行数 InfluxDB耗时(s) TimeScaleDB耗时(s)
select sum(usage_idle) ) from test_function group by type 1000万 1.01 2.8
select sum(usage_idle) from test_function group by type,address 1000万 2.955 3.7
由上述测试结果可知:结论与上文数据源维度查询 的结论相同

 

以时间维度聚合条件

  InfluxDB TimeScaleDB
sql select count(usage_idle) from test_function group by time(1d)   select 
to_char(time, 'YYYY-MM-DD') as d ,  count(*)  as  cnt from  test_function 
group by d
耗时(S) 0.9 9.2
符合条件的数据行数 1000万 1000万
由于两种数据库测试时使用的sql不同,因此这组测试数据的参考价值有限,不做过多的分析。

 

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信